mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-20 05:24:57 +08:00
We made too many shortcuts for passing data in and custom schematics could not work properly. This is temporary as we will likely move some more logic into schematics tooling to be able to pass only the raw args and the CLI config, but for now this is enough to unblock AngularMix.
172 lines
5.0 KiB
TypeScript
172 lines
5.0 KiB
TypeScript
import { cyan, yellow } from 'chalk';
|
|
import { oneLine } from 'common-tags';
|
|
import { CliConfig } from '../models/config';
|
|
|
|
import 'rxjs/add/observable/of';
|
|
import 'rxjs/add/operator/ignoreElements';
|
|
import {
|
|
getCollection,
|
|
getEngineHost
|
|
} from '../utilities/schematics';
|
|
import { DynamicPathOptions, dynamicPathParser } from '../utilities/dynamic-path-parser';
|
|
import { getAppFromConfig } from '../utilities/app-utils';
|
|
import { SchematicAvailableOptions } from '../tasks/schematic-get-options';
|
|
|
|
const Command = require('../ember-cli/lib/models/command');
|
|
const SilentError = require('silent-error');
|
|
|
|
|
|
export default Command.extend({
|
|
name: 'generate',
|
|
description: 'Generates and/or modifies files based on a schematic.',
|
|
aliases: ['g'],
|
|
|
|
availableOptions: [
|
|
{
|
|
name: 'dry-run',
|
|
type: Boolean,
|
|
default: false,
|
|
aliases: ['d'],
|
|
description: 'Run through without making any changes.'
|
|
},
|
|
{
|
|
name: 'force',
|
|
type: Boolean,
|
|
default: false,
|
|
aliases: ['f'],
|
|
description: 'Forces overwriting of files.'
|
|
},
|
|
{
|
|
name: 'app',
|
|
type: String,
|
|
aliases: ['a'],
|
|
description: 'Specifies app name to use.'
|
|
},
|
|
{
|
|
name: 'collection',
|
|
type: String,
|
|
aliases: ['c'],
|
|
description: 'Schematics collection to use.'
|
|
},
|
|
{
|
|
name: 'lint-fix',
|
|
type: Boolean,
|
|
aliases: ['lf'],
|
|
description: 'Use lint to fix files after generation.'
|
|
}
|
|
],
|
|
|
|
anonymousOptions: [
|
|
'<schematic>'
|
|
],
|
|
|
|
getCollectionName(rawArgs: string[]) {
|
|
let collectionName = CliConfig.getValue('defaults.schematics.collection');
|
|
if (rawArgs) {
|
|
const parsedArgs = this.parseArgs(rawArgs, false);
|
|
if (parsedArgs.options.collection) {
|
|
collectionName = parsedArgs.options.collection;
|
|
}
|
|
}
|
|
return collectionName;
|
|
},
|
|
|
|
beforeRun: function(rawArgs: string[]) {
|
|
|
|
const isHelp = ['--help', '-h'].indexOf(rawArgs[0]) != -1;
|
|
if (isHelp) {
|
|
return;
|
|
}
|
|
|
|
const schematicName = rawArgs[0];
|
|
if (!schematicName) {
|
|
return Promise.reject(new SilentError(oneLine`
|
|
The "ng generate" command requires a schematic name to be specified.
|
|
For more details, use "ng help".
|
|
`));
|
|
}
|
|
|
|
if (/^\d/.test(rawArgs[1])) {
|
|
SilentError.debugOrThrow('@angular/cli/commands/generate',
|
|
`The \`ng generate ${schematicName} ${rawArgs[1]}\` file name cannot begin with a digit.`);
|
|
}
|
|
|
|
const SchematicGetOptionsTask = require('../tasks/schematic-get-options').default;
|
|
|
|
const getOptionsTask = new SchematicGetOptionsTask({
|
|
ui: this.ui,
|
|
project: this.project
|
|
});
|
|
const collectionName = this.getCollectionName(rawArgs);
|
|
|
|
return getOptionsTask.run({
|
|
schematicName,
|
|
collectionName
|
|
})
|
|
.then((availableOptions: SchematicAvailableOptions) => {
|
|
let anonymousOptions: string[] = [];
|
|
if (collectionName === '@schematics/angular' && schematicName === 'interface') {
|
|
anonymousOptions = ['<type>'];
|
|
}
|
|
|
|
this.registerOptions({
|
|
anonymousOptions: anonymousOptions,
|
|
availableOptions: availableOptions
|
|
});
|
|
});
|
|
},
|
|
|
|
run: function (commandOptions: any, rawArgs: string[]) {
|
|
if (rawArgs[0] === 'module' && !rawArgs[1]) {
|
|
throw 'The `ng generate module` command requires a name to be specified.';
|
|
}
|
|
|
|
const entityName = rawArgs[1];
|
|
|
|
const appConfig = getAppFromConfig(commandOptions.app);
|
|
const dynamicPathOptions: DynamicPathOptions = {
|
|
project: this.project,
|
|
entityName: entityName,
|
|
appConfig: appConfig,
|
|
dryRun: commandOptions.dryRun
|
|
};
|
|
const parsedPath = dynamicPathParser(dynamicPathOptions);
|
|
|
|
// Do not pass the schematics name itself, that's not useful.
|
|
commandOptions._ = rawArgs.slice(1);
|
|
commandOptions._angularCliConfig = (CliConfig.fromProject() || CliConfig.fromGlobal()).config;
|
|
commandOptions._angularCliAppConfig = appConfig;
|
|
commandOptions._angularCliParsedPath = parsedPath;
|
|
|
|
const cwd = this.project.root;
|
|
const schematicName = rawArgs[0];
|
|
|
|
const SchematicRunTask = require('../tasks/schematic-run').default;
|
|
const schematicRunTask = new SchematicRunTask({
|
|
ui: this.ui,
|
|
project: this.project
|
|
});
|
|
const collectionName = commandOptions.collection ||
|
|
CliConfig.getValue('defaults.schematics.collection');
|
|
|
|
return schematicRunTask.run({
|
|
taskOptions: commandOptions,
|
|
workingDir: cwd,
|
|
collectionName,
|
|
schematicName
|
|
});
|
|
},
|
|
|
|
printDetailedHelp: function () {
|
|
const engineHost = getEngineHost();
|
|
const collectionName = this.getCollectionName();
|
|
const collection = getCollection(collectionName);
|
|
const schematicNames: string[] = engineHost.listSchematics(collection);
|
|
this.ui.writeLine(cyan('Available schematics:'));
|
|
schematicNames.forEach(schematicName => {
|
|
this.ui.writeLine(yellow(` ${schematicName}`));
|
|
});
|
|
this.ui.writeLine('');
|
|
}
|
|
});
|