From e751464ea330cfcab5aa8de3a84c05776d3ed1a9 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 24 May 2022 16:37:19 +0000 Subject: [PATCH] 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`. --- .../cli/src/command-builder/command-module.ts | 10 +--- .../schematics-command-module.ts | 47 ++++++++++++++++--- .../schematics/angular/app-shell/schema.json | 3 -- packages/schematics/angular/class/schema.json | 3 ++ .../schematics/angular/component/schema.json | 3 ++ .../schematics/angular/directive/schema.json | 3 ++ packages/schematics/angular/enum/schema.json | 3 ++ packages/schematics/angular/guard/schema.json | 3 ++ .../angular/interceptor/schema.json | 3 ++ .../schematics/angular/interface/schema.json | 3 ++ .../schematics/angular/module/schema.json | 3 ++ packages/schematics/angular/pipe/schema.json | 3 ++ .../schematics/angular/resolver/schema.json | 3 ++ .../schematics/angular/service/schema.json | 4 +- .../schematics/angular/web-worker/schema.json | 3 ++ 15 files changed, 78 insertions(+), 19 deletions(-) diff --git a/packages/angular/cli/src/command-builder/command-module.ts b/packages/angular/cli/src/command-builder/command-module.ts index 5de4e4e437..0ca5b12a74 100644 --- a/packages/angular/cli/src/command-builder/command-module.ts +++ b/packages/angular/cli/src/command-builder/command-module.ts @@ -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 implements CommandModuleI * **Note:** This method should be called from the command bundler method. */ protected addSchemaOptionsToCommand(localYargs: Argv, options: Option[]): Argv { - 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 implements CommandModuleI hidden, name, choices, - format, } = option; const sharedOptions: YargsOptions & PositionalOptions = { @@ -224,11 +221,6 @@ export abstract class CommandModule 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, diff --git a/packages/angular/cli/src/command-builder/schematics-command-module.ts b/packages/angular/cli/src/command-builder/schematics-command-module.ts index ec371fe228..13102644e8 100644 --- a/packages/angular/cli/src/command-builder/schematics-command-module.ts +++ b/packages/angular/cli/src/command-builder/schematics-command-module.ts @@ -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)['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)['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; }); @@ -356,9 +391,9 @@ export abstract class SchematicsCommandModule if (typeof defaultProjectName === 'string' && defaultProjectName) { if (!this.defaultProjectDeprecationWarningShown) { logger.warn(tags.oneLine` - DEPRECATED: The 'defaultProject' workspace option has been deprecated. - The project to use will be determined from the current working directory. - `); + DEPRECATED: The 'defaultProject' workspace option has been deprecated. + The project to use will be determined from the current working directory. + `); this.defaultProjectDeprecationWarningShown = true; } diff --git a/packages/schematics/angular/app-shell/schema.json b/packages/schematics/angular/app-shell/schema.json index 44fba253e0..460a45e960 100644 --- a/packages/schematics/angular/app-shell/schema.json +++ b/packages/schematics/angular/app-shell/schema.json @@ -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" }, diff --git a/packages/schematics/angular/class/schema.json b/packages/schematics/angular/class/schema.json index 1999daaea8..6bb235b5dd 100644 --- a/packages/schematics/angular/class/schema.json +++ b/packages/schematics/angular/class/schema.json @@ -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 }, diff --git a/packages/schematics/angular/component/schema.json b/packages/schematics/angular/component/schema.json index 38b5d06435..163461ce28 100644 --- a/packages/schematics/angular/component/schema.json +++ b/packages/schematics/angular/component/schema.json @@ -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 }, diff --git a/packages/schematics/angular/directive/schema.json b/packages/schematics/angular/directive/schema.json index 09ed861e67..2caa172ecb 100644 --- a/packages/schematics/angular/directive/schema.json +++ b/packages/schematics/angular/directive/schema.json @@ -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 }, diff --git a/packages/schematics/angular/enum/schema.json b/packages/schematics/angular/enum/schema.json index bb785e5746..c2b154947a 100644 --- a/packages/schematics/angular/enum/schema.json +++ b/packages/schematics/angular/enum/schema.json @@ -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 }, diff --git a/packages/schematics/angular/guard/schema.json b/packages/schematics/angular/guard/schema.json index 76c55dfe3e..f66bdc9428 100644 --- a/packages/schematics/angular/guard/schema.json +++ b/packages/schematics/angular/guard/schema.json @@ -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 }, diff --git a/packages/schematics/angular/interceptor/schema.json b/packages/schematics/angular/interceptor/schema.json index 6bc844ef37..506456c89c 100755 --- a/packages/schematics/angular/interceptor/schema.json +++ b/packages/schematics/angular/interceptor/schema.json @@ -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 }, diff --git a/packages/schematics/angular/interface/schema.json b/packages/schematics/angular/interface/schema.json index 5ae1aeaa9b..3691716f4f 100644 --- a/packages/schematics/angular/interface/schema.json +++ b/packages/schematics/angular/interface/schema.json @@ -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 }, diff --git a/packages/schematics/angular/module/schema.json b/packages/schematics/angular/module/schema.json index bd7c65225d..17b3d09e6a 100644 --- a/packages/schematics/angular/module/schema.json +++ b/packages/schematics/angular/module/schema.json @@ -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 }, diff --git a/packages/schematics/angular/pipe/schema.json b/packages/schematics/angular/pipe/schema.json index 900dac7ccd..3bfab73608 100644 --- a/packages/schematics/angular/pipe/schema.json +++ b/packages/schematics/angular/pipe/schema.json @@ -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 }, diff --git a/packages/schematics/angular/resolver/schema.json b/packages/schematics/angular/resolver/schema.json index e62b537b10..76ad1614c0 100644 --- a/packages/schematics/angular/resolver/schema.json +++ b/packages/schematics/angular/resolver/schema.json @@ -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 }, diff --git a/packages/schematics/angular/service/schema.json b/packages/schematics/angular/service/schema.json index 5c38930393..70b5aba026 100644 --- a/packages/schematics/angular/service/schema.json +++ b/packages/schematics/angular/service/schema.json @@ -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 }, diff --git a/packages/schematics/angular/web-worker/schema.json b/packages/schematics/angular/web-worker/schema.json index f137016447..2b8b9ccca9 100644 --- a/packages/schematics/angular/web-worker/schema.json +++ b/packages/schematics/angular/web-worker/schema.json @@ -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 },