Skip to content

Commit

Permalink
feat(public/exec): adds stream
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Apr 30, 2019
1 parent ad5abec commit 76da0d0
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export const FILE_EXT = ['.js', '.json', '.yml', '.yaml'];
export const DEFAULT_LOG_LEVEL = 'info';
// Default stdio for spawned commands
export const DEFAULT_STDIO = 'inherit';
// Node binary path
export const NODE_PATH = process.execPath;
// Kpo bin path
export const KPO_PATH = require.resolve('./bin/kpo');
// Concurrently path
export const CONCURRENTLY_PATH = require.resolve(
'concurrently/bin/concurrently'
Expand Down
3 changes: 2 additions & 1 deletion src/public/exec/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as series } from './series';
export { default as parallel } from './parallel';
export { default as series } from './series';
export { default as stream } from './stream';
97 changes: 97 additions & 0 deletions src/public/exec/stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import core from '~/core';
import expose from '~/utils/expose';
import { IChild } from '~/core/types';
import parallel from './parallel';
import series from './series';
import join from 'command-join';
import { NODE_PATH, KPO_PATH } from '~/constants';
import { IMultiExecOptions } from '~/types';
import chalk from 'chalk';
import { oneLine } from 'common-tags';
import { WrappedError } from '~/utils/errors';

/**
* Options taken by `stream`
*/
export type TStreamOptions = IMultiExecOptions & {
/**
* Include children by name
*/
include?: string[];
/**
* Exclude children by name
*/
exclude?: string[];
/**
* Execute streaming in parallel
*/
parallel?: boolean;
/**
* Cwd is forbidden on `TStreamOptions`
*/
cwd?: null;
};

export default expose(stream);

function stream(
argv: string[],
options: TStreamOptions = {}
): (args?: string[]) => Promise<void> {
return async (args?: string[]) => {
let children = await core.children();
if (!children.length) throw Error(`Project has no children`);

if (options.include) {
children = options.include.map((name) => getChild(name, children));
}

if (options.exclude && options.exclude.length) {
const excludeDirs = (options.exclude || []).map(
(name) => getChild(name, children).directory
);
children = children.filter(
(child) => !excludeDirs.includes(child.directory)
);
}

if (!children.length) throw Error(`No project children selected`);

const commands = children.map((child) => {
return [NODE_PATH, KPO_PATH, '-d', child.directory].concat(argv);
});

await (options.parallel
? parallel(commands.map(join), {
...options,
cwd: undefined,
names: children.map((child) => '@' + child.name)
})(args)
: series(
commands.reduce(
(acc: string[], cmd, i) =>
acc.concat([
join([
NODE_PATH,
'-e',
oneLine`console.log(
"\\nScope: ${chalk.bold.yellow('@' + children[i].name)}"
)`
]),
join(cmd)
]),
[]
),
{ ...options, cwd: undefined }
)(args).catch(async (err) => {
throw new WrappedError('Series commands execution failed', null, err);
}));
};
}

function getChild(name: string, children: IChild[]): IChild {
const matches = children.filter((child) => child.matcher(name));
if (matches.length > 1) throw Error(`Several scopes matched name "${name}"`);
if (matches.length < 1) throw Error(`Scope "${name}" not found`);
return matches[0];
}

0 comments on commit 76da0d0

Please sign in to comment.