Skip to content

Commit

Permalink
feat(misc): save directory and name format to nx json defaults (#18683)
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder authored Aug 17, 2023
1 parent 61d73fc commit e2ff519
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export async function normalizeOptions(
directory: options.directory,
projectNameAndRootFormat: options.projectNameAndRootFormat,
rootProject: options.rootProject,
callingGenerator: '@nx/angular:application',
});
options.rootProject = appProjectRoot === '.';
options.projectNameAndRootFormat = projectNameAndRootFormat;
Expand All @@ -34,6 +35,7 @@ export async function normalizeOptions(
directory: options.directory,
projectNameAndRootFormat: options.projectNameAndRootFormat,
rootProject: options.rootProject,
callingGenerator: '@nx/angular:application',
});
e2eProjectName = projectNameAndRoot.projectName;
e2eProjectRoot = projectNameAndRoot.projectRoot;
Expand Down
1 change: 1 addition & 0 deletions packages/angular/src/generators/host/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export async function hostInternal(tree: Tree, options: Schema) {
projectType: 'application',
directory: options.directory,
projectNameAndRootFormat: options.projectNameAndRootFormat,
callingGenerator: '@nx/angular:host',
});
options.projectNameAndRootFormat = projectNameAndRootFormat;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export async function normalizeOptions(
directory: options.directory,
importPath: options.importPath,
projectNameAndRootFormat: options.projectNameAndRootFormat,
callingGenerator: '@nx/angular:library',
});

const fileName = options.simpleName
Expand Down
1 change: 1 addition & 0 deletions packages/angular/src/generators/remote/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export async function remoteInternal(tree: Tree, options: Schema) {
projectType: 'application',
directory: options.directory,
projectNameAndRootFormat: options.projectNameAndRootFormat,
callingGenerator: '@nx/angular:remote',
});
options.projectNameAndRootFormat = projectNameAndRootFormat;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ async function normalizeOptions(
projectNameAndRootFormat: isRootProject
? 'as-provided'
: options.projectNameAndRootFormat,
callingGenerator: '@nx/cypress:cypress-project',
}
);

Expand Down
53 changes: 53 additions & 0 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,6 +2,7 @@ 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 @@ -40,6 +41,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
});

expect(result).toStrictEqual({
Expand All @@ -60,6 +62,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -81,6 +84,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
importPath: '@custom-scope/lib-name',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -104,6 +108,7 @@ describe('determineProjectNameAndRootOptions', () => {
name: '@scope/libName',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -129,6 +134,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
rootProject: true,
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -154,6 +160,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
rootProject: true,
callingGenerator: '',
});

expect(result.importPath).toBe('@proj/lib-name');
Expand All @@ -166,6 +173,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
})
).rejects.toThrowError();
});
Expand All @@ -176,6 +184,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'derived',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -197,6 +206,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'derived',
callingGenerator: '',
})
).rejects.toThrowError();
});
Expand All @@ -211,6 +221,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'derived',
rootProject: true,
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -236,6 +247,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
rootProject: true,
callingGenerator: '',
});

expect(result.importPath).toBe('@proj/lib-name');
Expand All @@ -252,6 +264,7 @@ describe('determineProjectNameAndRootOptions', () => {
name: 'libName',
projectType: 'library',
directory: 'shared',
callingGenerator: '',
});

expect(promptSpy).toHaveBeenCalled();
Expand All @@ -275,6 +288,32 @@ 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).generators['@nx/some-plugin:app']).toEqual({
projectNameAndRootFormat: 'as-provided',
});

// 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 All @@ -284,6 +323,7 @@ describe('determineProjectNameAndRootOptions', () => {
name: '@scope/libName',
projectType: 'library',
directory: 'shared',
callingGenerator: '',
});

expect(promptSpy).not.toHaveBeenCalled();
Expand Down Expand Up @@ -315,6 +355,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -335,6 +376,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -356,6 +398,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
importPath: '@custom-scope/lib-name',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -380,6 +423,7 @@ describe('determineProjectNameAndRootOptions', () => {
name: '@scope/libName',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -405,6 +449,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
rootProject: true,
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -430,6 +475,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
rootProject: true,
callingGenerator: '',
});

