diff --git a/docs/generated/devkit/NxJsonConfiguration.md b/docs/generated/devkit/NxJsonConfiguration.md index 9a47653e6923a..18c5c9ddc2f2f 100644 --- a/docs/generated/devkit/NxJsonConfiguration.md +++ b/docs/generated/devkit/NxJsonConfiguration.md @@ -200,8 +200,7 @@ Where new apps + libs should be placed #### Type declaration -| Name | Type | -| :-------------------------- | :----------------------------- | -| `appsDir?` | `string` | -| `libsDir?` | `string` | -| `projectNameAndRootFormat?` | `"as-provided"` \| `"derived"` | +| Name | Type | +| :--------- | :------- | +| `appsDir?` | `string` | +| `libsDir?` | `string` | diff --git a/docs/generated/devkit/Workspace.md b/docs/generated/devkit/Workspace.md index 239db1d5767c5..7f2f09e29a107 100644 --- a/docs/generated/devkit/Workspace.md +++ b/docs/generated/devkit/Workspace.md @@ -280,11 +280,10 @@ Where new apps + libs should be placed #### Type declaration -| Name | Type | -| :-------------------------- | :----------------------------- | -| `appsDir?` | `string` | -| `libsDir?` | `string` | -| `projectNameAndRootFormat?` | `"as-provided"` \| `"derived"` | +| Name | Type | +| :--------- | :------- | +| `appsDir?` | `string` | +| `libsDir?` | `string` | #### Inherited from diff --git a/e2e/linter/src/linter.test.ts b/e2e/linter/src/linter.test.ts index 54f81dd716b97..719cbdb424457 100644 --- a/e2e/linter/src/linter.test.ts +++ b/e2e/linter/src/linter.test.ts @@ -558,7 +558,9 @@ describe('Linter', () => { bundler: 'vite', e2eTestRunner: 'none', }); - runCLI(`generate @nx/js:lib ${mylib} --directory libs/${mylib}`); + runCLI( + `generate @nx/js:lib ${mylib} --directory libs/${mylib} --projectNameAndRootFormat as-provided` + ); // migrate to flat structure runCLI(`generate @nx/linter:convert-to-flat-config`); diff --git a/e2e/utils/create-project-utils.ts b/e2e/utils/create-project-utils.ts index 69af84352d58f..3439a43cab49a 100644 --- a/e2e/utils/create-project-utils.ts +++ b/e2e/utils/create-project-utils.ts @@ -57,10 +57,6 @@ export function newProject({ console.warn( 'ATTENTION: The workspace generated for this e2e test does not use the new as-provided project name/root format. Please update this test' ); - updateJson('nx.json', (nxJson) => { - delete nxJson.workspaceLayout; - return nxJson; - }); createFile('apps/.gitkeep'); createFile('libs/.gitkeep'); } diff --git a/e2e/workspace-create-npm/src/create-nx-workspace-npm.test.ts b/e2e/workspace-create-npm/src/create-nx-workspace-npm.test.ts index 0a927597b8820..fef38095f2310 100644 --- a/e2e/workspace-create-npm/src/create-nx-workspace-npm.test.ts +++ b/e2e/workspace-create-npm/src/create-nx-workspace-npm.test.ts @@ -53,7 +53,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => { - runCLI(`generate @nx/angular:app ${appName} --no-interactive`); + runCLI( + `generate @nx/angular:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }, 1_000_000); @@ -64,7 +66,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/angular:lib ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/angular:lib ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -81,7 +83,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => runCLI( - `generate @nx/js:library ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/js:library ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ) ).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -97,7 +99,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => - runCLI(`generate @nx/web:app ${appName} --no-interactive`) + runCLI( + `generate @nx/web:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ) ).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }); @@ -108,7 +112,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => { - runCLI(`generate @nx/react:app ${appName} --no-interactive`); + runCLI( + `generate @nx/react:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }); @@ -120,7 +126,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/react:lib ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/react:lib ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -136,7 +142,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => { - runCLI(`generate @nx/next:app ${appName} --no-interactive`); + runCLI( + `generate @nx/next:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }); @@ -148,7 +156,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/next:lib ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/next:lib ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -166,7 +174,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/react-native:app ${appName} --install=false --no-interactive` + `generate @nx/react-native:app ${appName} --install=false --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -179,7 +187,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/react-native:lib ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/react-native:lib ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -195,7 +203,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => { - runCLI(`generate @nx/node:app ${appName} --no-interactive`); + runCLI( + `generate @nx/node:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }); @@ -207,7 +217,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/node:lib ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/node:lib ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -223,7 +233,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => { - runCLI(`generate @nx/nest:app ${appName} --no-interactive`); + runCLI( + `generate @nx/nest:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }); @@ -235,7 +247,7 @@ describe('create-nx-workspace --preset=npm', () => { expect(() => { runCLI( - `generate @nx/nest:lib ${libName} --directory packages/${libName} --no-interactive` + `generate @nx/nest:lib ${libName} --directory packages/${libName} --projectNameAndRootFormat as-provided --no-interactive` ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); @@ -251,7 +263,9 @@ describe('create-nx-workspace --preset=npm', () => { const appName = uniq('my-app'); expect(() => { - runCLI(`generate @nx/express:app ${appName} --no-interactive`); + runCLI( + `generate @nx/express:app ${appName} --projectNameAndRootFormat as-provided --no-interactive` + ); }).not.toThrowError(); checkFilesExist('tsconfig.base.json'); }); diff --git a/packages/devkit/src/generators/project-name-and-root-utils.spec.ts b/packages/devkit/src/generators/project-name-and-root-utils.spec.ts index fe31b01319092..2d2b5c5175561 100644 --- a/packages/devkit/src/generators/project-name-and-root-utils.spec.ts +++ b/packages/devkit/src/generators/project-name-and-root-utils.spec.ts @@ -2,7 +2,6 @@ import * as enquirer from 'enquirer'; import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; import type { Tree } from 'nx/src/generators/tree'; import { updateJson } from 'nx/src/generators/utils/json'; -import { readNxJson } from 'nx/src/generators/utils/nx-json'; import { determineProjectNameAndRootOptions } from './project-name-and-root-utils'; describe('determineProjectNameAndRootOptions', () => { @@ -330,43 +329,6 @@ describe('determineProjectNameAndRootOptions', () => { restoreOriginalInteractiveMode(); }); - it('should prompt to save default when as-provided is choosen', async () => { - // simulate interactive mode - ensureInteractiveMode(); - const promptSpy = jest - .spyOn(enquirer, 'prompt') - .mockImplementation(() => - Promise.resolve({ format: 'lib-name @ shared', saveDefault: true }) - ); - - await determineProjectNameAndRootOptions(tree, { - name: 'libName', - projectType: 'library', - directory: 'shared', - callingGenerator: '@nx/some-plugin:app', - }); - - expect(promptSpy).toHaveBeenCalledTimes(2); - - expect(readNxJson(tree).workspaceLayout).toEqual({ - projectNameAndRootFormat: 'as-provided', - }); - - promptSpy.mockReset(); - - await determineProjectNameAndRootOptions(tree, { - name: 'libName', - projectType: 'library', - directory: 'shared', - callingGenerator: '@nx/some-plugin:app', - }); - - expect(promptSpy).not.toHaveBeenCalled(); - - // restore original interactive mode - restoreOriginalInteractiveMode(); - }); - it('should directly use format as-provided and not prompt when the name is a scoped package name', async () => { // simulate interactive mode ensureInteractiveMode(); diff --git a/packages/devkit/src/generators/project-name-and-root-utils.ts b/packages/devkit/src/generators/project-name-and-root-utils.ts index d9639be3efe56..30a78061f2e15 100644 --- a/packages/devkit/src/generators/project-name-and-root-utils.ts +++ b/packages/devkit/src/generators/project-name-and-root-utils.ts @@ -77,17 +77,9 @@ export async function determineProjectNameAndRootOptions( > { validateName(options.name, options.projectNameAndRootFormat); const formats = getProjectNameAndRootFormats(tree, options); - const configuredDefault = getDefaultProjectNameAndRootFormat(tree); - - if (configuredDefault === 'derived') { - logger.warn( - deprecationWarning + '\n' + getExample(options.callingGenerator, formats) - ); - } const format = options.projectNameAndRootFormat ?? - configuredDefault ?? (await determineFormat(tree, formats, options.callingGenerator)); return { @@ -179,38 +171,13 @@ async function determineFormat( format === asProvidedSelectedValue ? 'as-provided' : 'derived' ); - if (result === 'as-provided' && callingGenerator) { - const { saveDefault } = await prompt<{ saveDefault: boolean }>({ - type: 'confirm', - message: `Would you like to configure Nx to always take project name and root as provided for ${callingGenerator}?`, - name: 'saveDefault', - initial: true, - }); - if (saveDefault) { - setProjectNameAndRootFormatDefault(tree); - } else { - logger.warn(deprecationWarning); - } - } else { + if (result === 'derived' && callingGenerator) { const example = getExample(callingGenerator, formats); logger.warn(deprecationWarning + '\n' + example); } return result; } - -function setProjectNameAndRootFormatDefault(tree: Tree) { - const nxJson = readNxJson(tree); - nxJson.workspaceLayout ??= {}; - nxJson.workspaceLayout.projectNameAndRootFormat = 'as-provided'; - updateNxJson(tree, nxJson); -} - -function getDefaultProjectNameAndRootFormat(tree: Tree) { - const nxJson = readNxJson(tree); - return nxJson.workspaceLayout?.projectNameAndRootFormat; -} - function getProjectNameAndRootFormats( tree: Tree, options: ProjectGenerationOptions diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index 681e3ea3c4af9..0823f002395fa 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -117,7 +117,6 @@ export interface NxJsonConfiguration { workspaceLayout?: { libsDir?: string; appsDir?: string; - projectNameAndRootFormat?: 'as-provided' | 'derived'; }; /** * Available Task Runners diff --git a/packages/nx/src/migrations/update-16-9-0/remove-project-name-and-root-format.spec.ts b/packages/nx/src/migrations/update-16-9-0/remove-project-name-and-root-format.spec.ts new file mode 100644 index 0000000000000..40398573651f6 --- /dev/null +++ b/packages/nx/src/migrations/update-16-9-0/remove-project-name-and-root-format.spec.ts @@ -0,0 +1,47 @@ +import { readJson, writeJson } from '../../generators/utils/json'; +import { createTree } from '../../generators/testing-utils/create-tree'; +import removeProjectNameAndRootFormat from './remove-project-name-and-root-format'; +import { NxJsonConfiguration } from '../../config/nx-json'; + +describe('removeProjectNameAndRootFormat', () => { + let tree; + beforeEach(() => { + tree = createTree(); + }); + + it('should not error if nx.json is not present', async () => { + await removeProjectNameAndRootFormat(tree); + }); + + it('should not update nx.json if projectNameAndRoot is not present', async () => { + const nxJson: NxJsonConfiguration = {}; + writeJson(tree, 'nx.json', nxJson); + await removeProjectNameAndRootFormat(tree); + expect(readJson(tree, 'nx.json')).toEqual(nxJson); + }); + + it('should remove projectNameAndRoot if it is present', async () => { + const nxJson: any = { + workspaceLayout: { + libsDir: 'libs', + projectNameAndRootFormat: 'as-provided', + }, + }; + writeJson(tree, 'nx.json', nxJson); + await removeProjectNameAndRootFormat(tree); + expect(readJson(tree, 'nx.json').workspaceLayout).toEqual({ + libsDir: 'libs', + }); + }); + + it('should remove workspaceLayout if it is present', async () => { + const nxJson: any = { + workspaceLayout: { + projectNameAndRootFormat: 'as-provided', + }, + }; + writeJson(tree, 'nx.json', nxJson); + await removeProjectNameAndRootFormat(tree); + expect(readJson(tree, 'nx.json').workspaceLayout).not.toBeDefined(); + }); +}); diff --git a/packages/nx/src/migrations/update-16-9-0/remove-project-name-and-root-format.ts b/packages/nx/src/migrations/update-16-9-0/remove-project-name-and-root-format.ts new file mode 100644 index 0000000000000..0437c44ba0c2f --- /dev/null +++ b/packages/nx/src/migrations/update-16-9-0/remove-project-name-and-root-format.ts @@ -0,0 +1,25 @@ +import { Tree } from '../../generators/tree'; +import { updateJson } from '../../generators/utils/json'; +import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available'; + +export default async function removeProjectNameAndRootFormat(tree: Tree) { + if (!tree.exists('nx.json')) { + return; + } + + updateJson(tree, 'nx.json', (nxJson) => { + if (!nxJson.workspaceLayout) { + return nxJson; + } + + delete nxJson.workspaceLayout.projectNameAndRootFormat; + + if (Object.keys(nxJson.workspaceLayout).length === 0) { + delete nxJson.workspaceLayout; + } + + return nxJson; + }); + + await formatChangedFilesWithPrettierIfAvailable(tree); +} diff --git a/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap b/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap index 693757e1212cb..ec1603d79d675 100644 --- a/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap +++ b/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap @@ -53,8 +53,5 @@ exports[`new should generate an empty nx.json 1`] = ` "runner": "nx/tasks-runners/default", }, }, - "workspaceLayout": { - "projectNameAndRootFormat": "as-provided", - }, } `; diff --git a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts index 41b6e84f7e245..91e9aa1dd0ba3 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts @@ -124,9 +124,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { "runner": "nx/tasks-runners/default", }, }, - "workspaceLayout": { - "projectNameAndRootFormat": "as-provided", - }, } `); const validateNxJson = ajv.compile(nxSchema); @@ -179,9 +176,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { "runner": "nx/tasks-runners/default", }, }, - "workspaceLayout": { - "projectNameAndRootFormat": "as-provided", - }, } `); }); @@ -246,9 +240,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { "runner": "nx/tasks-runners/default", }, }, - "workspaceLayout": { - "projectNameAndRootFormat": "as-provided", - }, } `); diff --git a/packages/workspace/src/generators/new/generate-workspace-files.ts b/packages/workspace/src/generators/new/generate-workspace-files.ts index 5090f3b25ddff..e19451a25a985 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.ts @@ -60,26 +60,6 @@ function setPresetProperty(tree: Tree, options: NormalizedSchema) { return json; }); } - -function createAppsAndLibsFolders(tree: Tree, options: NormalizedSchema) { - if (options.preset === Preset.TS || options.preset === Preset.NPM) { - tree.write(join(options.directory, 'packages/.gitkeep'), ''); - } else if ( - options.preset === Preset.AngularStandalone || - options.preset === Preset.ReactStandalone || - options.preset === Preset.VueStandalone || - options.preset === Preset.NodeStandalone || - options.preset === Preset.NextJsStandalone || - options.preset === Preset.TsStandalone || - options.isCustomPreset - ) { - // don't generate any folders - } else { - tree.write(join(options.directory, 'apps/.gitkeep'), ''); - tree.write(join(options.directory, 'libs/.gitkeep'), ''); - } -} - function createNxJson( tree: Tree, { directory, defaultBase, preset }: NormalizedSchema @@ -97,9 +77,6 @@ function createNxJson( }, }, }, - workspaceLayout: { - projectNameAndRootFormat: 'as-provided', - }, }; nxJson.targetDefaults = {