mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-16 02:24:10 +08:00
fix(@angular/cli): populate path with working directory in nested schematics
With this change we change the how we handle `"format": "path"` schematic property option. We replace the formatter in favour of a `SmartDefaultProvider`, which ensures that nested schematics can access the `workingDirectory`.
This commit is contained in:
parent
cd2250fe23
commit
e751464ea3
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import { analytics, logging, normalize, schema, strings } from '@angular-devkit/core';
|
||||
import { analytics, logging, schema, strings } from '@angular-devkit/core';
|
||||
import { readFileSync } from 'fs';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
@ -197,8 +197,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
|
||||
* **Note:** This method should be called from the command bundler method.
|
||||
*/
|
||||
protected addSchemaOptionsToCommand<T>(localYargs: Argv<T>, options: Option[]): Argv<T> {
|
||||
const workingDir = normalize(path.relative(this.context.root, process.cwd()));
|
||||
|
||||
for (const option of options) {
|
||||
const {
|
||||
default: defaultVal,
|
||||
@ -211,7 +209,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
|
||||
hidden,
|
||||
name,
|
||||
choices,
|
||||
format,
|
||||
} = option;
|
||||
|
||||
const sharedOptions: YargsOptions & PositionalOptions = {
|
||||
@ -224,11 +221,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
|
||||
...(this.context.args.options.help ? { default: defaultVal } : {}),
|
||||
};
|
||||
|
||||
// Special case for schematics
|
||||
if (workingDir && format === 'path' && name === 'path' && hidden) {
|
||||
sharedOptions.default = workingDir;
|
||||
}
|
||||
|
||||
if (positional === undefined) {
|
||||
localYargs = localYargs.option(strings.dasherize(name), {
|
||||
type,
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import { schema, tags } from '@angular-devkit/core';
|
||||
import { normalize as devkitNormalize, isJsonObject, schema, tags } from '@angular-devkit/core';
|
||||
import { Collection, UnsuccessfulWorkflowExecution, formats } from '@angular-devkit/schematics';
|
||||
import {
|
||||
FileSystemCollectionDescription,
|
||||
@ -14,7 +14,7 @@ import {
|
||||
NodeWorkflow,
|
||||
} from '@angular-devkit/schematics/tools';
|
||||
import type { CheckboxQuestion, Question } from 'inquirer';
|
||||
import { resolve } from 'path';
|
||||
import { relative, resolve } from 'path';
|
||||
import { Argv } from 'yargs';
|
||||
import { getProjectByCwd, getSchematicDefaults } from '../utilities/config';
|
||||
import { memoize } from '../utilities/memoize';
|
||||
@ -133,10 +133,16 @@ export abstract class SchematicsCommandModule
|
||||
});
|
||||
|
||||
workflow.registry.addPostTransform(schema.transforms.addUndefinedDefaults);
|
||||
workflow.registry.addSmartDefaultProvider('projectName', () => this.getProjectName());
|
||||
workflow.registry.useXDeprecatedProvider((msg) => logger.warn(msg));
|
||||
workflow.registry.addSmartDefaultProvider('projectName', () => this.getProjectName());
|
||||
|
||||
const workingDir = devkitNormalize(relative(this.context.root, process.cwd()));
|
||||
workflow.registry.addSmartDefaultProvider('workingDirectory', () =>
|
||||
workingDir === '' ? undefined : workingDir,
|
||||
);
|
||||
|
||||
let shouldReportAnalytics = true;
|
||||
|
||||
workflow.engineHost.registerOptionsTransform(async (schematic, options) => {
|
||||
if (shouldReportAnalytics) {
|
||||
shouldReportAnalytics = false;
|
||||
@ -150,6 +156,35 @@ export abstract class SchematicsCommandModule
|
||||
]);
|
||||
}
|
||||
|
||||
// TODO: The below should be removed in version 15 when we change 1P schematics to use the `workingDirectory smart default`.
|
||||
// Handle `"format": "path"` options.
|
||||
const schema = schematic?.schemaJson;
|
||||
if (!options || !schema || !isJsonObject(schema)) {
|
||||
return options;
|
||||
}
|
||||
|
||||
if (!('path' in options && (options as Record<string, unknown>)['path'] === undefined)) {
|
||||
return options;
|
||||
}
|
||||
|
||||
const properties = schema?.['properties'];
|
||||
if (!properties || !isJsonObject(properties)) {
|
||||
return options;
|
||||
}
|
||||
|
||||
const property = properties['path'];
|
||||
if (!property || !isJsonObject(property)) {
|
||||
return options;
|
||||
}
|
||||
|
||||
if (property['format'] === 'path' && !property['$default']) {
|
||||
(options as Record<string, unknown>)['path'] = workingDir || undefined;
|
||||
this.context.logger.warn(
|
||||
`The 'path' option in '${schematic?.schema}' is using deprecated behaviour.` +
|
||||
`'workingDirectory' smart default provider should be used instead.`,
|
||||
);
|
||||
}
|
||||
|
||||
return options;
|
||||
});
|
||||
|
||||
|
@ -27,19 +27,16 @@
|
||||
},
|
||||
"main": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "The name of the main entry-point file.",
|
||||
"default": "main.server.ts"
|
||||
},
|
||||
"appDir": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "The name of the application directory.",
|
||||
"default": "app"
|
||||
},
|
||||
"rootModuleFileName": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "The name of the root module file",
|
||||
"default": "app.server.module.ts"
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the class, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -9,6 +9,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the interface that defines the directive, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the enum definition, relative to the current workspace.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -29,6 +29,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the interface that defines the guard, relative to the current workspace.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the interceptor, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the interface, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the NgModule, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -18,6 +18,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the pipe, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -29,6 +29,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the interface that defines the resolver, relative to the current workspace.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -17,7 +17,9 @@
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the service, relative to the workspace root.",
|
||||
"visible": false
|
||||
},
|
||||
|
@ -9,6 +9,9 @@
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"$default": {
|
||||
"$source": "workingDirectory"
|
||||
},
|
||||
"description": "The path at which to create the worker file, relative to the current workspace.",
|
||||
"visible": false
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user