From 4937366760278848b564984ee6b1b119cc712c2f Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Wed, 30 Oct 2024 02:30:13 -0600 Subject: [PATCH] resolves #46 suppress stderr from command if runtime.silent key on playbook is true --- CHANGELOG.adoc | 1 + .../modules/ROOT/pages/configure-run.adoc | 3 ++- packages/collector-extension/lib/index.js | 5 +++-- packages/collector-extension/lib/util/run-command.js | 10 +++++----- .../test/collector-extension-test.js | 11 ++++++++--- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index e8b464c..547d955 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -16,6 +16,7 @@ For a detailed view of what's changed, refer to the {url-repo}/commits[commit hi * move repository URL inside paranthetical context in error message * report missing command in error message using ps.spawnargs[0] instead of cmdv[0] for consistency * rename project to Antora Collector and project repository to antora-collector (name of npm package remains the same) (#45) +* suppress stderr from command if runtime.silent key on playbook is true (#46) === Fixed diff --git a/docs/collector-extension/modules/ROOT/pages/configure-run.adoc b/docs/collector-extension/modules/ROOT/pages/configure-run.adoc index 32344c9..823087f 100644 --- a/docs/collector-extension/modules/ROOT/pages/configure-run.adoc +++ b/docs/collector-extension/modules/ROOT/pages/configure-run.adoc @@ -147,7 +147,8 @@ This alternation is not often needed if the command has arguments. By default, both the stdout (output stream) and stderr (error stream) of the command are directed to the current terminal. The extension also logs the command it's about to run at the info level. If you want to suppress the stdout and the info log message, you can set the `runtime.quiet` key in the playbook to true. -It's not currently possible to suppress the stderr. +If you also want to suppress the stderr, you can set the `runtime.silent` key in the playbook to true. +If the command fails, the stderr lines will still be appended to the error message. === Use the current Node.js diff --git a/packages/collector-extension/lib/index.js b/packages/collector-extension/lib/index.js index 37ac342..20bbdcc 100644 --- a/packages/collector-extension/lib/index.js +++ b/packages/collector-extension/lib/index.js @@ -23,7 +23,8 @@ module.exports.register = function ({ config: { createWorktrees = 'auto', keepWo this.once('contentAggregated', async ({ playbook, contentAggregate }) => { let logger const playbookEnv = playbook.env - const quiet = playbook.runtime?.quiet + const silent = playbook.runtime?.silent + const quiet = silent || playbook.runtime?.quiet const cacheDir = ospath.join(getBaseCacheDir(playbook), 'collector') await fsp.mkdir(cacheDir, { recursive: true }) const git = this.require('@antora/content-aggregator/git') @@ -140,7 +141,7 @@ module.exports.register = function ({ config: { createWorktrees = 'auto', keepWo commandContext = createCommandContext(url, remote, startPath, worktree, reftype, refname) logger.info(`run.command: ${command}${commandContext}`) } - await runCommand(command, { cwd, local, shell: !!shell, env, quiet, cache: runCache }) + await runCommand(command, { cwd, local, shell: !!shell, env, quiet, silent, cache: runCache }) } catch (err) { commandContext ??= createCommandContext(url, remote, startPath, worktree, reftype, refname) err.message = err.message.replace(/$/m, commandContext) diff --git a/packages/collector-extension/lib/util/run-command.js b/packages/collector-extension/lib/util/run-command.js index 31ed0af..7a9d55f 100644 --- a/packages/collector-extension/lib/util/run-command.js +++ b/packages/collector-extension/lib/util/run-command.js @@ -18,7 +18,7 @@ async function runCommand (cmd = '', opts = {}) { let cmdv = parseCommand(String(cmd), { preserveQuotes: shell }) if (!cmdv.length) throw new TypeError('Command not specified') let cmd0 = cmdv[0] - const { quiet, local, cache: { where = {} } = {}, ...spawnOpts } = opts + const { silent, quiet = silent, local, cache: { where = {} } = {}, ...spawnOpts } = opts if (IS_WIN) { if (~cmd0.indexOf('/')) cmdv[0] = cmd0 = cmd0.replace(/[/]/g, ospath.sep) if (shell) { @@ -64,10 +64,10 @@ async function runCommand (cmd = '', opts = {}) { } else if (local && !~cmd0.indexOf('/')) { cmdv[0] = './' + cmd0 } - return spawnCommand(cmdv, spawnOpts, quiet) + return spawnCommand(cmdv, spawnOpts, { stdout: !quiet, stderr: !silent }) } -async function spawnCommand (cmdv, opts, quiet) { +async function spawnCommand (cmdv, opts, output) { return new Promise((resolve, reject) => { try { const [cmd, ...args] = cmdv @@ -75,7 +75,7 @@ async function spawnCommand (cmdv, opts, quiet) { const ps = spawn(cmd, args, opts) ps.on('close', (exitCode, signalCode) => { if (exitCode === 0) { - if (stderr.length) process.stderr.write(stderr.join('')) + if (stderr.length && output.stderr) process.stderr.write(stderr.join('')) resolve() } else { const result = signalCode ? `terminated with signal ${signalCode}` : `failed with exit code ${exitCode ?? -1}` @@ -85,7 +85,7 @@ async function spawnCommand (cmdv, opts, quiet) { } }) ps.on('error', (err) => reject(err.code === 'ENOENT' ? new Error(`Command not found: ${ps.spawnargs[0]}`) : err)) - ps.stdout.on('data', (data) => quiet || process.stdout.write(data)) + ps.stdout.on('data', (data) => output.stdout && process.stdout.write(data)) ps.stderr.on('data', (data) => stderr.push(data)) ps.stdin.end() } catch (err) { diff --git a/packages/collector-extension/test/collector-extension-test.js b/packages/collector-extension/test/collector-extension-test.js index c0dbbf7..663d7b6 100644 --- a/packages/collector-extension/test/collector-extension-test.js +++ b/packages/collector-extension/test/collector-extension-test.js @@ -153,7 +153,7 @@ describe('collector extension', () => { } const runScenario = async (opts) => { - const { repoName, branches, tags, startPath, local, collectorConfig, quiet, before, after } = opts + const { repoName, branches, tags, startPath, local, collectorConfig, quiet, silent, before, after } = opts const repo = await createRepository({ repoName, branches, tags, startPath, collectorConfig }) const playbook = { content: { @@ -167,7 +167,7 @@ describe('collector extension', () => { ], }, env: process.env, - runtime: { cacheDir: CACHE_DIR, quiet: quiet == null ? true : quiet }, + runtime: { cacheDir: CACHE_DIR, quiet: quiet == null ? true : quiet, silent }, } const contentAggregate = await aggregateContent(playbook) if (before) isAsync(before) ? await before(contentAggregate, playbook) : before(contentAggregate, playbook) @@ -2055,13 +2055,18 @@ describe('collector extension', () => { assert.equal(stdout, 'start\nall done!\n') }) - // TODO: perhaps direct these messages to the log? it('should direct stderr from command to parent stderr even when quiet is true', async () => { const collectorConfig = { run: { command: '$NODE .gen-error-output.js' } } const stderr = await captureStderr(() => runScenario({ repoName: 'at-root', collectorConfig })) assert.equal(stderr, 'there were some issues\n') }) + it('should suppress stderr from command when silent is true', async () => { + const collectorConfig = { run: { command: '$NODE .gen-error-output.js' } } + const stderr = await captureStderr(() => runScenario({ repoName: 'at-root', collectorConfig, silent: true })) + assert.equal(stderr.length, 0) + }) + it('should suppress stdout from command when quiet is true', async () => { const collectorConfig = { run: { command: '$NODE .gen-output.js' } } const stdout = await captureStdout(() => runScenario({ repoName: 'at-root', collectorConfig })) -- GitLab