fix(angular): set projectName as the default source for relevant generators (#15664)

This commit is contained in:
Leosvel Pérez Espinosa 2023-03-14 16:38:35 +00:00 committed by GitHub
parent 425c13448b
commit ca8d24b3d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 61 additions and 187 deletions

View File

@ -11,6 +11,7 @@
"projectName": { "projectName": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": { "$source": "projectName", "index": 0 },
"examples": ["ui-samples"], "examples": ["ui-samples"],
"x-priority": "important" "x-priority": "important"
}, },

View File

@ -11,6 +11,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project where the component is located.", "description": "The name of the project where the component is located.",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects", "x-dropdown": "projects",
"x-prompt": "What project is the component located in?", "x-prompt": "What project is the component located in?",
"x-priority": "important" "x-priority": "important"

View File

@ -19,6 +19,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -12,6 +12,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project to add cypress component testing configuration to", "description": "The name of the project to add cypress component testing configuration to",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects", "x-dropdown": "projects",
"x-prompt": "What project should we add Cypress component testing to?", "x-prompt": "What project should we add Cypress component testing to?",
"x-priority": "important" "x-priority": "important"

View File

@ -25,6 +25,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -25,6 +25,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -25,6 +25,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -17,6 +17,7 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": { "$source": "projectName", "index": 0 },
"x-dropdown": "projects", "x-dropdown": "projects",
"x-priority": "important" "x-priority": "important"
}, },

View File

@ -8,6 +8,10 @@
"projectName": { "projectName": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": {
"$source": "projectName",
"index": 0
},
"examples": ["ui-samples"], "examples": ["ui-samples"],
"x-priority": "important" "x-priority": "important"
}, },

View File

@ -8,6 +8,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project where the component is located.", "description": "The name of the project where the component is located.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects", "x-dropdown": "projects",
"x-prompt": "What project is the component located in?", "x-prompt": "What project is the component located in?",
"x-priority": "important" "x-priority": "important"

View File

