Skip to content

Commit 41fb78b

Browse files
committed
fix(@angular/cli): handle format path in invoked schematics
With this change we change the how we handle `"format": "path"` schematic property option. Previously, in version 14 this format was only being applied on parent schematics that were registered as commands. With this change we apply the formatter on all options, even those who are called programmatically using APIs like `externalSchematic`.
1 parent fe3d8ca commit 41fb78b

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

packages/angular/cli/src/command-builder/command-module.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { analytics, logging, normalize, schema, strings } from '@angular-devkit/core';
9+
import { analytics, logging, schema, strings } from '@angular-devkit/core';
1010
import { readFileSync } from 'fs';
1111
import * as path from 'path';
1212
import {
@@ -197,8 +197,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
197197
* **Note:** This method should be called from the command bundler method.
198198
*/
199199
protected addSchemaOptionsToCommand<T>(localYargs: Argv<T>, options: Option[]): Argv<T> {
200-
const workingDir = normalize(path.relative(this.context.root, process.cwd()));
201-
202200
for (const option of options) {
203201
const {
204202
default: defaultVal,
@@ -211,7 +209,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
211209
hidden,
212210
name,
213211
choices,
214-
format,
215212
} = option;
216213

217214
const sharedOptions: YargsOptions & PositionalOptions = {
@@ -224,11 +221,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
224221
...(this.context.args.options.help ? { default: defaultVal } : {}),
225222
};
226223

227-
// Special case for schematics
228-
if (workingDir && format === 'path' && name === 'path' && hidden) {
229-
sharedOptions.default = workingDir;
230-
}
231-
232224
if (positional === undefined) {
233225
localYargs = localYargs.option(strings.dasherize(name), {
234226
type,

packages/angular/cli/src/command-builder/schematics-command-module.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { schema, tags } from '@angular-devkit/core';
9+
import { normalize as devkitNormalize, isJsonObject, schema, tags } from '@angular-devkit/core';
1010
import { Collection, UnsuccessfulWorkflowExecution, formats } from '@angular-devkit/schematics';
1111
import {
1212
FileSystemCollectionDescription,
1313
FileSystemSchematicDescription,
1414
NodeWorkflow,
1515
} from '@angular-devkit/schematics/tools';
1616
import type { CheckboxQuestion, Question } from 'inquirer';
17-
import { resolve } from 'path';
17+
import { relative, resolve } from 'path';
1818
import { Argv } from 'yargs';
1919
import { getProjectByCwd, getSchematicDefaults } from '../utilities/config';
2020
import { memoize } from '../utilities/memoize';
@@ -137,6 +137,8 @@ export abstract class SchematicsCommandModule
137137
workflow.registry.useXDeprecatedProvider((msg) => logger.warn(msg));
138138

139139
let shouldReportAnalytics = true;
140+
const workingDir = devkitNormalize(relative(this.context.root, process.cwd()));
141+
140142
workflow.engineHost.registerOptionsTransform(async (schematic, options) => {
141143
if (shouldReportAnalytics) {
142144
shouldReportAnalytics = false;
@@ -150,6 +152,32 @@ export abstract class SchematicsCommandModule
150152
]);
151153
}
152154

155+
// Handle `"format": "path"` options.
156+
const schema = schematic?.schemaJson;
157+
if (!options || workingDir === '' || !schema || !isJsonObject(schema)) {
158+
return options;
159+
}
160+
161+
for (const [key, value] of Object.entries(options)) {
162+
if (value !== undefined) {
163+
continue;
164+
}
165+
166+
const properties = schema?.['properties'];
167+
if (!properties || !isJsonObject(properties)) {
168+
break;
169+
}
170+
171+
const property = properties[key];
172+
if (!property || !isJsonObject(property)) {
173+
continue;
174+
}
175+
176+
if (property['format'] === 'path') {
177+
(options as Record<string, unknown>)[key] = workingDir;
178+
}
179+
}
180+
153181
return options;
154182
});
155183

0 commit comments

Comments
 (0)