diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 5d09b4ded3f77f14f139ccc174fc95e145db8d7d..362c40b2e5ce42310b23080acd1c77c684112fd7 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -14,6 +14,7 @@ For a detailed view of what's changed, refer to the {url-repo}/commits[commit hi * don't remove the scan dir unless the `clean: true` is specified on the scan entry (#10) * process cleans per collector entry rather than before running collector on the origin (#10) +* allow `run` key to accept an array of entries (#14) == 1.0.0-alpha.3 (2022-11-12) diff --git a/docs/modules/ROOT/pages/configuration-keys.adoc b/docs/modules/ROOT/pages/configuration-keys.adoc index a9257c0a2ebcf4698da03f479a32f86e70eb402a..a07579955e528f83f127a7053542a03fae9f83e8 100644 --- a/docs/modules/ROOT/pages/configuration-keys.adoc +++ b/docs/modules/ROOT/pages/configuration-keys.adoc @@ -43,6 +43,7 @@ ext: <.> `files` key that provides a pattern of files to scan The `collector` key accepts an array (i.e., list) of collector entries. +These entries can configure any combination of clean, run, and scan operations. If there's only a single entry, the array can be replaced by a map for a single entry (i.e., no preceding hyphen). If the `collector` key isn't set in a component version descriptor, or its value is falsy, the extension won't run on that git reference. @@ -89,7 +90,7 @@ In this case, the first clean entry can be important to ensuring a predictable r == run key The `run` key is nested under the `collector` key. -The `run` key accepts a list of built-in key-value pairs that configure the external command or commands (`command`) to be run and the scan settings (`scan`) the extension will use once the previous command is complete. +If the `collector` key is an array, the `run` key must be specified as a key on one of its entries. .antora.yml [,yaml] @@ -100,7 +101,9 @@ version: '5.6.0' ext: collector: - run: - command: ./gradlew --console rich generateContent + - command: gradlew -v + local: true + - command: ./gradlew --console rich generateContent scan: dir: build/generated clean: true @@ -110,8 +113,16 @@ ext: dir: analysis/final ---- -The `run` key can be specified multiple times. -Each `run` key is invoked sequentially in the order specified in the array. +The `run` key accepts an array of items (i.e., list). +An entry in the `run` key is a map of built-in key-value pairs that configure the run, which includes the directory (`dir`) and command string (`command`). +Each `run` entry is invoked sequentially in the order specified in the array. +If there's only a single entry, the array can be replaced by a map for a single entry. + +If the `local` key is specified with the value `true`, the command must be located relative to where the command is run. +This key can be set implicitly by prepending the command with `./`. +This setting effectively disables looking for a global command on the current user's PATH. + +If the command ends with `.js`, the Node.js binary used to run Antora is also used to run the command. [#scan-key] == scan key @@ -200,6 +211,13 @@ Otherwise, the path is resolved relative to the worktree. |Not set |Path relative to the content root +|`run.local` +|Prevents system from resolving global command on the user's PATH. +In this case, the command must be located at the location relative to where the command is run. +This key can be set implicitly by prepending the command with `./`. +|Not set (false) +|Boolean + |`scan.dir` |Defines the location from where the extension collects the generated files after the previous command is complete. The extension then imports the collected files into the bucket in the content aggregate. diff --git a/packages/collector-extension/lib/index.js b/packages/collector-extension/lib/index.js index c73be8af37eafb100040c9ad0a685258804d13a8..3a684f6aaae3fd1fb631d3bfae308563de7d5aad 100644 --- a/packages/collector-extension/lib/index.js +++ b/packages/collector-extension/lib/index.js @@ -42,10 +42,13 @@ module.exports.register = function () { if (typeof clean.dir === 'string') accum.push({ dir: expandPath(clean.dir, expandPathContext) }) return accum }, [])), - run: { - ...runConfig, - cwd: typeof runConfig.dir === 'string' ? expandPath(runConfig.dir, expandPathContext) : worktreeDir, - }, + run: (Array.isArray(runConfig) ? runConfig : [runConfig]).reduce((accum, run) => { + if (typeof run.command === 'string') { + const dir = typeof run.dir === 'string' ? expandPath(run.dir, expandPathContext) : worktreeDir + accum.push({ ...run, dir }) + } + return accum + }, []), scan: (Array.isArray(scanConfig) ? scanConfig : [scanConfig]).reduce((accum, scan) => { if (typeof scan.dir === 'string') { const dir = expandPath(scan.dir, expandPathContext) @@ -61,30 +64,31 @@ module.exports.register = function () { const ref = `refs/${reftype === 'branch' ? 'head' : reftype}s/${refname}` await prepareWorktree({ fs, cache, dir: worktreeDir, gitdir, ref, remote, bare: worktree === undefined }) } - for (const { clean: cleans, run, scan: scans } of collectors) { + for (const { clean: cleans, run: runs, scan: scans } of collectors) { for (const clean of cleans) { await fsp.rm(clean.dir, { recursive: true, force: true }) } - const { cwd, command, local } = run - if (command) { - let cmd = command - const opts = { cwd, output: true, quiet } - if (local) { - opts.local = true - } else if (cmd.startsWith('./')) { - cmd = cmd.slice(2) - opts.local = true - } else if (cmd.startsWith('node ') ? (cmd = cmd.slice(5)) : cmd.split(' ', 2)[0].endsWith('.js')) { - cmd = `"${process.execPath}" ${cmd}` - } - try { - await runCommand(cmd, [], opts) - } catch (err) { - const loc = worktree || url - const flag = worktree ? ' ' : remote && worktree === false ? ` ` : '' - const pathInfo = startPath ? ` | start path: ${startPath}` : '' - const ctx = ` in ${loc} (${reftype}: ${refname}${flag}${pathInfo})` - throw Object.assign(err, { message: `(${PACKAGE_NAME}): ${err.message.replace(/$/m, ctx)}` }) + for (const { dir: cwd, command, local } of runs) { + if (command) { + let cmd = command + const opts = { cwd, output: true, quiet } + if (local) { + opts.local = true + } else if (cmd.startsWith('./')) { + cmd = cmd.slice(2) + opts.local = true + } else if (cmd.startsWith('node ') ? (cmd = cmd.slice(5)) : cmd.split(' ', 2)[0].endsWith('.js')) { + cmd = `"${process.execPath}" ${cmd}` + } + try { + await runCommand(cmd, [], opts) + } catch (err) { + const loc = worktree || url + const flag = worktree ? ' ' : remote && worktree === false ? ` ` : '' + const pathInfo = startPath ? ` | start path: ${startPath}` : '' + const ctx = ` in ${loc} (${reftype}: ${refname}${flag}${pathInfo})` + throw Object.assign(err, { message: `(${PACKAGE_NAME}): ${err.message.replace(/$/m, ctx)}` }) + } } } for (const scan of scans) { diff --git a/packages/collector-extension/test/collector-extension-test.js b/packages/collector-extension/test/collector-extension-test.js index 736c1ecca8d4dc61768523120d24a3d07d3512f8..123e58e1de3b62dde106b23c2b8c34dcf95a7801 100644 --- a/packages/collector-extension/test/collector-extension-test.js +++ b/packages/collector-extension/test/collector-extension-test.js @@ -634,10 +634,7 @@ describe('collector extension', () => { it('should not clean worktree between collector entries', async () => { const collectorConfig = [ { - run: { command: 'node .gen-files.js' }, - }, - { - run: { command: 'node .gen-component-desc.js' }, + run: [{ command: 'node .gen-files.js' }, { command: 'node .gen-component-desc.js' }], }, { run: { command: 'node .gen-start-page.js' }, @@ -675,10 +672,7 @@ describe('collector extension', () => { it('should clean specified dirs per collector entry', async () => { const collectorConfig = [ { - run: { command: 'node .gen-files.js' }, - }, - { - run: { command: 'node .gen-component-desc.js' }, + run: [{ command: 'node .gen-files.js' }, { command: 'node .gen-component-desc.js' }], }, { clean: [{ dir: 'build/modules/ROOT/examples' }, { dir: 'build/modules/ROOT/partials' }],