Skip to content

Commit

Permalink
feat: treat 'default' keys in Task.Record as the task to be run for i…
Browse files Browse the repository at this point in the history
…ts top level
  • Loading branch information
rafamel committed Apr 3, 2021
1 parent 2c939b0 commit 90c1527
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 33 deletions.
9 changes: 6 additions & 3 deletions src/bin/lift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ export default async function bin(
$ ${opts.bin} :lift [options]
Options:
--purge Purge all non-${opts.bin} scripts
--mode <value> Lift mode of operation (default, confirm, dry, audit)
-h, --help Show help
--purge Purge all non-${opts.bin} scripts
--defaults Lift default tasks and subtasks by their own
--mode <value> Lift mode of operation (default, confirm, dry, audit)
-h, --help Show help
`;

const types = {
'--purge': Boolean,
'--defaults': Boolean,
'--mode': String,
'--help': Boolean
};
Expand Down Expand Up @@ -65,6 +67,7 @@ export default async function bin(
print(),
lift(params.record, {
purge: cmd['--purge'],
defaults: cmd['--defaults'],
mode: cmd['--mode'] as any,
bin: opts.bin
})
Expand Down
60 changes: 60 additions & 0 deletions src/bin/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Task } from '../definitions';
import { list, series, raises, print, log } from '../tasks';
import { stripIndent as indent } from 'common-tags';
import { flags, safePairs } from 'cli-belt';
import chalk from 'chalk';
import arg from 'arg';

interface Params {
argv: string[];
record: Task.Record;
}

interface Options {
bin: string;
}

export default async function bin(
params: Params,
opts: Options
): Promise<Task> {
const help = indent`
${chalk.bold(`Lists ${opts.bin} tasks`)}
Usage:
$ ${opts.bin} :list [options]
Options:
--defaults List default tasks and subtasks by their own
-h, --help Show help
`;

const types = {
'--defaults': Boolean,
'--help': Boolean
};

const { options, aliases } = flags(help);
safePairs(types, options, { fail: true, bidirectional: true });
Object.assign(types, aliases);
const cmd = arg(types, {
argv: params.argv,
permissive: false,
stopAtPositional: true
});

if (cmd['--help']) return print(help + '\n');
if (cmd._.length) {
return series(
print(help + '\n'),
raises(Error(`Unknown subcommand: ${cmd._[0]}`))
);
}

return series(
log('debug', 'Working directory:', process.cwd()),
log('info', chalk.bold(opts.bin), chalk.bold.blue(':list')),
print(),
list(params.record, { defaults: cmd['--defaults'], bin: opts.bin })
);
}
21 changes: 6 additions & 15 deletions src/bin/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { LogLevel, Task, PrefixPolicy } from '../definitions';
import { print, log, list, raises, series, context, combine } from '../tasks';
import { print, log, raises, series, context, combine } from '../tasks';
import { fetch } from '../utils';
import watch from './watch';
import list from './list';
import lift from './lift';
import { Members } from 'type-core';
import { flags, safePairs, splitBy } from 'cli-belt';
Expand Down Expand Up @@ -153,20 +154,10 @@ export default async function main(
);
}
case ':list': {
return cmd._.length
? series(
print(help + '\n'),
raises(Error(`Unknown subcommand: ${cmd._[0]}`))
)
: into(
series(
log('debug', 'Working directory:', process.cwd()),
log('info', chalk.bold(opts.bin), chalk.bold.blue(':list')),
print(),
list(record, { bin: opts.bin })
),
withContext
);
return into(
await list({ argv: cmd._, record: record }, { bin: opts.bin }),
withContext
);
}
case ':lift': {
return into(
Expand Down
3 changes: 2 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export const constants = {
bin: 'kpo',
file: 'kpo.tasks.js',
description: pkg.description || '',
version: pkg.version || 'Unknown'
version: pkg.version || 'Unknown',
record: { default: 'default' }
};
42 changes: 33 additions & 9 deletions src/helpers/parse.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import { Task } from '../definitions';
import { constants } from '../constants';
import { series } from '../tasks/aggregate/series';
import { stringifyRoute } from './stringify-route';
import { Members } from 'type-core';
import { Members, TypeGuard } from 'type-core';

interface Item {
name: string;
route: string[];
task: Task;
}

interface Options {
interface ParseToArrayOptions {
defaults: boolean;
}

interface ParseToRecordOptions extends ParseToArrayOptions {
include: string[] | null;
exclude: string[] | null;
}

export function parseToRecord(
options: Options,
options: ParseToRecordOptions,
record: Task.Record
): Members<Task> {
const { include, exclude } = options;
const arr = parseToArray(record);
const arr = parseToArray({ defaults: options.defaults }, record);

const members: Members<Task> = {};
for (const item of arr) {
Expand All @@ -39,7 +44,10 @@ export function parseToRecord(
return members;
}

export function parseToArray(record: Task.Record): Item[] {
export function parseToArray(
options: ParseToArrayOptions,
record: Task.Record
): Item[] {
const names: string[] = [];

return parseHelper(record)
Expand All @@ -56,24 +64,40 @@ export function parseToArray(record: Task.Record): Item[] {
names.push(name);
return { name, route, task };
})
.filter((item): item is Item => Boolean(item.task));
.filter((item) => {
return options.defaults
? Boolean(item.task)
: Boolean(
item.route.indexOf(constants.record.default) === -1 && item.task
);
});
}

function parseHelper(record: Task.Record): Array<[string[], Task]> {
const arr: Array<[string[], Task]> = [];

for (const [name, tasks] of Object.entries(record)) {
if (typeof tasks === 'function') {
if (TypeGuard.isFunction(tasks)) {
arr.push([[name], tasks]);
} else {
const all: Task[] = [];
const defaults: Task[] = [];
const every: Array<[string[], Task]> = [];
for (const [route, task] of parseHelper(tasks)) {
every.push([[name, ...route], task]);
if (route.length <= 1) all.push(task);
if (route.length <= 1) {
route[0] === constants.record.default
? defaults.push(task)
: all.push(task);
}
}

if (defaults.length) {
arr.push([[name], series(...defaults)]);
} else if (all.length) {
arr.push([[name], series(...all)]);
}

if (all.length) arr.push([[name], series(...all)]);
if (every.length) arr.push(...every);
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/tasks/aggregate/combine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ export function combine(
task
);
}),
parseToRecord.bind(null, { include: keys, exclude: null }),
parseToRecord.bind(null, {
include: keys,
exclude: null,
defaults: true
}),
(record) => keys.map((key) => record[key]),
(arr) => series(...arr),
(task) => run(task, ctx)
Expand Down
12 changes: 10 additions & 2 deletions src/tasks/reflection/lift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export interface LiftOptions {
* * `'audit'`: prints the expected changes and fails if there are pending changes.
*/
mode?: 'default' | 'confirm' | 'dry' | 'audit';
/**
* Lift default tasks and subtasks by their own
*/
defaults?: boolean;
/**
* Name of kpo's executable
*/
Expand All @@ -47,7 +51,7 @@ export function lift(
): Task.Async {
return async (ctx: Context): Promise<void> => {
const opts = shallow(
{ purge: false, mode: 'default', bin: constants.bin },
{ purge: false, mode: 'default', defaults: false, bin: constants.bin },
options || undefined
);

Expand All @@ -63,7 +67,11 @@ export function lift(

const taskScripts = into(
source,
parseToRecord.bind(null, { include: null, exclude: null }),
parseToRecord.bind(null, {
include: null,
exclude: null,
defaults: opts.defaults
}),
(record) => Object.keys(record),
(keys) => {
return keys.reduce(
Expand Down
11 changes: 9 additions & 2 deletions src/tasks/reflection/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import table from 'as-table';
import chalk from 'chalk';

export interface ListOptions {
/**
* List default tasks and subtasks by their own
*/
defaults?: boolean;
/**
* Name of kpo's executable.
*/
Expand All @@ -27,10 +31,13 @@ export function list(
map?: (name: string, route: string[]) => string[]
): Task.Async {
return async (ctx: Context): Promise<void> => {
const opts = shallow({ bin: constants.bin }, options || undefined);
const opts = shallow(
{ defaults: false, bin: constants.bin },
options || undefined
);

const source = await getTaskRecord(tasks);
const items = parseToArray(source);
const items = parseToArray({ defaults: opts.defaults }, source);
const maxRouteLength = items.reduce(
(acc, item) => (acc > item.route.length ? acc : item.route.length),
0
Expand Down

0 comments on commit 90c1527

Please sign in to comment.