Skip to content

Commit

Permalink
feat(nx): add verbose flag to @nrwl/tao which will output stack trace…
Browse files Browse the repository at this point in the history
… on error
  • Loading branch information
catfireparty authored and vsavkin committed Oct 1, 2019
1 parent e13910d commit 4b4a5dc
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 85 deletions.
38 changes: 28 additions & 10 deletions packages/tao/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,59 @@ import './src/compat/compat';
export async function invokeCommand(
command: string,
root: string,
commandArgs: string[]
commandArgs: string[] = []
) {
if (command === undefined) {
command = 'help';
}

let verboseFlagIndex = commandArgs.indexOf('--verbose');
if (verboseFlagIndex < 0) {
verboseFlagIndex = commandArgs.indexOf('-v');
}
const isVerbose = verboseFlagIndex >= 0;
if (isVerbose) {
commandArgs.splice(verboseFlagIndex, 1);
}

switch (command) {
case 'new':
return (await import('./src/commands/generate')).taoNew(
root,
commandArgs
commandArgs,
isVerbose
);
case 'generate':
case 'g':
return (await import('./src/commands/generate')).generate(
root,
commandArgs
commandArgs,
isVerbose
);
case 'run':
case 'r':
return (await import('./src/commands/run')).run(root, commandArgs);
return (await import('./src/commands/run')).run(
root,
commandArgs,
isVerbose
);
case 'migrate':
return (await import('./src/commands/migrate')).migrate(
root,
commandArgs
commandArgs,
isVerbose
);
case 'help':
case '--help':
return (await import('./src/commands/help')).printHelp();
return (await import('./src/commands/help')).help();
default:
const projectName = commandArgs[0] ? 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)
]);
return (await import('./src/commands/run')).run(
root,
[`${projectName}:${command}`, ...commandArgs.slice(1)],
isVerbose
);
}
}

