mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-16 18:43:42 +08:00
fix(@angular/cli): error out when command json is invalid
This commit is contained in:
parent
7ca3bb5263
commit
eef66f0f65
@ -36,7 +36,6 @@ export class GenerateCommand extends SchematicCommand<GenerateCommandSchema> {
|
||||
schematic.description.path,
|
||||
this._workflow.registry,
|
||||
schematic.description.schemaJson,
|
||||
this.logger,
|
||||
);
|
||||
} else {
|
||||
continue;
|
||||
|
@ -92,7 +92,7 @@ export async function runCommand(
|
||||
}
|
||||
|
||||
commandMap[name] =
|
||||
await parseJsonSchemaToCommandDescription(name, schemaPath, registry, schema, logger);
|
||||
await parseJsonSchemaToCommandDescription(name, schemaPath, registry, schema);
|
||||
}
|
||||
|
||||
let commandName: string | undefined = undefined;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import { json, logging } from '@angular-devkit/core';
|
||||
import { BaseException, json } from '@angular-devkit/core';
|
||||
import { ExportStringRef } from '@angular-devkit/schematics/tools';
|
||||
import { readFileSync } from 'fs';
|
||||
import { dirname, resolve } from 'path';
|
||||
@ -19,6 +19,13 @@ import {
|
||||
Value,
|
||||
} from '../models/interface';
|
||||
|
||||
|
||||
export class CommandJsonPathException extends BaseException {
|
||||
constructor(public readonly path: string, public readonly name: string) {
|
||||
super(`File ${path} was not found while constructing the subcommand ${name}.`);
|
||||
}
|
||||
}
|
||||
|
||||
function _getEnumFromValue<E, T extends E[keyof E]>(
|
||||
value: json.JsonValue,
|
||||
enumeration: E,
|
||||
@ -40,7 +47,6 @@ export async function parseJsonSchemaToSubCommandDescription(
|
||||
jsonPath: string,
|
||||
registry: json.schema.SchemaRegistry,
|
||||
schema: json.JsonObject,
|
||||
logger: logging.Logger,
|
||||
): Promise<SubCommandDescription> {
|
||||
const options = await parseJsonSchemaToOptions(registry, schema);
|
||||
|
||||
@ -69,7 +75,7 @@ export async function parseJsonSchemaToSubCommandDescription(
|
||||
try {
|
||||
longDescription = readFileSync(ldPath, 'utf-8');
|
||||
} catch (e) {
|
||||
logger.warn(`File ${ldPath} was not found while constructing the subcommand ${name}.`);
|
||||
throw new CommandJsonPathException(ldPath, name);
|
||||
}
|
||||
}
|
||||
let usageNotes = '';
|
||||
@ -78,7 +84,7 @@ export async function parseJsonSchemaToSubCommandDescription(
|
||||
try {
|
||||
usageNotes = readFileSync(unPath, 'utf-8');
|
||||
} catch (e) {
|
||||
logger.warn(`File ${unPath} was not found while constructing the subcommand ${name}.`);
|
||||
throw new CommandJsonPathException(unPath, name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,10 +105,9 @@ export async function parseJsonSchemaToCommandDescription(
|
||||
jsonPath: string,
|
||||
registry: json.schema.SchemaRegistry,
|
||||
schema: json.JsonObject,
|
||||
logger: logging.Logger,
|
||||
): Promise<CommandDescription> {
|
||||
const subcommand =
|
||||
await parseJsonSchemaToSubCommandDescription(name, jsonPath, registry, schema, logger);
|
||||
await parseJsonSchemaToSubCommandDescription(name, jsonPath, registry, schema);
|
||||
|
||||
// Before doing any work, let's validate the implementation.
|
||||
if (typeof schema.$impl != 'string') {
|
||||
|
76
packages/angular/cli/utilities/json-schema_spec.ts
Normal file
76
packages/angular/cli/utilities/json-schema_spec.ts
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*
|
||||
*/
|
||||
import { schema } from '@angular-devkit/core';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { of } from 'rxjs';
|
||||
import { CommandJsonPathException, parseJsonSchemaToCommandDescription } from './json-schema';
|
||||
|
||||
describe('parseJsonSchemaToCommandDescription', () => {
|
||||
let registry: schema.CoreSchemaRegistry;
|
||||
const baseSchemaJson = {
|
||||
'$schema': 'http://json-schema.org/schema',
|
||||
'$id': 'ng-cli://commands/version.json',
|
||||
'description': 'Outputs Angular CLI version.',
|
||||
'$longDescription': 'not a file ref',
|
||||
|
||||
'$aliases': ['v'],
|
||||
'$scope': 'all',
|
||||
'$impl': './version-impl#VersionCommand',
|
||||
|
||||
'type': 'object',
|
||||
'allOf': [
|
||||
{ '$ref': './definitions.json#/definitions/base' },
|
||||
],
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
registry = new schema.CoreSchemaRegistry([]);
|
||||
registry.registerUriHandler((uri: string) => {
|
||||
if (uri.startsWith('ng-cli://')) {
|
||||
const content = readFileSync(
|
||||
join(__dirname, '..', uri.substr('ng-cli://'.length)), 'utf-8');
|
||||
|
||||
return of(JSON.parse(content));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it(`should throw on invalid $longDescription path`, async () => {
|
||||
const name = 'version';
|
||||
const schemaPath = join(__dirname, './bad-sample.json');
|
||||
const schemaJson = { ...baseSchemaJson, $longDescription: 'not a file ref' };
|
||||
try {
|
||||
await parseJsonSchemaToCommandDescription(name, schemaPath, registry, schemaJson);
|
||||
} catch (error) {
|
||||
const refPath = join(__dirname, schemaJson.$longDescription);
|
||||
expect(error).toEqual(new CommandJsonPathException(refPath, name));
|
||||
|
||||
return;
|
||||
}
|
||||
expect(true).toBe(false, 'function should have thrown');
|
||||
});
|
||||
|
||||
it(`should throw on invalid $usageNotes path`, async () => {
|
||||
const name = 'version';
|
||||
const schemaPath = join(__dirname, './bad-sample.json');
|
||||
const schemaJson = { ...baseSchemaJson, $usageNotes: 'not a file ref' };
|
||||
try {
|
||||
await parseJsonSchemaToCommandDescription(name, schemaPath, registry, schemaJson);
|
||||
} catch (error) {
|
||||
const refPath = join(__dirname, schemaJson.$usageNotes);
|
||||
expect(error).toEqual(new CommandJsonPathException(refPath, name));
|
||||
|
||||
return;
|
||||
}
|
||||
expect(true).toBe(false, 'function should have thrown');
|
||||
});
|
||||
});
|
@ -184,9 +184,9 @@ export default async function(opts: SnapshotsOptions, logger: logging.Logger) {
|
||||
const options = { cwd: newProjectRoot };
|
||||
const childLogger = logger.createChild(commandName);
|
||||
const stdout = _exec(ngPath, [commandName, '--help=json'], options, childLogger);
|
||||
if (stdout.trim()) {
|
||||
fs.writeFileSync(path.join(helpOutputRoot, commandName + '.json'), stdout);
|
||||
}
|
||||
// Make sure the output is JSON before printing it, and format it as well.
|
||||
const jsonOutput = JSON.stringify(JSON.parse(stdout.trim()), undefined, 2);
|
||||
fs.writeFileSync(path.join(helpOutputRoot, commandName + '.json'), jsonOutput);
|
||||
}
|
||||
|
||||
if (!githubToken) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user