зеркало из https://github.com/microsoft/just.git
Switching to yargs-parser rather than yargs (#356)
* totally changing how args are parsed with yargs-parser * fix up initCommand with new yargs types * Change files * fixing up resolve * making the watch script to be consistent * fixing the mocks with yargs init
This commit is contained in:
Родитель
b57d6acd84
Коммит
df664ff35c
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "none",
|
||||
"comment": "fix up initCommand with new yargs types",
|
||||
"packageName": "create-just",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "565e98494de5bae050cdc04365dee0a0aef638d8",
|
||||
"date": "2020-04-10T04:31:08.848Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "Jest now can take a positional arg to run a certain test pattern",
|
||||
"packageName": "just-scripts",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "565e98494de5bae050cdc04365dee0a0aef638d8",
|
||||
"date": "2020-04-10T04:31:34.381Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "Replace yargs with yargs-parser, taking over the command parsing",
|
||||
"packageName": "just-task",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "565e98494de5bae050cdc04365dee0a0aef638d8",
|
||||
"date": "2020-04-10T04:31:52.506Z"
|
||||
}
|
|
@ -39,7 +39,7 @@ async function getStackPath(pathName: string, registry?: string) {
|
|||
* 4. git init and commit
|
||||
* 5. yarn install
|
||||
*/
|
||||
export async function initCommand(argv: yargs.Arguments) {
|
||||
export async function initCommand(argv: yargs.Arguments<{ [key: string]: string }>) {
|
||||
// TODO: autosuggest just-stack-* packages from npmjs.org
|
||||
if (!argv.stack) {
|
||||
const { stack } = await prompts({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { resolve, logger, resolveCwd, TaskFunction } from 'just-task';
|
||||
import { resolve, logger, resolveCwd, TaskFunction, argv } from 'just-task';
|
||||
import { spawn, encodeArgs } from 'just-scripts-utils';
|
||||
import { existsSync } from 'fs';
|
||||
import supportsColor from 'supports-color';
|
||||
|
@ -11,6 +11,8 @@ export interface JestTaskOptions {
|
|||
watch?: boolean;
|
||||
colors?: boolean;
|
||||
passWithNoTests?: boolean;
|
||||
testPathPattern?: string;
|
||||
testNamePattern?: string;
|
||||
u?: boolean;
|
||||
_?: string[];
|
||||
|
||||
|
@ -35,6 +37,10 @@ export function jestTask(options: JestTaskOptions = {}): TaskFunction {
|
|||
if (configFile && jestCmd && existsSync(configFile)) {
|
||||
logger.info(`Running Jest`);
|
||||
const cmd = process.execPath;
|
||||
|
||||
const positional = argv()._.slice(1);
|
||||
options = { ...options, ...{ ...argv(), _: positional } };
|
||||
|
||||
const args = [
|
||||
...(options.nodeArgs || []),
|
||||
jestCmd,
|
||||
|
@ -45,6 +51,8 @@ export function jestTask(options: JestTaskOptions = {}): TaskFunction {
|
|||
...(options.runInBand ? ['--runInBand'] : []),
|
||||
...(options.coverage ? ['--coverage'] : []),
|
||||
...(options.watch ? ['--watch'] : []),
|
||||
...(options.testPathPattern ? ['--testPathPattern', options.testPathPattern] : []),
|
||||
...(options.testNamePattern ? ['--testNamePattern', options.testNamePattern] : []),
|
||||
...(options.u || options.updateSnapshot ? ['--updateSnapshot'] : ['']),
|
||||
...(options._ || [])
|
||||
].filter(arg => !!arg) as Array<string>;
|
||||
|
|
|
@ -15,19 +15,20 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsc -w --preserveWatchOutput",
|
||||
"start": "tsc -w --preserveWatchOutput",
|
||||
"start-test": "jest --watch",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/package-deps-hash": "^2.2.153",
|
||||
"bach": "^1.2.0",
|
||||
"chalk": "^2.4.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"just-task-logger": ">=0.3.0 <1.0.0",
|
||||
"resolve": "^1.8.1",
|
||||
"undertaker": "^1.2.0",
|
||||
"undertaker": "^1.2.1",
|
||||
"undertaker-registry": "^1.0.1",
|
||||
"yargs": "^12.0.5"
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^5.0.4",
|
||||
|
@ -37,7 +38,7 @@
|
|||
"@types/resolve": "^0.0.8",
|
||||
"@types/undertaker": "^1.2.0",
|
||||
"@types/undertaker-registry": "^1.0.1",
|
||||
"@types/yargs": "12.0.1",
|
||||
"@types/yargs-parser": "^15.0.0",
|
||||
"jest": "^24.0.0",
|
||||
"mock-fs": "^4.8.0",
|
||||
"ts-jest": "^24.0.1",
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
import yargs from 'yargs';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { logger, mark } from './logger';
|
||||
|
||||
import UndertakerRegistry from 'undertaker-registry';
|
||||
import Undertaker from 'undertaker';
|
||||
import { resolve } from './resolve';
|
||||
import { enableTypeScript } from './enableTypeScript';
|
||||
|
||||
export class JustTaskRegistry extends UndertakerRegistry {
|
||||
private hasDefault: boolean = false;
|
||||
|
||||
public init(taker: Undertaker) {
|
||||
super.init(taker);
|
||||
|
||||
// uses a separate instance of yargs to first parse the config (without the --help in the way) so we can parse the configFile first regardless
|
||||
const configFile = [yargs.argv.config, './just.config.js', './just-task.js', './just.config.ts'].reduce(
|
||||
(value, entry) => value || resolve(entry)
|
||||
);
|
||||
|
||||
mark('registry:configModule');
|
||||
|
||||
if (configFile && fs.existsSync(configFile)) {
|
||||
const ext = path.extname(configFile);
|
||||
if (ext === '.ts' || ext === '.tsx') {
|
||||
// TODO: add option to do typechecking as well
|
||||
enableTypeScript({ transpileOnly: true });
|
||||
}
|
||||
|
||||
try {
|
||||
const configModule = require(configFile);
|
||||
if (typeof configModule === 'function') {
|
||||
configModule();
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(`Invalid configuration file: ${configFile}`);
|
||||
logger.error(`Error: ${e.stack || e.message || e}`);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
logger.error(
|
||||
`Cannot find config file "${configFile}".`,
|
||||
`Please create a file called "just.config.js" in the root of the project next to "package.json".`
|
||||
);
|
||||
}
|
||||
|
||||
logger.perf('registry:configModule');
|
||||
|
||||
if (!validateCommands(yargs)) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!this.hasDefault) {
|
||||
yargs.demandCommand(1, 'No default tasks are defined.').help();
|
||||
}
|
||||
}
|
||||
|
||||
public set<TTaskFunction>(taskName: string, fn: TTaskFunction): TTaskFunction {
|
||||
super.set(taskName, fn);
|
||||
|
||||
if (taskName === 'default') {
|
||||
this.hasDefault = true;
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
function validateCommands(yargs: any) {
|
||||
const commandKeys = yargs.getCommandInstance().getCommands();
|
||||
const argv = yargs.argv;
|
||||
const unknown: string[] = [];
|
||||
const currentContext = yargs.getContext();
|
||||
|
||||
if (commandKeys.length > 0) {
|
||||
argv._.slice(currentContext.commands.length).forEach((key: string) => {
|
||||
if (commandKeys.indexOf(key) === -1) {
|
||||
unknown.push(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (unknown.length > 0) {
|
||||
logger.error(`Unknown command: ${unknown.join(', ')}`);
|
||||
|
||||
const recommended = recommendCommands(unknown[0], commandKeys);
|
||||
|
||||
if (recommended) {
|
||||
logger.info(`Did you mean this task name: ${recommended}?`);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function recommendCommands(cmd: string, potentialCommands: string[]) {
|
||||
const distance = require('yargs/lib/levenshtein');
|
||||
const threshold = 3; // if it takes more than three edits, let's move on.
|
||||
potentialCommands = potentialCommands.sort((a, b) => b.length - a.length);
|
||||
|
||||
let recommended = null;
|
||||
let bestDistance = Infinity;
|
||||
for (let i = 0, candidate; (candidate = potentialCommands[i]) !== undefined; i++) {
|
||||
const d = distance(cmd, candidate);
|
||||
if (d <= threshold && d < bestDistance) {
|
||||
bestDistance = d;
|
||||
recommended = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return recommended;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
import * as yargs from './yargs/yargs';
|
||||
export default yargs;
|
|
@ -1,21 +0,0 @@
|
|||
const yargs = () => yargs;
|
||||
|
||||
yargs.argv = {
|
||||
config: undefined
|
||||
} as { config: string | undefined };
|
||||
|
||||
yargs.command = () => yargs;
|
||||
|
||||
yargs.demandCommand = () => yargs;
|
||||
|
||||
yargs.help = () => yargs;
|
||||
|
||||
yargs.getCommandInstance = () => ({
|
||||
getCommands: () => []
|
||||
});
|
||||
|
||||
yargs.getContext = () => ({
|
||||
commands: []
|
||||
});
|
||||
|
||||
export = yargs;
|
|
@ -1,14 +1,8 @@
|
|||
import mockfs from 'mock-fs';
|
||||
import path from 'path';
|
||||
import yargsMock from './__mocks__/yargs/yargs';
|
||||
import {
|
||||
_isFileNameLike,
|
||||
_tryResolve,
|
||||
resetResolvePaths,
|
||||
resolveCwd,
|
||||
addResolvePath,
|
||||
resolve
|
||||
} from '../resolve';
|
||||
import { _isFileNameLike, _tryResolve, resetResolvePaths, resolveCwd, addResolvePath, resolve } from '../resolve';
|
||||
|
||||
import * as option from '../option';
|
||||
|
||||
describe('_isFileNameLike', () => {
|
||||
it('returns false for empty input', () => {
|
||||
|
@ -83,6 +77,10 @@ describe('_tryResolve', () => {
|
|||
});
|
||||
|
||||
describe('resolveCwd', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: undefined } as any));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockfs.restore();
|
||||
resetResolvePaths();
|
||||
|
@ -117,9 +115,10 @@ describe('resolveCwd', () => {
|
|||
});
|
||||
|
||||
describe('resolve', () => {
|
||||
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: undefined } as any));
|
||||
|
||||
afterEach(() => {
|
||||
mockfs.restore();
|
||||
yargsMock.argv.config = undefined;
|
||||
resetResolvePaths();
|
||||
});
|
||||
|
||||
|
@ -145,7 +144,9 @@ describe('resolve', () => {
|
|||
mockfs({
|
||||
a: { 'b.txt': '' }
|
||||
});
|
||||
yargsMock.argv.config = 'a/just-task.js';
|
||||
|
||||
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: 'a/just-task.js' } as any));
|
||||
|
||||
expect(resolve('b.txt')).toContain(path.join('a', 'b.txt'));
|
||||
});
|
||||
|
||||
|
@ -166,7 +167,9 @@ describe('resolve', () => {
|
|||
d: { 'b.txt': '' }, // wrong
|
||||
'b.txt': '' // wrong
|
||||
});
|
||||
yargsMock.argv.config = 'a/just-task.js';
|
||||
|
||||
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: 'a/just-task.js' } as any));
|
||||
|
||||
addResolvePath('c');
|
||||
expect(resolve('b.txt', 'd')).toContain(path.join('d', 'b.txt'));
|
||||
});
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
import { task } from '../task';
|
||||
import { parallel, undertaker } from '../undertaker';
|
||||
import { JustTaskRegistry } from '../JustTaskRegistry';
|
||||
import UndertakerRegistry from 'undertaker-registry';
|
||||
|
||||
import { logger } from '../logger';
|
||||
import yargsMock from './__mocks__/yargs';
|
||||
import path from 'path';
|
||||
|
||||
import * as option from '../option';
|
||||
|
||||
describe('task', () => {
|
||||
beforeAll(() => {
|
||||
yargsMock.argv.config = path.resolve(__dirname, '__mocks__/just-task.js');
|
||||
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: path.resolve(__dirname, '__mocks__/just-task.js') } as any));
|
||||
jest.spyOn(logger, 'info').mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
undertaker.registry(new JustTaskRegistry());
|
||||
undertaker.registry(new UndertakerRegistry());
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
yargsMock.argv.config = undefined;
|
||||
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: 'a/just-task.js' } as any));
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { undertaker } from './undertaker';
|
||||
import { JustTaskRegistry } from './JustTaskRegistry';
|
||||
import yargs from 'yargs';
|
||||
import { option, parseCommand } from './option';
|
||||
import { logger } from 'just-task-logger';
|
||||
import { TaskFunction } from './interfaces';
|
||||
import { readConfig } from './config';
|
||||
|
||||
const originalEmitWarning = process.emitWarning;
|
||||
|
||||
|
@ -17,15 +19,33 @@ const originalEmitWarning = process.emitWarning;
|
|||
return originalEmitWarning.apply(this, arguments);
|
||||
};
|
||||
|
||||
yargs
|
||||
.option({ config: { describe: 'path to a just-task.js file (includes the file name)' } })
|
||||
.usage('$0 <cmd> [options]')
|
||||
.updateStrings({
|
||||
'Commands:': 'Tasks:\n'
|
||||
});
|
||||
function showHelp() {
|
||||
const tasks = undertaker.registry().tasks();
|
||||
|
||||
const registry = new JustTaskRegistry();
|
||||
console.log('All the tasks that are available to just:');
|
||||
|
||||
undertaker.registry(registry);
|
||||
for (const [name, wrappedTask] of Object.entries(tasks)) {
|
||||
const unwrapped = (wrappedTask as any).unwrap ? (wrappedTask as any).unwrap() : (wrappedTask as TaskFunction);
|
||||
const description = (unwrapped as TaskFunction).description;
|
||||
console.log(` ${name}${description ? `: ${description}` : ''}`);
|
||||
}
|
||||
}
|
||||
|
||||
yargs.parse();
|
||||
// Define a built-in option of "config" so users can specify which path to choose for configurations
|
||||
option('config', { describe: 'path to a just configuration file (includes the file name, e.g. /path/to/just.config.ts)' });
|
||||
|
||||
readConfig();
|
||||
|
||||
const registry = undertaker.registry();
|
||||
|
||||
const command = parseCommand();
|
||||
|
||||
if (command) {
|
||||
if (registry.get(command)) {
|
||||
undertaker.series(registry.get(command))(() => {});
|
||||
} else {
|
||||
logger.error(`Command not defined: ${command}`);
|
||||
}
|
||||
} else {
|
||||
showHelp();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { argv } from './option';
|
||||
import { resolve } from './resolve';
|
||||
import { mark, logger } from 'just-task-logger';
|
||||
import { enableTypeScript } from './enableTypeScript';
|
||||
|
||||
export function readConfig() {
|
||||
// uses a separate instance of yargs to first parse the config (without the --help in the way) so we can parse the configFile first regardless
|
||||
let configFile: string | null = null;
|
||||
for (const entry of [argv().config, './just.config.js', './just-task.js', './just.config.ts']) {
|
||||
configFile = resolve(entry);
|
||||
if (configFile) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mark('registry:configModule');
|
||||
|
||||
if (configFile && fs.existsSync(configFile)) {
|
||||
const ext = path.extname(configFile);
|
||||
if (ext === '.ts' || ext === '.tsx') {
|
||||
// TODO: add option to do typechecking as well
|
||||
enableTypeScript({ transpileOnly: true });
|
||||
}
|
||||
|
||||
try {
|
||||
const configModule = require(configFile);
|
||||
if (typeof configModule === 'function') {
|
||||
configModule();
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(`Invalid configuration file: ${configFile}`);
|
||||
logger.error(`Error: ${e.stack || e.message || e}`);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
logger.error(
|
||||
`Cannot find config file "${configFile}".`,
|
||||
`Please create a file called "just.config.js" in the root of the project next to "package.json".`
|
||||
);
|
||||
}
|
||||
|
||||
logger.perf('registry:configModule');
|
||||
}
|
|
@ -13,4 +13,5 @@ export interface TaskContext {
|
|||
export interface TaskFunction extends Undertaker.TaskFunctionParams {
|
||||
(this: TaskContext, done: (error?: any) => void): void | Duplex | NodeJS.Process | Promise<never> | any;
|
||||
cached?: () => void;
|
||||
description?: string;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,90 @@
|
|||
import yargs from 'yargs';
|
||||
import parser, { Options, Arguments } from 'yargs-parser';
|
||||
|
||||
export function option(key: string, options: yargs.Options = {}): yargs.Argv {
|
||||
return yargs.option.apply(yargs, [key, options]);
|
||||
export interface OptionConfig {
|
||||
/** Aliases for the argument, can be a string or array */
|
||||
alias?: string | string[];
|
||||
|
||||
/** Argument should be an array */
|
||||
array?: boolean;
|
||||
|
||||
/** Argument should be parsed as booleans: `{ boolean: ['x', 'y'] }`. */
|
||||
boolean?: boolean;
|
||||
|
||||
/**
|
||||
* Provide a custom synchronous function that returns a coerced value from the argument provided (or throws an error), e.g.
|
||||
* `{ coerce: function (arg) { return modifiedArg } }`.
|
||||
*/
|
||||
coerce?: (arg: any) => any;
|
||||
|
||||
/** Indicate a key that should be used as a counter, e.g., `-vvv = {v: 3}`. */
|
||||
count?: boolean;
|
||||
|
||||
/** Provide default values for keys: `{ default: { x: 33, y: 'hello world!' } }`. */
|
||||
default?: { [key: string]: any };
|
||||
|
||||
/** Specify that a key requires n arguments: `{ narg: {x: 2} }`. */
|
||||
narg?: number;
|
||||
|
||||
/** `path.normalize()` will be applied to values set to this key. */
|
||||
normalize?: boolean;
|
||||
|
||||
/** Keys should be treated as strings (even if they resemble a number `-x 33`). */
|
||||
string?: boolean;
|
||||
|
||||
/** Keys should be treated as numbers. */
|
||||
number?: boolean;
|
||||
|
||||
/** A description of the option */
|
||||
describe?: string;
|
||||
}
|
||||
|
||||
export function argv(): yargs.Arguments {
|
||||
return yargs.argv;
|
||||
let argOptions: Options = {};
|
||||
const descriptions: { [key: string]: string } = {};
|
||||
const processArgs = process.argv.slice(2);
|
||||
|
||||
export function option(key: string, options: OptionConfig = {}) {
|
||||
const booleanArgs = ['array', 'boolean', 'count', 'normalize', 'string', 'number'] as const;
|
||||
const assignArgs = ['alias', 'coerce', 'default'] as const;
|
||||
|
||||
for (const argName of booleanArgs) {
|
||||
if (options[argName]) {
|
||||
if (!argOptions[argName]) {
|
||||
argOptions[argName] = [];
|
||||
}
|
||||
|
||||
const argOpts = argOptions[argName]! as string[];
|
||||
|
||||
if (argOpts.indexOf(key) === -1) {
|
||||
argOpts.push(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const argName of assignArgs) {
|
||||
if (options[argName]) {
|
||||
if (!argOptions[argName]) {
|
||||
argOptions[argName] = {};
|
||||
}
|
||||
|
||||
argOptions[argName]![key] = options[argName];
|
||||
}
|
||||
}
|
||||
|
||||
if (options.describe) {
|
||||
descriptions[key] = options.describe;
|
||||
}
|
||||
}
|
||||
|
||||
export function argv(): Arguments {
|
||||
return parser(processArgs, argOptions);
|
||||
}
|
||||
|
||||
export function parseCommand(): string | null {
|
||||
const positionals = argv()._;
|
||||
|
||||
if (positionals.length > 0) {
|
||||
return positionals[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
import { sync as resolveSync } from 'resolve';
|
||||
import path from 'path';
|
||||
|
||||
// It is important to keep this line like this:
|
||||
// 1. it cannot be an import because TS will try to do type checks which isn't available in @types/yargs
|
||||
// 2. this breaks a require.cache, which is needed because we need a new instance of yargs to check the config
|
||||
// - this is because of the timing of when tasks are defined vs when this resolve is called the first time
|
||||
// to figure out config path)
|
||||
const yargsFn = require('yargs/yargs');
|
||||
import { argv } from './option';
|
||||
|
||||
let resolvePaths: string[] = [__dirname];
|
||||
|
||||
|
@ -62,7 +56,8 @@ export function resolve(moduleName: string, cwd?: string): string | null {
|
|||
if (!cwd) {
|
||||
cwd = process.cwd();
|
||||
}
|
||||
const configArg = yargsFn(process.argv.slice(1).filter(a => a !== '--help')).argv.config;
|
||||
|
||||
const configArg = argv().config;
|
||||
const configFilePath = configArg ? path.resolve(path.dirname(configArg)) : undefined;
|
||||
|
||||
const allResolvePaths = [cwd, ...(configFilePath ? [configFilePath] : []), ...resolvePaths];
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import yargs from 'yargs';
|
||||
import { undertaker } from './undertaker';
|
||||
import { wrapTask } from './wrapTask';
|
||||
import { TaskFunction } from './interfaces';
|
||||
import { logger } from 'just-task-logger';
|
||||
import { registerCachedTask, isCached, saveCache } from './cache';
|
||||
import { registerCachedTask } from './cache';
|
||||
|
||||
export function task(firstParam: string | TaskFunction, secondParam?: string | TaskFunction, thirdParam?: TaskFunction): TaskFunction {
|
||||
const argCount = arguments.length;
|
||||
|
@ -19,7 +17,6 @@ export function task(firstParam: string | TaskFunction, secondParam?: string | T
|
|||
};
|
||||
|
||||
undertaker.task(firstParam, wrapped);
|
||||
yargs.command(getCommandModule(firstParam, ''));
|
||||
|
||||
return wrapped;
|
||||
} else if (argCount === 2 && isString(firstParam) && isTaskFunction(secondParam)) {
|
||||
|
@ -31,7 +28,6 @@ export function task(firstParam: string | TaskFunction, secondParam?: string | T
|
|||
};
|
||||
|
||||
undertaker.task(firstParam, wrapped);
|
||||
yargs.command(getCommandModule(firstParam, ''));
|
||||
|
||||
return wrapped;
|
||||
} else if (argCount === 3 && isString(firstParam) && isString(secondParam) && isTaskFunction(thirdParam)) {
|
||||
|
@ -41,8 +37,9 @@ export function task(firstParam: string | TaskFunction, secondParam?: string | T
|
|||
registerCachedTask(firstParam);
|
||||
};
|
||||
|
||||
wrapped.description = secondParam;
|
||||
|
||||
undertaker.task(firstParam, wrapped);
|
||||
yargs.command(getCommandModule(firstParam, secondParam));
|
||||
|
||||
return wrapped;
|
||||
} else {
|
||||
|
@ -57,21 +54,3 @@ function isString(param: string | TaskFunction | undefined): param is string {
|
|||
function isTaskFunction(param: string | TaskFunction | undefined): param is TaskFunction {
|
||||
return typeof param === 'function';
|
||||
}
|
||||
|
||||
function getCommandModule(taskName: string, describe?: string): yargs.CommandModule {
|
||||
return {
|
||||
command: taskName,
|
||||
describe,
|
||||
...(taskName === 'default' ? { aliases: ['*'] } : {}),
|
||||
handler(_argvParam: any) {
|
||||
if (isCached(taskName)) {
|
||||
logger.info(`Skipped ${taskName} since it was cached`);
|
||||
return;
|
||||
}
|
||||
|
||||
return undertaker.parallel(taskName)(() => {
|
||||
saveCache(taskName);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src"]
|
||||
"include": ["src", "types"]
|
||||
}
|
||||
|
|
17
yarn.lock
17
yarn.lock
|
@ -2328,6 +2328,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0"
|
||||
integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw==
|
||||
|
||||
"@types/yargs-parser@^15.0.0":
|
||||
version "15.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
|
||||
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
|
||||
|
||||
"@types/yargs@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.1.tgz#c5ce4ad64499010ae4dc2acd9b14d49749a44233"
|
||||
|
@ -3248,7 +3253,7 @@ babylon@^6.17.4:
|
|||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
|
||||
integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
|
||||
|
||||
bach@^1.0.0:
|
||||
bach@^1.0.0, bach@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880"
|
||||
integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=
|
||||
|
@ -13364,7 +13369,7 @@ undertaker-registry@^1.0.0, undertaker-registry@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50"
|
||||
integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=
|
||||
|
||||
undertaker@^1.2.0:
|
||||
undertaker@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.1.tgz#701662ff8ce358715324dfd492a4f036055dfe4b"
|
||||
integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==
|
||||
|
@ -14045,6 +14050,14 @@ yargs-parser@^13.1.0, yargs-parser@^13.1.1:
|
|||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs-parser@^18.1.2:
|
||||
version "18.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1"
|
||||
integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==
|
||||
dependencies:
|
||||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs-parser@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
|
||||
|
|
Загрузка…
Ссылка в новой задаче