fix(nx): validate target and configuration in @nrwl/tao/run and provide better errors
This commit is contained in:
parent
fa675f1194
commit
58353a6be8
@ -1,16 +1,16 @@
|
||||
import { packagesWeCareAbout } from '@nrwl/workspace/src/command-line/report';
|
||||
import { ensureProject, forEachCli, runCLI } from './utils';
|
||||
import { ensureProject, forEachCli, runCommand } from './utils';
|
||||
|
||||
const testTimeout = 120000;
|
||||
|
||||
forEachCli('nx', () => {
|
||||
forEachCli(() => {
|
||||
describe('report', () => {
|
||||
it(
|
||||
`should report package versions`,
|
||||
async () => {
|
||||
ensureProject();
|
||||
|
||||
const reportOutput = runCLI('report');
|
||||
const reportOutput = runCommand('npm run nx report');
|
||||
|
||||
packagesWeCareAbout.forEach(p => {
|
||||
expect(reportOutput).toContain(p);
|
||||
@ -20,15 +20,3 @@ forEachCli('nx', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
forEachCli('angular', () => {
|
||||
describe('report', () => {
|
||||
it(
|
||||
`shouldn't do anything at all`,
|
||||
async () => {
|
||||
// report is an Nx only command
|
||||
},
|
||||
testTimeout
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -49,12 +49,18 @@ export async function invokeCommand(
|
||||
case 'help':
|
||||
case '--help':
|
||||
return (await import('./src/commands/help')).help();
|
||||
|
||||
default:
|
||||
const projectName = commandArgs[0] ? commandArgs[0] : '';
|
||||
const projectNameIncluded =
|
||||
commandArgs[0] && !commandArgs[0].startsWith('-');
|
||||
const projectName = projectNameIncluded ? commandArgs[0] : '';
|
||||
// this is to make `tao test mylib` same as `tao run mylib:test`
|
||||
return (await import('./src/commands/run')).run(
|
||||
root,
|
||||
[`${projectName}:${command}`, ...commandArgs.slice(1)],
|
||||
[
|
||||
`${projectName}:${command}`,
|
||||
...(projectNameIncluded ? commandArgs.slice(1) : commandArgs)
|
||||
],
|
||||
isVerbose
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,7 +5,8 @@ import {
|
||||
json,
|
||||
logging,
|
||||
normalize,
|
||||
schema
|
||||
schema,
|
||||
terminal
|
||||
} from '@angular-devkit/core';
|
||||
import { NodeJsSyncHost } from '@angular-devkit/core/node';
|
||||
import { getLogger } from '../shared/logger';
|
||||
@ -34,7 +35,8 @@ function throwInvalidInvocation() {
|
||||
|
||||
function parseRunOpts(
|
||||
args: string[],
|
||||
defaultProjectName: string | null
|
||||
defaultProjectName: string | null,
|
||||
logger: logging.Logger
|
||||
): RunOptions {
|
||||
const runOptions = convertToCamelCase(
|
||||
minimist(args, {
|
||||
@ -47,7 +49,14 @@ function parseRunOpts(
|
||||
throwInvalidInvocation();
|
||||
}
|
||||
let [project, target, configuration] = runOptions._[0].split(':');
|
||||
if (!project && defaultProjectName) project = defaultProjectName;
|
||||
if (!project && defaultProjectName) {
|
||||
logger.debug(
|
||||
`No project name specified. Using default project : ${terminal.bold(
|
||||
defaultProjectName
|
||||
)}`
|
||||
);
|
||||
project = defaultProjectName;
|
||||
}
|
||||
if (!project || !target) {
|
||||
throwInvalidInvocation();
|
||||
}
|
||||
@ -82,6 +91,45 @@ function printRunHelp(
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -93,7 +141,9 @@ export async function run(root: string, args: string[], isVerbose: boolean) {
|
||||
)
|
||||
.loadWorkspaceFromHost('workspace.json' as any)
|
||||
.toPromise();
|
||||
const opts = parseRunOpts(args, workspace.getDefaultProjectName());
|
||||
|
||||
const opts = parseRunOpts(args, workspace.getDefaultProjectName(), logger);
|
||||
validateTargetAndConfiguration(workspace, opts);
|
||||
|
||||
const registry = new json.schema.CoreSchemaRegistry();
|
||||
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
|
||||
@ -111,23 +161,24 @@ export async function run(root: string, args: string[], isVerbose: boolean) {
|
||||
const flattenedSchema = await registry
|
||||
.flatten(builderDesc.optionSchema! as json.JsonObject)
|
||||
.toPromise();
|
||||
|
||||
if (opts.help) {
|
||||
printRunHelp(opts, flattenedSchema as any, logger);
|
||||
return 0;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user