From df664ff35c4b42a628c347040eabb80a2c5f224e Mon Sep 17 00:00:00 2001 From: Kenneth Chau Date: Fri, 10 Apr 2020 13:31:08 -0700 Subject: [PATCH] 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 --- ...just-2020-04-09-21-31-52-yargs-parser.json | 8 ++ ...ipts-2020-04-09-21-31-52-yargs-parser.json | 8 ++ ...task-2020-04-09-21-31-52-yargs-parser.json | 8 ++ .../create-just/src/commands/initCommand.ts | 2 +- packages/just-scripts/src/tasks/jestTask.ts | 10 +- packages/just-task/package.json | 9 +- packages/just-task/src/JustTaskRegistry.ts | 115 ------------------ .../src/__tests__/__mocks__/yargs.ts | 2 - .../src/__tests__/__mocks__/yargs/yargs.ts | 21 ---- .../just-task/src/__tests__/resolve.spec.ts | 27 ++-- packages/just-task/src/__tests__/task.spec.ts | 12 +- packages/just-task/src/cli.ts | 42 +++++-- packages/just-task/src/config.ts | 46 +++++++ packages/just-task/src/interfaces.ts | 1 + packages/just-task/src/option.ts | 91 +++++++++++++- packages/just-task/src/resolve.ts | 11 +- packages/just-task/src/task.ts | 27 +--- packages/just-task/tsconfig.json | 2 +- yarn.lock | 17 ++- 19 files changed, 247 insertions(+), 212 deletions(-) create mode 100644 change/create-just-2020-04-09-21-31-52-yargs-parser.json create mode 100644 change/just-scripts-2020-04-09-21-31-52-yargs-parser.json create mode 100644 change/just-task-2020-04-09-21-31-52-yargs-parser.json delete mode 100644 packages/just-task/src/JustTaskRegistry.ts delete mode 100644 packages/just-task/src/__tests__/__mocks__/yargs.ts delete mode 100644 packages/just-task/src/__tests__/__mocks__/yargs/yargs.ts create mode 100644 packages/just-task/src/config.ts diff --git a/change/create-just-2020-04-09-21-31-52-yargs-parser.json b/change/create-just-2020-04-09-21-31-52-yargs-parser.json new file mode 100644 index 00000000..998d9489 --- /dev/null +++ b/change/create-just-2020-04-09-21-31-52-yargs-parser.json @@ -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" +} \ No newline at end of file diff --git a/change/just-scripts-2020-04-09-21-31-52-yargs-parser.json b/change/just-scripts-2020-04-09-21-31-52-yargs-parser.json new file mode 100644 index 00000000..889cfc76 --- /dev/null +++ b/change/just-scripts-2020-04-09-21-31-52-yargs-parser.json @@ -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" +} \ No newline at end of file diff --git a/change/just-task-2020-04-09-21-31-52-yargs-parser.json b/change/just-task-2020-04-09-21-31-52-yargs-parser.json new file mode 100644 index 00000000..2f4c8688 --- /dev/null +++ b/change/just-task-2020-04-09-21-31-52-yargs-parser.json @@ -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" +} \ No newline at end of file diff --git a/packages/create-just/src/commands/initCommand.ts b/packages/create-just/src/commands/initCommand.ts index 6078a3cf..9b2b12a7 100644 --- a/packages/create-just/src/commands/initCommand.ts +++ b/packages/create-just/src/commands/initCommand.ts @@ -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({ diff --git a/packages/just-scripts/src/tasks/jestTask.ts b/packages/just-scripts/src/tasks/jestTask.ts index 4397c3ea..b8a4a3aa 100644 --- a/packages/just-scripts/src/tasks/jestTask.ts +++ b/packages/just-scripts/src/tasks/jestTask.ts @@ -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; diff --git a/packages/just-task/package.json b/packages/just-task/package.json index 606c1cc8..7c432312 100644 --- a/packages/just-task/package.json +++ b/packages/just-task/package.json @@ -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", diff --git a/packages/just-task/src/JustTaskRegistry.ts b/packages/just-task/src/JustTaskRegistry.ts deleted file mode 100644 index 53c74410..00000000 --- a/packages/just-task/src/JustTaskRegistry.ts +++ /dev/null @@ -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(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; -} diff --git a/packages/just-task/src/__tests__/__mocks__/yargs.ts b/packages/just-task/src/__tests__/__mocks__/yargs.ts deleted file mode 100644 index ef5b4397..00000000 --- a/packages/just-task/src/__tests__/__mocks__/yargs.ts +++ /dev/null @@ -1,2 +0,0 @@ -import * as yargs from './yargs/yargs'; -export default yargs; diff --git a/packages/just-task/src/__tests__/__mocks__/yargs/yargs.ts b/packages/just-task/src/__tests__/__mocks__/yargs/yargs.ts deleted file mode 100644 index 70a18e55..00000000 --- a/packages/just-task/src/__tests__/__mocks__/yargs/yargs.ts +++ /dev/null @@ -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; diff --git a/packages/just-task/src/__tests__/resolve.spec.ts b/packages/just-task/src/__tests__/resolve.spec.ts index d5033e00..92965d8b 100644 --- a/packages/just-task/src/__tests__/resolve.spec.ts +++ b/packages/just-task/src/__tests__/resolve.spec.ts @@ -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')); }); diff --git a/packages/just-task/src/__tests__/task.spec.ts b/packages/just-task/src/__tests__/task.spec.ts index 097a3251..f4dcfca2 100644 --- a/packages/just-task/src/__tests__/task.spec.ts +++ b/packages/just-task/src/__tests__/task.spec.ts @@ -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(); }); diff --git a/packages/just-task/src/cli.ts b/packages/just-task/src/cli.ts index 2c7adafa..55194b03 100644 --- a/packages/just-task/src/cli.ts +++ b/packages/just-task/src/cli.ts @@ -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 [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}` : ''}`); + } +} + +// 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(); -yargs.parse(); +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(); +} diff --git a/packages/just-task/src/config.ts b/packages/just-task/src/config.ts new file mode 100644 index 00000000..fd484b56 --- /dev/null +++ b/packages/just-task/src/config.ts @@ -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'); +} diff --git a/packages/just-task/src/interfaces.ts b/packages/just-task/src/interfaces.ts index 0409c941..030489ae 100644 --- a/packages/just-task/src/interfaces.ts +++ b/packages/just-task/src/interfaces.ts @@ -13,4 +13,5 @@ export interface TaskContext { export interface TaskFunction extends Undertaker.TaskFunctionParams { (this: TaskContext, done: (error?: any) => void): void | Duplex | NodeJS.Process | Promise | any; cached?: () => void; + description?: string; } diff --git a/packages/just-task/src/option.ts b/packages/just-task/src/option.ts index d14366fd..d1b33975 100644 --- a/packages/just-task/src/option.ts +++ b/packages/just-task/src/option.ts @@ -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; } diff --git a/packages/just-task/src/resolve.ts b/packages/just-task/src/resolve.ts index f659fde5..68ded5c4 100644 --- a/packages/just-task/src/resolve.ts +++ b/packages/just-task/src/resolve.ts @@ -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]; diff --git a/packages/just-task/src/task.ts b/packages/just-task/src/task.ts index 850d0f35..b948188b 100644 --- a/packages/just-task/src/task.ts +++ b/packages/just-task/src/task.ts @@ -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); - }); - } - }; -} diff --git a/packages/just-task/tsconfig.json b/packages/just-task/tsconfig.json index 1b551f4e..2602673a 100644 --- a/packages/just-task/tsconfig.json +++ b/packages/just-task/tsconfig.json @@ -3,5 +3,5 @@ "compilerOptions": { "outDir": "lib" }, - "include": ["src"] + "include": ["src", "types"] } diff --git a/yarn.lock b/yarn.lock index b55a5475..24b6d848 100644 --- a/yarn.lock +++ b/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"