Skip to content

Commit

Permalink
feat(repo): remove projectNameAndRoot nx.json option
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz committed Sep 20, 2023
1 parent 11e8e00 commit 8ef6472
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 138 deletions.
9 changes: 4 additions & 5 deletions docs/generated/devkit/NxJsonConfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` |
9 changes: 4 additions & 5 deletions docs/generated/devkit/Workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion e2e/linter/src/linter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down
4 changes: 0 additions & 4 deletions e2e/utils/create-project-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<NxJsonConfiguration>('nx.json', (nxJson) => {
delete nxJson.workspaceLayout;
return nxJson;
});
createFile('apps/.gitkeep');
createFile('libs/.gitkeep');
}
Expand Down
44 changes: 29 additions & 15 deletions e2e/workspace-create-npm/src/create-nx-workspace-npm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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');
Expand All @@ -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');
Expand All @@ -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');
});
Expand All @@ -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');
});
Expand All @@ -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');
Expand All @@ -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');
});
Expand All @@ -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');
Expand All @@ -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');
Expand All @@ -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');
Expand All @@ -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');
});
Expand All @@ -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');
Expand All @@ -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');
});
Expand All @@ -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');
Expand All @@ -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');
});
Expand Down
38 changes: 0 additions & 38 deletions packages/devkit/src/generators/project-name-and-root-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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();
Expand Down
35 changes: 1 addition & 34 deletions packages/devkit/src/generators/project-name-and-root-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion packages/nx/src/config/nx-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ export interface NxJsonConfiguration<T = '*' | string[]> {
workspaceLayout?: {
libsDir?: string;
appsDir?: string;
projectNameAndRootFormat?: 'as-provided' | 'derived';
};
/**
* Available Task Runners
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
});
});
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 8ef6472

Please sign in to comment.