From d23bd645d1b05c594a40ccd97356fe53163c4756 Mon Sep 17 00:00:00 2001 From: Francisco Tavares Date: Fri, 25 Feb 2022 15:23:53 +0000 Subject: [PATCH] feat: Add batch mode for plugin-runner-bin --- packages/plugin-runner-bin/runners.json | 13 +++++++ packages/plugin-runner-bin/src/index.ts | 52 ++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 packages/plugin-runner-bin/runners.json diff --git a/packages/plugin-runner-bin/runners.json b/packages/plugin-runner-bin/runners.json new file mode 100644 index 0000000..8302199 --- /dev/null +++ b/packages/plugin-runner-bin/runners.json @@ -0,0 +1,13 @@ +{ + "runners": { + "default": { + "handler": "./lib", + "description": "Runs bin" + }, + "batch": { + "handler": "./lib#batchRunner", + "description": "Runs bin in batch mode", + "batch": true + } + } +} \ No newline at end of file diff --git a/packages/plugin-runner-bin/src/index.ts b/packages/plugin-runner-bin/src/index.ts index c09b11f..332799a 100644 --- a/packages/plugin-runner-bin/src/index.ts +++ b/packages/plugin-runner-bin/src/index.ts @@ -1,4 +1,5 @@ import { defineRunner, defineOptionsFromJSONSchema } from '@garment/runner'; +import * as optionsSchema from './schema.json'; import { parseOptions, resolveBin } from './utils'; import execa = require('execa'); @@ -40,7 +41,7 @@ export interface BinRunnerOptions { } export default defineRunner( - defineOptionsFromJSONSchema(require('./schema.json')), + defineOptionsFromJSONSchema(optionsSchema), async ctx => { const { logger, options, project, workspace, renderTemplate } = ctx; const { stream, env, longRunning = false } = options; @@ -83,3 +84,52 @@ export default defineRunner( } } ); + +export const batchRunner = defineRunner( + defineOptionsFromJSONSchema(optionsSchema), + async ctx => { + const { workspace, logger, renderTemplate } = ctx; + + for (const item of ctx.batch()) { + const { options, project } = item; + const { stream, env, longRunning = false } = options; + const [binOption, ...args] = parseOptions(options).map(arg => + renderTemplate(arg, { + projectDir: project.fullPath, + workspaceDir: workspace.cwd, + projectName: project.name + }) + ); + + const bin = await resolveBin(binOption, workspace.cwd); + logger.debug('bin:', bin); + logger.debug('args:', args); + + try { + const promise = execa(bin, args, { + cwd: project.fullPath, + stdin: 'inherit', + stdout: stream ? 'inherit' : 'pipe', + stderr: stream ? 'inherit' : 'pipe', + env + }); + + if (!longRunning) { + const { stderr, stdout } = await promise; + + if (!stream) { + logger.info(stdout); + if (stderr) { + logger.info(stderr); + } + } + } + } catch (error) { + if (!stream) { + logger.info(error.stdout); + logger.error(error.stderr); + } + } + } + } +);