Skip to content

Commit 63e45bc

Browse files
thekhegayclydin
authored andcommitted
fix(@angular/cli): keep schematic positional arguments in index order
sort checked `positional` for truthiness, so argument at index 0 was ordered like plain option and help showed it after index 1 when that argument has `x-prompt` both are optional for yargs and values go to wrong argumnets, now positionals are sorted by index (cherry picked from commit d69dcec)
1 parent e78cf0a commit 63e45bc

3 files changed

Lines changed: 52 additions & 9 deletions

File tree

‎packages/angular/cli/src/command-builder/utilities/json-schema.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,10 @@ export async function parseJsonSchemaToOptions(
390390

391391
// Sort by positional and name.
392392
return options.sort((a, b) => {
393-
if (a.positional) {
394-
return b.positional ? a.positional - b.positional : a.name.localeCompare(b.name);
395-
} else if (b.positional) {
396-
return -1;
393+
if (a.positional !== undefined) {
394+
return b.positional !== undefined ? a.positional - b.positional : -1;
395+
} else if (b.positional !== undefined) {
396+
return 1;
397397
}
398398

399399
return a.name.localeCompare(b.name);

‎packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,47 @@ describe('parseJsonSchemaToOptions', () => {
345345
);
346346
});
347347
});
348+
349+
describe('with positional arguments not in alphabetical order', () => {
350+
it('sorts positional arguments by their index', async () => {
351+
const jsonSchema = {
352+
'$id': 'FakeSchema',
353+
'title': 'Fake Schema',
354+
'type': 'object',
355+
'required': ['preset'],
356+
'properties': {
357+
'preset': {
358+
'type': 'string',
359+
'enum': ['form', 'table'],
360+
'description': 'preset.',
361+
'$default': {
362+
'$source': 'argv',
363+
'index': 0,
364+
},
365+
'x-prompt': 'Which preset?',
366+
},
367+
'name': {
368+
'type': 'string',
369+
'description': 'name.',
370+
'$default': {
371+
'$source': 'argv',
372+
'index': 1,
373+
},
374+
},
375+
'path': {
376+
'type': 'string',
377+
'description': 'path.',
378+
},
379+
},
380+
};
381+
const registry = new schema.CoreSchemaRegistry();
382+
const options = await parseJsonSchemaToOptions(registry, jsonSchema, /* interactive= */ true);
383+
384+
expect(options).toEqual([
385+
jasmine.objectContaining({ name: 'preset', positional: 0, required: false }),
386+
jasmine.objectContaining({ name: 'name', positional: 1, required: false }),
387+
jasmine.objectContaining({ name: 'path', positional: undefined, required: false }),
388+
]);
389+
});
390+
});
348391
});

‎tests/e2e/tests/generate/help-output.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,22 @@ export default function () {
3232
"$id": "FakeSchema",
3333
"title": "Fake Schema",
3434
"type": "object",
35-
"required": ["a"],
35+
"required": ["b"],
3636
"properties": {
3737
"b": {
3838
"type": "string",
3939
"description": "b.",
4040
"$default": {
4141
"$source": "argv",
42-
"index": 1
42+
"index": 0
4343
}
4444
},
4545
"a": {
4646
"type": "string",
4747
"description": "a.",
4848
"$default": {
4949
"$source": "argv",
50-
"index": 0
50+
"index": 1
5151
}
5252
},
5353
"optC": {
@@ -76,7 +76,7 @@ export default function () {
7676
)
7777
.then(() => ng('generate', 'fake-schematics:fake', '--help'))
7878
.then(({ stdout }) => {
79-
assert.match(stdout, /ng generate fake-schematics:fake <a> \[b\]/);
79+
assert.match(stdout, /ng generate fake-schematics:fake <b> \[a\]/);
8080
assert.match(stdout, /opt-a[\s\S]*opt-b[\s\S]*opt-c/);
8181
})
8282
// set up default collection.
@@ -89,7 +89,7 @@ export default function () {
8989
.then(() => ng('generate', 'fake', '--help'))
9090
// verify same output
9191
.then(({ stdout }) => {
92-
assert.match(stdout, /ng generate fake <a> \[b\]/);
92+
assert.match(stdout, /ng generate fake <b> \[a\]/);
9393
assert.match(stdout, /opt-a[\s\S]*opt-b[\s\S]*opt-c/);
9494
})
9595

0 commit comments

Comments
 (0)