@ -42,20 +42,6 @@ export class ExampleComponent {
" "
`; `;
exports[`component Generator --path should infer project from path and generate component correctly 1`] = `
"import { Component } from '@angular/core';
@Component({
selector: 'example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent {
}
"
`;
exports[`component Generator secondary entry points should create the component correctly and export it in the entry point 1`] = ` exports[`component Generator secondary entry points should create the component correctly and export it in the entry point 1`] = `
"import { Component } from '@angular/core'; "import { Component } from '@angular/core';

View File

@ -1,4 +1,3 @@
import type { ProjectGraph } from '@nrwl/devkit';
import { import {
addProjectConfiguration, addProjectConfiguration,
stripIndents, stripIndents,
@ -8,14 +7,6 @@ import {
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import componentGenerator from './component'; import componentGenerator from './component';
let projectGraph: ProjectGraph;
jest.mock('@nrwl/devkit', () => {
return {
...jest.requireActual('@nrwl/devkit'),
createProjectGraphAsync: jest.fn().mockImplementation(() => projectGraph),
};
});
describe('component Generator', () => { describe('component Generator', () => {
it('should create the component correctly and export it in the entry point when "export=true"', async () => { it('should create the component correctly and export it in the entry point when "export=true"', async () => {
// ARRANGE // ARRANGE
@ -420,50 +411,6 @@ describe('component Generator', () => {
); );
}); });
it('should infer project from path and generate component correctly', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
addProjectConfiguration(tree, 'lib1', {
projectType: 'library',
sourceRoot: 'libs/lib1/src',
root: 'libs/lib1',
});
tree.write(
'libs/lib1/src/lib/lib.module.ts',
`
import { NgModule } from '@angular/core';
@NgModule({
declarations: [],
exports: []
})
export class LibModule {}`
);
projectGraph = {
nodes: {
lib1: {
name: 'lib1',
type: 'lib',
data: { root: 'libs/lib1' } as any,
},
},
dependencies: {},
};
// ACT
await componentGenerator(tree, {
name: 'example',
path: 'libs/lib1/src/lib/mycomp',
});
// ASSERT
const componentSource = tree.read(
'libs/lib1/src/lib/mycomp/example/example.component.ts',
'utf-8'
);
expect(componentSource).toMatchSnapshot();
});
it('should throw if the path specified is not under the project root', async () => { it('should throw if the path specified is not under the project root', async () => {
// ARRANGE // ARRANGE
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
@ -495,36 +442,6 @@ describe('component Generator', () => {
}) })
).rejects.toThrow(); ).rejects.toThrow();
}); });
it('should throw when path and projects are not provided and defaultProject is not set', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
addProjectConfiguration(tree, 'lib1', {
projectType: 'library',
sourceRoot: 'libs/lib1/src',
root: 'libs/lib1',
});
tree.write(
'libs/lib1/src/lib/lib.module.ts',
`
import { NgModule } from '@angular/core';
@NgModule({
declarations: [],
exports: []
})
export class LibModule {}`
);
tree.write('libs/lib1/src/index.ts', 'export * from "./lib/lib.module";');
// ACT & ASSERT
await expect(
componentGenerator(tree, {
name: 'example',
export: false,
})
).rejects.toThrow();
});
}); });
describe('--module', () => { describe('--module', () => {

View File

@ -1,11 +1,11 @@
import type { Tree } from '@nrwl/devkit'; import type { Tree } from '@nrwl/devkit';
import { formatFiles, stripIndents } from '@nrwl/devkit'; import { formatFiles, stripIndents } from '@nrwl/devkit';
import { lt } from 'semver';
import { checkPathUnderProjectRoot } from '../utils/path';
import { getInstalledAngularVersionInfo } from '../utils/version-utils';
import { exportComponentInEntryPoint } from './lib/component'; import { exportComponentInEntryPoint } from './lib/component';
import { normalizeOptions } from './lib/normalize-options'; import { normalizeOptions } from './lib/normalize-options';
import type { Schema } from './schema'; import type { Schema } from './schema';
import { getInstalledAngularVersionInfo } from '../utils/version-utils';
import { lt } from 'semver';
import { checkPathUnderProjectRoot } from '../utils/path';
export async function componentGenerator(tree: Tree, rawOptions: Schema) { export async function componentGenerator(tree: Tree, rawOptions: Schema) {
const installedAngularVersionInfo = getInstalledAngularVersionInfo(tree); const installedAngularVersionInfo = getInstalledAngularVersionInfo(tree);

View File

@ -1,52 +1,14 @@
import type { Tree } from '@nrwl/devkit'; import type { Tree } from '@nrwl/devkit';
import { import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit';
createProjectGraphAsync,
joinPathFragments,
readNxJson,
readProjectConfiguration,
} from '@nrwl/devkit';
import type { NormalizedSchema, Schema } from '../schema'; import type { NormalizedSchema, Schema } from '../schema';
import {
createProjectRootMappings,
findProjectForPath,
} from 'nx/src/project-graph/utils/find-project-for-path';
async function findProjectFromOptions(options: Schema) {
const projectGraph = await createProjectGraphAsync();
const projectRootMappings = createProjectRootMappings(projectGraph.nodes);
// path can be undefined when running on the root of the workspace, we default to the root
// to handle standalone layouts
return findProjectForPath(options.path || '', projectRootMappings);
}
export async function normalizeOptions( export async function normalizeOptions(
tree: Tree, tree: Tree,
options: Schema options: Schema
): Promise<NormalizedSchema> { ): Promise<NormalizedSchema> {
const project =
options.project ??
(await findProjectFromOptions(options)) ??
readNxJson(tree).defaultProject;
if (!project) {
// path is hidden, so if not provided we don't suggest setting it
if (!options.path) {
throw new Error(
'No "project" was specified and "defaultProject" is not set in the workspace configuration. Please provide the "project" option and try again.'
);
}
// path was provided, so it's wrong and we should mention it
throw new Error(
'The provided "path" is wrong and no "project" was specified and "defaultProject" is not set in the workspace configuration. ' +
'Please provide a correct "path" or provide the "project" option instead and try again.'
);
}
const { projectType, root, sourceRoot } = readProjectConfiguration( const { projectType, root, sourceRoot } = readProjectConfiguration(
tree, tree,
project options.project
); );
const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src');
const path = const path =
@ -59,7 +21,6 @@ export async function normalizeOptions(
return { return {
...options, ...options,
path, path,
project,
projectSourceRoot, projectSourceRoot,
}; };
} }

View File

@ -1,7 +1,7 @@
export interface Schema { export interface Schema {
name: string; name: string;
project: string;
path?: string; path?: string;
project?: string;
displayBlock?: boolean; displayBlock?: boolean;
inlineStyle?: boolean; inlineStyle?: boolean;
inlineTemplate?: boolean; inlineTemplate?: boolean;
@ -21,6 +21,5 @@ export interface Schema {
export interface NormalizedSchema extends Schema { export interface NormalizedSchema extends Schema {
path: string; path: string;
project: string;
projectSourceRoot: string; projectSourceRoot: string;
} }

View File

@ -16,6 +16,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -9,6 +9,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project to add cypress component testing configuration to", "description": "The name of the project to add cypress component testing configuration to",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects", "x-dropdown": "projects",
"x-prompt": "What project should we add Cypress component testing to?", "x-prompt": "What project should we add Cypress component testing to?",
"x-priority": "important" "x-priority": "important"

View File

@ -1,19 +1,14 @@
import type { Tree } from '@nrwl/devkit'; import type { Tree } from '@nrwl/devkit';
import { import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit';
joinPathFragments,
readNxJson,
readProjectConfiguration,
} from '@nrwl/devkit';
import type { NormalizedSchema, Schema } from '../schema'; import type { NormalizedSchema, Schema } from '../schema';
export function normalizeOptions( export function normalizeOptions(
tree: Tree, tree: Tree,
options: Schema options: Schema
): NormalizedSchema { ): NormalizedSchema {
const project = options.project ?? readNxJson(tree).defaultProject;
const { projectType, root, sourceRoot } = readProjectConfiguration( const { projectType, root, sourceRoot } = readProjectConfiguration(
tree, tree,
project options.project
); );
const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src');
const path = const path =
@ -29,7 +24,6 @@ export function normalizeOptions(
flat: options.flat ?? true, flat: options.flat ?? true,
inlineScam: options.inlineScam ?? true, inlineScam: options.inlineScam ?? true,
path, path,
project,
projectSourceRoot, projectSourceRoot,
}; };
} }

View File

@ -2,7 +2,6 @@ import type { Tree } from '@nrwl/devkit';
import { import {
formatFiles, formatFiles,
normalizePath, normalizePath,
readNxJson,
readProjectConfiguration, readProjectConfiguration,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
import { exportScam } from '../utils/export-scam'; import { exportScam } from '../utils/export-scam';
@ -41,8 +40,7 @@ function checkPathUnderProjectRoot(tree: Tree, options: Partial<Schema>) {
return; return;
} }
const project = options.project ?? readNxJson(tree).defaultProject; const { root } = readProjectConfiguration(tree, options.project);
const { root } = readProjectConfiguration(tree, project);
let pathToDirective = normalizePath(options.path); let pathToDirective = normalizePath(options.path);
pathToDirective = pathToDirective.startsWith('/') pathToDirective = pathToDirective.startsWith('/')

View File

@ -1,7 +1,7 @@
export interface Schema { export interface Schema {
name: string; name: string;
project: string;
path?: string; path?: string;
project?: string;
skipTests?: boolean; skipTests?: boolean;
inlineScam?: boolean; inlineScam?: boolean;
flat?: boolean; flat?: boolean;
@ -15,6 +15,5 @@ export interface NormalizedSchema extends Schema {
flat: boolean; flat: boolean;
inlineScam: boolean; inlineScam: boolean;
path: string; path: string;
project: string;
projectSourceRoot: string; projectSourceRoot: string;
} }

View File

@ -22,6 +22,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -1,19 +1,14 @@
import type { Tree } from '@nrwl/devkit'; import type { Tree } from '@nrwl/devkit';
import { import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit';
joinPathFragments,
readNxJson,
readProjectConfiguration,
} from '@nrwl/devkit';
import type { NormalizedSchema, Schema } from '../schema'; import type { NormalizedSchema, Schema } from '../schema';
export function normalizeOptions( export function normalizeOptions(
tree: Tree, tree: Tree,
options: Schema options: Schema
): NormalizedSchema { ): NormalizedSchema {
const project = options.project ?? readNxJson(tree).defaultProject;
const { projectType, root, sourceRoot } = readProjectConfiguration( const { projectType, root, sourceRoot } = readProjectConfiguration(
tree, tree,
project options.project
); );
const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src');
const path = const path =
@ -29,7 +24,6 @@ export function normalizeOptions(
flat: options.flat ?? true, flat: options.flat ?? true,
inlineScam: options.inlineScam ?? true, inlineScam: options.inlineScam ?? true,
path, path,
project,
projectSourceRoot, projectSourceRoot,
}; };
} }

View File

@ -2,7 +2,6 @@ import type { Tree } from '@nrwl/devkit';
import { import {
formatFiles, formatFiles,
normalizePath, normalizePath,
readNxJson,
readProjectConfiguration, readProjectConfiguration,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
import { exportScam } from '../utils/export-scam'; import { exportScam } from '../utils/export-scam';
@ -41,8 +40,7 @@ function checkPathUnderProjectRoot(tree: Tree, options: Partial<Schema>) {
return; return;
} }
const project = options.project ?? readNxJson(tree).defaultProject; const { root } = readProjectConfiguration(tree, options.project);
const { root } = readProjectConfiguration(tree, project);
let pathToPipe = normalizePath(options.path); let pathToPipe = normalizePath(options.path);
pathToPipe = pathToPipe.startsWith('/') ? pathToPipe.slice(1) : pathToPipe; pathToPipe = pathToPipe.startsWith('/') ? pathToPipe.slice(1) : pathToPipe;

View File

@ -1,7 +1,7 @@
export interface Schema { export interface Schema {
name: string; name: string;
project: string;
path?: string; path?: string;
project?: string;
skipTests?: boolean; skipTests?: boolean;
inlineScam?: boolean; inlineScam?: boolean;
flat?: boolean; flat?: boolean;
@ -13,6 +13,5 @@ export interface NormalizedSchema extends Schema {
flat: boolean; flat: boolean;
inlineScam: boolean; inlineScam: boolean;
path: string; path: string;
project: string;
projectSourceRoot: string; projectSourceRoot: string;
} }

View File

@ -22,6 +22,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -1,19 +1,14 @@
import type { Tree } from '@nrwl/devkit'; import type { Tree } from '@nrwl/devkit';
import { import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit';
joinPathFragments,
readNxJson,
readProjectConfiguration,
} from '@nrwl/devkit';
import type { NormalizedSchema, Schema } from '../schema'; import type { NormalizedSchema, Schema } from '../schema';
export function normalizeOptions( export function normalizeOptions(
tree: Tree, tree: Tree,
options: Schema options: Schema
): NormalizedSchema { ): NormalizedSchema {
const project = options.project ?? readNxJson(tree).defaultProject;
const { projectType, root, sourceRoot } = readProjectConfiguration( const { projectType, root, sourceRoot } = readProjectConfiguration(
tree, tree,
project options.project
); );
const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src');
const path = const path =
@ -28,7 +23,6 @@ export function normalizeOptions(
export: options.export ?? true, export: options.export ?? true,
inlineScam: options.inlineScam ?? true, inlineScam: options.inlineScam ?? true,
path, path,
project,
projectSourceRoot, projectSourceRoot,
}; };
} }

View File

@ -41,8 +41,7 @@ function checkPathUnderProjectRoot(tree: Tree, options: Partial<Schema>) {
return; return;
} }
const project = options.project ?? readNxJson(tree).defaultProject; const { root } = readProjectConfiguration(tree, options.project);
const { root } = readProjectConfiguration(tree, project);
let pathToComponent = normalizePath(options.path); let pathToComponent = normalizePath(options.path);
pathToComponent = pathToComponent.startsWith('/') pathToComponent = pathToComponent.startsWith('/')

View File

@ -1,7 +1,7 @@
export interface Schema { export interface Schema {
name: string; name: string;
project: string;
path?: string; path?: string;
project?: string;
displayBlock?: boolean; displayBlock?: boolean;
inlineStyle?: boolean; inlineStyle?: boolean;
inlineTemplate?: boolean; inlineTemplate?: boolean;
@ -22,6 +22,5 @@ export interface NormalizedSchema extends Schema {
export: boolean; export: boolean;
inlineScam: boolean; inlineScam: boolean;
path: string; path: string;
project: string;
projectSourceRoot: string; projectSourceRoot: string;
} }

View File

@ -22,6 +22,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects" "x-dropdown": "projects"
}, },
"name": { "name": {

View File

@ -2,16 +2,15 @@ import {
joinPathFragments, joinPathFragments,
names, names,
normalizePath, normalizePath,
readNxJson,
readProjectConfiguration, readProjectConfiguration,
Tree, Tree,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
export type GenerationOptions = { export type GenerationOptions = {
name: string; name: string;
project: string;
flat?: boolean; flat?: boolean;
path?: string; path?: string;
project?: string;
type?: string; type?: string;
}; };
export type FileInfo = { export type FileInfo = {
@ -46,10 +45,9 @@ function getFileInfo(
options: GenerationOptions, options: GenerationOptions,
defaultType: string defaultType: string
): FileInfo { ): FileInfo {
const project = options.project ?? readNxJson(tree).defaultProject;
const { root, sourceRoot, projectType } = readProjectConfiguration( const { root, sourceRoot, projectType } = readProjectConfiguration(
tree, tree,
project options.project
); );
const { fileName: normalizedName } = names(options.name); const { fileName: normalizedName } = names(options.name);

View File

@ -39,8 +39,7 @@ export function checkPathUnderProjectRoot(
return; return;
} }
const project = projectName ?? readNxJson(tree).defaultProject; const { root } = readProjectConfiguration(tree, projectName);
const { root } = readProjectConfiguration(tree, project);
let pathToComponent = normalizePath(path); let pathToComponent = normalizePath(path);
pathToComponent = pathToComponent.startsWith('/') pathToComponent = pathToComponent.startsWith('/')

View File

@ -14,6 +14,10 @@
"project": { "project": {
"type": "string", "type": "string",
"description": "The name of the project.", "description": "The name of the project.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-dropdown": "projects", "x-dropdown": "projects",
"x-priority": "important" "x-priority": "important"
}, },