Skip to content

Commit

Permalink
fix(@angular/cli): populate path with working directory in nested sch…
Browse files Browse the repository at this point in the history
…ematics

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`.
  • Loading branch information
alan-agius4 committed May 24, 2022
1 parent fe3d8ca commit 3aa32de
Show file tree
Hide file tree
Showing 16 changed files with 81 additions and 19 deletions.
10 changes: 1 addition & 9 deletions packages/angular/cli/src/command-builder/command-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -211,7 +209,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
hidden,
name,
choices,
format,
} = option;

const sharedOptions: YargsOptions & PositionalOptions = {
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
* 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,
FileSystemSchematicDescription,
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';
Expand Down Expand Up @@ -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;
Expand All @@ -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;
});

Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 0 additions & 3 deletions packages/schematics/angular/app-shell/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/class/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/component/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/directive/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/enum/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/guard/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/interceptor/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/interface/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/library/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"entryFile": {
"type": "string",
"format": "path",
"$default": {
"$source": "workingDirectory"
},
"description": "The path at which to create the library's public API file, relative to the workspace root.",
"default": "public-api"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/module/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/pipe/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/resolver/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
4 changes: 3 additions & 1 deletion packages/schematics/angular/service/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
3 changes: 3 additions & 0 deletions packages/schematics/angular/web-worker/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down

0 comments on commit 3aa32de

Please sign in to comment.