expect(result.importPath).toBe('@proj/lib-name');
Expand All @@ -442,6 +488,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
callingGenerator: '',
})
).rejects.toThrowError();
});
Expand All @@ -452,6 +499,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'derived',
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -473,6 +521,7 @@ describe('determineProjectNameAndRootOptions', () => {
directory: 'shared',
projectType: 'library',
projectNameAndRootFormat: 'derived',
callingGenerator: '',
})
).rejects.toThrowError();
});
Expand All @@ -488,6 +537,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'derived',
rootProject: true,
callingGenerator: '',
});

expect(result).toEqual({
Expand All @@ -513,6 +563,7 @@ describe('determineProjectNameAndRootOptions', () => {
projectType: 'library',
projectNameAndRootFormat: 'as-provided',
rootProject: true,
callingGenerator: '',
});

expect(result.importPath).toBe('@proj/lib-name');
Expand All @@ -529,6 +580,7 @@ describe('determineProjectNameAndRootOptions', () => {
name: 'libName',
projectType: 'library',
directory: 'shared',
callingGenerator: '',
});

expect(promptSpy).toHaveBeenCalled();
Expand Down Expand Up @@ -561,6 +613,7 @@ describe('determineProjectNameAndRootOptions', () => {
name: '@scope/libName',
projectType: 'library',
directory: 'shared',
callingGenerator: '',
});

expect(promptSpy).not.toHaveBeenCalled();
Expand Down
28 changes: 24 additions & 4 deletions packages/devkit/src/generators/project-name-and-root-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {
} from '../utils/get-workspace-layout';
import { names } from '../utils/names';

const { joinPathFragments, readJson, readNxJson } = requireNx();
const { joinPathFragments, readJson, readNxJson, updateNxJson } = requireNx();

export type ProjectNameAndRootFormat = 'as-provided' | 'derived';
export type ProjectGenerationOptions = {
name: string;
projectType: ProjectType;
callingGenerator: string;
directory?: string;
importPath?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
Expand Down Expand Up @@ -65,7 +66,8 @@ export async function determineProjectNameAndRootOptions(
validateName(options.name, options.projectNameAndRootFormat);
const formats = getProjectNameAndRootFormats(tree, options);
const format =
options.projectNameAndRootFormat ?? (await determineFormat(formats));
options.projectNameAndRootFormat ??
(await determineFormat(tree, formats, options.callingGenerator));

return {
...formats[format],
Expand Down Expand Up @@ -104,7 +106,9 @@ function validateName(
}

async function determineFormat(
formats: ProjectNameAndRootFormats
tree: Tree,
formats: ProjectNameAndRootFormats,
callingGenerator: string
): Promise<ProjectNameAndRootFormat> {
if (!formats.derived) {
return 'as-provided';
Expand All @@ -123,7 +127,7 @@ async function determineFormat(
Root: ${formats['derived'].projectRoot}`;
const derivedSelectedValue = `${formats['derived'].projectName} @ ${formats['derived'].projectRoot} (This was derived from the folder structure. Please provide the exact name and directory in the future)`;

return await prompt<{ format: ProjectNameAndRootFormat }>({
const result = await prompt<{ format: ProjectNameAndRootFormat }>({
type: 'select',
name: 'format',
message:
Expand All @@ -142,6 +146,22 @@ async function determineFormat(
}).then(({ format }) =>
format === asProvidedSelectedValue ? 'as-provided' : 'derived'
);
if (result === 'as-provided' && callingGenerator) {
const { saveDefault } = await prompt<{ saveDefault: boolean }>({
type: 'confirm',
message: 'Would you like to save this layout as a default?',
name: 'saveDefault',
});
if (saveDefault) {
const nxJson = readNxJson(tree);
nxJson.generators ??= {};
nxJson.generators[callingGenerator] ??= {};
nxJson.generators[callingGenerator].projectNameAndRootFormat = result;
updateNxJson(tree, nxJson);
}
}

return result;
}

function getProjectNameAndRootFormats(
Expand Down
1 change: 1 addition & 0 deletions packages/js/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ async function normalizeOptions(
importPath: options.importPath,
projectNameAndRootFormat: options.projectNameAndRootFormat,
rootProject: options.rootProject,
callingGenerator: '@nx/js:library',
});
options.rootProject = projectRoot === '.';
const fileName = getCaseAwareFileName({
Expand Down

1 comment on commit e2ff519

@vercel
Copy link

@vercel vercel bot commented on e2ff519 Aug 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-dev-nrwl.vercel.app
nx-five.vercel.app
nx.dev

Please sign in to comment.