Expand Down
60 changes: 38 additions & 22 deletions packages/tao/src/commands/generate.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import {
coerceTypes,
convertAliases,
convertToCamelCase,
handleErrors,
Schema
} from '../shared/params';
import {
experimental,
JsonObject,
Expand All @@ -15,24 +8,30 @@ import {
terminal,
virtualFs
} from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import {
DryRunEvent,
formats,
HostTree,
Schematic,
formats
Schematic
} from '@angular-devkit/schematics';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import {
NodeWorkflow,
validateOptionsWithSchema,
FileSystemSchematicDescription
validateOptionsWithSchema
} from '@angular-devkit/schematics/tools';
import { execSync } from 'child_process';
import * as fs from 'fs';
import * as inquirer from 'inquirer';
import { logger } from '../shared/logger';
import { getLogger } from '../shared/logger';
import {
coerceTypes,
convertAliases,
convertToCamelCase,
handleErrors,
Schema
} from '../shared/params';
import { commandName, printHelp } from '../shared/print-help';
import * as fs from 'fs';
import minimist = require('minimist');
import { execSync } from 'child_process';

interface GenerateOptions {
collectionName: string;
Expand Down Expand Up @@ -290,7 +289,11 @@ function getCollection(workflow: NodeWorkflow, name: string) {
return collection;
}

function printGenHelp(opts: GenerateOptions, schema: Schema) {
function printGenHelp(
opts: GenerateOptions,
schema: Schema,
logger: logging.Logger
) {
printHelp(
`${commandName} generate ${opts.collectionName}:${opts.schematicName}`,
{
Expand All @@ -299,7 +302,8 @@ function printGenHelp(opts: GenerateOptions, schema: Schema) {
...schema.properties,
dryRun: `Runs through and reports activity without writing to disk.`
}
}
},
logger
);
}

Expand Down Expand Up @@ -346,7 +350,7 @@ async function runSchematic(
.toPromise();

if (opts.help) {
printGenHelp(opts, flattenedSchema as any);
printGenHelp(opts, flattenedSchema as any, logger);
} else {
const defaults =
opts.schematicName === 'tao-new'
Expand Down Expand Up @@ -381,8 +385,14 @@ async function runSchematic(
return 0;
}

export async function generate(root: string, args: string[]) {
return handleErrors(logger, async () => {
export async function generate(
root: string,
args: string[],
isVerbose: boolean = false
) {
const logger = getLogger(isVerbose);

return handleErrors(logger, isVerbose, async () => {
const fsHost = new virtualFs.ScopedHost(
new NodeJsSyncHost(),
normalize(root)
Expand Down Expand Up @@ -412,8 +422,14 @@ async function readDefaultCollection(host: virtualFs.Host<any>) {
return workspaceJson.cli ? workspaceJson.cli.defaultCollection : null;
}

export async function taoNew(root: string, args: string[]) {
return handleErrors(logger, async () => {
export async function taoNew(
root: string,
args: string[],
isVerbose: boolean = false
) {
const logger = getLogger(isVerbose);

return handleErrors(logger, isVerbose, async () => {
const fsHost = new virtualFs.ScopedHost(
new NodeJsSyncHost(),
normalize(root)
Expand Down
11 changes: 6 additions & 5 deletions packages/tao/src/commands/help.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { tags } from '@angular-devkit/core';
import { logger } from '../shared/logger';
import { toolDescription, commandName } from '../shared/print-help';
import { terminal } from '@angular-devkit/core';
import { tags, terminal } from '@angular-devkit/core';
import { getLogger } from '../shared/logger';
import { commandName, toolDescription } from '../shared/print-help';

export function help() {
const logger = getLogger(true);

export function printHelp() {
logger.info(tags.stripIndent`
${terminal.bold(toolDescription)}
Expand Down
36 changes: 20 additions & 16 deletions packages/tao/src/commands/migrate.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { gt, lte } from 'semver';
import { handleErrors, convertToCamelCase } from '../shared/params';
import { logger } from '../shared/logger';
import minimist = require('minimist');
import { commandName } from '../shared/print-help';
import { virtualFs, normalize, logging } from '@angular-devkit/core';
import { logging, normalize, virtualFs } from '@angular-devkit/core';
import * as core from '@angular-devkit/core/node';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { HostTree } from '@angular-devkit/schematics';
import { dirSync } from 'tmp';
import { readFileSync, writeFileSync, statSync } from 'fs';
import { NodeModulesEngineHost } from '@angular-devkit/schematics/tools';
import { BaseWorkflow } from '@angular-devkit/schematics/src/workflow';
import * as stripJsonComments from 'strip-json-comments';

import * as path from 'path';
import * as core from '@angular-devkit/core/node';
import { NodeModulesEngineHost } from '@angular-devkit/schematics/tools';
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
import * as path from 'path';
import { gt, lte } from 'semver';
import * as stripJsonComments from 'strip-json-comments';
import { dirSync } from 'tmp';
import { getLogger } from '../shared/logger';
import { convertToCamelCase, handleErrors } from '../shared/params';
import { commandName } from '../shared/print-help';
import minimist = require('minimist');

export type MigrationsJson = {
version: string;
Expand Down Expand Up @@ -484,8 +482,14 @@ async function runMigrations(
await p;
}

export async function migrate(root: string, args: string[]) {
return handleErrors(logger, async () => {
export async function migrate(
root: string,
args: string[],
isVerbose: boolean = false
) {
const logger = getLogger(isVerbose);

return handleErrors(logger, isVerbose, async () => {
const opts = parseMigrationsOptions(args);
if (opts.type === 'generateMigrations') {
await generateMigrationsJsonAndUpdatePackageJson(logger, root, opts);
Expand Down
44 changes: 27 additions & 17 deletions packages/tao/src/commands/run.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import {
convertToCamelCase,
handleErrors,
Schema,
coerceTypes
} from '../shared/params';
import { Architect } from '@angular-devkit/architect';
import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node';
import {
experimental,
json,
logging,
normalize,
schema,
tags
schema
} from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node';
import { Architect } from '@angular-devkit/architect';
import { logger } from '../shared/logger';
import { getLogger } from '../shared/logger';
import {
coerceTypes,
convertToCamelCase,
handleErrors,
Schema
} from '../shared/params';
import { commandName, printHelp } from '../shared/print-help';
import minimist = require('minimist');
import { printHelp, commandName } from '../shared/print-help';

export interface RunOptions {
project: string;
Expand Down Expand Up @@ -70,12 +70,22 @@ function parseRunOpts(
return res;
}

function printRunHelp(opts: RunOptions, schema: Schema) {
printHelp(`${commandName} run ${opts.project}:${opts.target}`, schema);
function printRunHelp(
opts: RunOptions,
schema: Schema,
logger: logging.Logger
) {
printHelp(
`${commandName} run ${opts.project}:${opts.target}`,
schema,
logger
);
}

export async function run(root: string, args: string[]) {
return handleErrors(logger, async () => {
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,
Expand All @@ -102,7 +112,7 @@ export async function run(root: string, args: string[]) {
.flatten(builderDesc.optionSchema! as json.JsonObject)
.toPromise();
if (opts.help) {
printRunHelp(opts, flattenedSchema as any);
printRunHelp(opts, flattenedSchema as any, logger);
return 0;
} else {
const runOptions = coerceTypes(opts.runOptions, flattenedSchema as any);
Expand Down
21 changes: 11 additions & 10 deletions packages/tao/src/shared/logger.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { logging, terminal } from '@angular-devkit/core';
import { createConsoleLogger } from '@angular-devkit/core/node';
import { terminal } from '@angular-devkit/core';

export const logger = createConsoleLogger(
false,
process.stdout,
process.stderr,
{
warn: s => terminal.bold(terminal.yellow(s)),
error: s => terminal.bold(terminal.red(s)),
fatal: s => terminal.bold(terminal.red(s))
let logger: logging.Logger;
export const getLogger = (isVerbose: boolean = false) => {
if (!logger) {
logger = createConsoleLogger(isVerbose, process.stdout, process.stderr, {
warn: s => terminal.bold(terminal.yellow(s)),
error: s => terminal.bold(terminal.red(s)),
fatal: s => terminal.bold(terminal.red(s))
});
}
);
return logger;
};
9 changes: 8 additions & 1 deletion packages/tao/src/shared/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ export type Schema = {
description: string;
};

export async function handleErrors(logger: logging.Logger, fn: Function) {
export async function handleErrors(
logger: logging.Logger,
isVerbose: boolean,
fn: Function
) {
try {
return await fn();
} catch (err) {
Expand All @@ -16,6 +20,9 @@ export async function handleErrors(logger: logging.Logger, fn: Function) {
} else {
logger.fatal(err.message);
}
if (isVerbose && err.stack) {
logger.info(err.stack);
}
return 1;
}
}
Expand Down
10 changes: 6 additions & 4 deletions packages/tao/src/shared/print-help.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { logging, tags, terminal } from '@angular-devkit/core';
import { Schema } from './params';
import { logger } from './logger';
import { tags } from '@angular-devkit/core';
import { terminal } from '@angular-devkit/core';

export function printHelp(header: string, schema: Schema) {
export function printHelp(
header: string,
schema: Schema,
logger: logging.Logger
) {
const allPositional = Object.keys(schema.properties).filter(key => {
const p = schema.properties[key];
return p['$default'] && p['$default']['$source'] === 'argv';
Expand Down

0 comments on commit 4b4a5dc

Please sign in to comment.