diff --git a/src/bin/main.ts b/src/bin/main.ts index 16a7b7f..5e91f2a 100644 --- a/src/bin/main.ts +++ b/src/bin/main.ts @@ -39,8 +39,8 @@ export default async function main( -f, --file Configuration file -d, --dir Project directory -e, --env Environment variables - --prefix Print task routes --level Logging level + --prefix Prefix task output with its route -h, --help Show help -v, --version Show version number @@ -59,8 +59,8 @@ export default async function main( '--file': String, '--dir': String, '--env': [String] as [StringConstructor], - '--prefix': Boolean, '--level': String, + '--prefix': Boolean, '--help': Boolean, '--version': Boolean }; @@ -137,7 +137,7 @@ export default async function main( names.join(' ') ), print(), - combine(record, names) + combine(record, { include: names, defaults: true }) ), context.bind(null, { args }), withContext diff --git a/src/bin/watch.ts b/src/bin/watch.ts index 7638dae..3ad7a20 100644 --- a/src/bin/watch.ts +++ b/src/bin/watch.ts @@ -113,7 +113,7 @@ export default async function bin( names.join(' ') ); }), - combine(params.record, names) + combine(params.record, { include: names, defaults: true }) ) ) ) diff --git a/src/helpers/parse.ts b/src/helpers/parse.ts index 1eb98ed..be9fe0f 100644 --- a/src/helpers/parse.ts +++ b/src/helpers/parse.ts @@ -11,6 +11,7 @@ interface Item { } interface ParseToArrayOptions { + roots: boolean; defaults: boolean; } @@ -24,7 +25,10 @@ export function parseToRecord( record: Task.Record ): Members { const { include, exclude } = options; - const arr = parseToArray({ defaults: options.defaults }, record); + const arr = parseToArray( + { roots: options.roots, defaults: options.defaults }, + record + ); const members: Members = {}; for (const item of arr) { @@ -50,7 +54,7 @@ export function parseToArray( ): Item[] { const names: string[] = []; - return parseHelper(record) + return parseHelper(record, options.roots) .map(([route, task]) => { const name = stringifyRoute(route); @@ -73,7 +77,10 @@ export function parseToArray( }); } -function parseHelper(record: Task.Record): Array<[string[], Task]> { +function parseHelper( + record: Task.Record, + roots: boolean +): Array<[string[], Task]> { const arr: Array<[string[], Task]> = []; for (const [name, tasks] of Object.entries(record)) { @@ -83,7 +90,7 @@ function parseHelper(record: Task.Record): Array<[string[], Task]> { const all: Task[] = []; const defaults: Task[] = []; const every: Array<[string[], Task]> = []; - for (const [route, task] of parseHelper(tasks)) { + for (const [route, task] of parseHelper(tasks, roots)) { every.push([[name, ...route], task]); if (route.length <= 1) { route[0] === constants.record.default @@ -92,10 +99,12 @@ function parseHelper(record: Task.Record): Array<[string[], Task]> { } } - if (defaults.length) { - arr.push([[name], series(...defaults)]); - } else if (all.length) { - arr.push([[name], series(...all)]); + if (roots) { + if (defaults.length) { + arr.push([[name], series(...defaults)]); + } else if (all.length) { + arr.push([[name], series(...all)]); + } } if (every.length) arr.push(...every); diff --git a/src/tasks/aggregate/combine.ts b/src/tasks/aggregate/combine.ts index 821e7b1..7b93ddf 100644 --- a/src/tasks/aggregate/combine.ts +++ b/src/tasks/aggregate/combine.ts @@ -4,40 +4,65 @@ import { run } from '../../utils/run'; import { recreate } from '../../utils/recreate'; import { context } from '../transform/context'; import { series } from './series'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; +export interface CombineOptions { + /** + * An array of strings indicating the name of the tasks + * to include for a task record. + * A task name is the stringification of its route in the record, + * joined by with a ':' character for each depth level. + * Targetting a level with inner tasks will run all of them. + */ + include?: string[] | null; + /** + * An array of strings indicating the name of the tasks + * to exclude for a task record. + * A task name is the stringification of its route in the record, + * joined by with a ':' character for each depth level. + */ + exclude?: string[] | null; + /** + * Whether to consider default tasks as separate from their root. + */ + defaults?: boolean; +} + /** * Takes a task nested record `tasks` and runs a number - * of them in series as selected by their `names`. - * A task name will be the stringification of its route - * in the record, with a ':' character for each level deep. - * Targetting a level with inner tasks will run all of them. + * of them in series as selected by the inclusion or exclusion options. * @returns Task */ export function combine( tasks: Task.Record, - names: string | string[] + options?: CombineOptions ): Task.Async { - const keys = Array.isArray(names) ? names : [names]; - return async (ctx: Context): Promise => { + const opts: Required = shallow( + { include: null, exclude: null, defaults: false }, + options || undefined + ); + return into( tasks, recreate.bind(null, (task, route) => { return context( - (ctx) => ({ - ...ctx, - route: ctx.route.concat(route) - }), + (ctx) => ({ ...ctx, route: ctx.route.concat(route) }), task ); }), parseToRecord.bind(null, { - include: keys, - exclude: null, - defaults: true + include: opts.include, + exclude: opts.exclude, + defaults: opts.defaults, + roots: Array.isArray(opts.include) }), - (record) => keys.map((key) => record[key]), + (record) => { + return Array.isArray(opts.include) + ? opts.include.map((name) => record[name]) + : Object.values(record); + }, (arr) => series(...arr), (task) => run(task, ctx) ); diff --git a/src/tasks/reflection/lift.ts b/src/tasks/reflection/lift.ts index 0ffe5ac..8a3cba7 100644 --- a/src/tasks/reflection/lift.ts +++ b/src/tasks/reflection/lift.ts @@ -70,6 +70,7 @@ export function lift( parseToRecord.bind(null, { include: null, exclude: null, + roots: true, defaults: opts.defaults }), (record) => Object.keys(record), diff --git a/src/tasks/reflection/list.ts b/src/tasks/reflection/list.ts index 7a97b95..539441a 100644 --- a/src/tasks/reflection/list.ts +++ b/src/tasks/reflection/list.ts @@ -37,7 +37,10 @@ export function list( ); const source = await getTaskRecord(tasks); - const items = parseToArray({ defaults: opts.defaults }, source); + const items = parseToArray( + { roots: true, defaults: opts.defaults }, + source + ); const maxRouteLength = items.reduce( (acc, item) => (acc > item.route.length ? acc : item.route.length), 0