Victor Savkin f816fc424d Revert "feat(core): update to next version of angular deps"
This reverts commit bd230e0530e690b2ae7896a876510f62002943c8.
2019-12-10 08:07:26 -05:00

185 lines
4.9 KiB
TypeScript

import { Architect } from '@angular-devkit/architect';
import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node';
import {
experimental,
json,
logging,
normalize,
schema,
terminal
} from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { getLogger } from '../shared/logger';
import {
coerceTypes,
convertToCamelCase,
handleErrors,
Schema
} from '../shared/params';
import { commandName, printHelp } from '../shared/print-help';
import minimist = require('minimist');
export interface RunOptions {
project: string;
target: string;
configuration: string;
help: boolean;
runOptions: { [k: string]: any };
}
function throwInvalidInvocation() {
throw new Error(
`Specify the project name and the target (e.g., ${commandName} run proj:build)`
);
}
function parseRunOpts(
args: string[],
defaultProjectName: string | null,
logger: logging.Logger
): RunOptions {
const runOptions = convertToCamelCase(
minimist(args, {
boolean: ['help', 'prod'],
string: ['configuration', 'project']
})
);
const help = runOptions.help;
if (!runOptions._ || !runOptions._[0]) {
throwInvalidInvocation();
}
let [project, target, configuration] = runOptions._[0].split(':');
if (!project && defaultProjectName) {
logger.debug(
`No project name specified. Using default project : ${terminal.bold(
defaultProjectName
)}`
);
project = defaultProjectName;
}
if (!project || !target) {
throwInvalidInvocation();
}
if (runOptions.configuration) {
configuration = runOptions.configuration;
}
if (runOptions.prod) {
configuration = 'production';
}
if (runOptions.project) {
project = runOptions.project;
}
const res = { project, target, configuration, help, runOptions };
delete runOptions['help'];
delete runOptions['_'];
delete runOptions['configuration'];
delete runOptions['prod'];
delete runOptions['project'];
return res;
}
function printRunHelp(
opts: RunOptions,
schema: Schema,
logger: logging.Logger
) {
printHelp(
`${commandName} run ${opts.project}:${opts.target}`,
schema,
logger
);
}
export function validateTargetAndConfiguration(
workspace: experimental.workspace.Workspace,
opts: RunOptions
) {
const targets = workspace.getProjectTargets(opts.project);
const target = targets[opts.target];
if (!target) {
throw new Error(
`Could not find target "${opts.target}" in the ${
opts.project
} project. Valid targets are: ${terminal.bold(
Object.keys(targets).join(', ')
)}`
);
}
// Not all targets have configurations
// and an undefined configuration is valid
if (opts.configuration) {
if (target.configurations) {
const configuration = target.configurations[opts.configuration];
if (!configuration) {
throw new Error(
`Could not find configuration "${opts.configuration}" in ${
opts.project
}:${opts.target}. Valid configurations are: ${Object.keys(
target.configurations
).join(', ')}`
);
}
} else {
throw new Error(
`No configurations are defined for ${opts.project}:${opts.target}, so "${opts.configuration}" is invalid.`
);
}
}
}
export async function run(root: string, args: string[], isVerbose: boolean) {
const logger = getLogger(isVerbose);
return handleErrors(logger, isVerbose, async () => {
const fsHost = new NodeJsSyncHost();
const workspace = await new experimental.workspace.Workspace(
normalize(root) as any,
fsHost
)
.loadWorkspaceFromHost('workspace.json' as any)
.toPromise();
const opts = parseRunOpts(args, workspace.getDefaultProjectName(), logger);
validateTargetAndConfiguration(workspace, opts);
const registry = new json.schema.CoreSchemaRegistry();
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
const architectHost = new WorkspaceNodeModulesArchitectHost(
workspace,
root
);
const architect = new Architect(architectHost, registry);
const builderConf = await architectHost.getBuilderNameForTarget({
project: opts.project,
target: opts.target
});
const builderDesc = await architectHost.resolveBuilder(builderConf);
const flattenedSchema = await registry
.flatten(builderDesc.optionSchema! as json.JsonObject)
.toPromise();
if (opts.help) {
printRunHelp(opts, flattenedSchema as any, logger);
return 0;
}
const runOptions = coerceTypes(opts.runOptions, flattenedSchema as any);
const run = await architect.scheduleTarget(
{
project: opts.project,
target: opts.target,
configuration: opts.configuration
},
runOptions,
{ logger }
);
const result = await run.output.toPromise();
await run.stop();
return result.success ? 0 : 1;
});
}