@antora/cli 3.0.0-alpha.9 → 3.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  The command line interface (CLI) for Antora.
4
4
 
5
5
  [Antora](https://antora.org) is a modular static site generator designed for creating documentation sites from AsciiDoc documents.
6
- Its site generator pipeline aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
6
+ Its site generator aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
7
7
 
8
- To run Antora, you need both the CLI and a site generator pipeline.
8
+ To run Antora, you need both the CLI and a site generator.
9
9
  Once these packages are installed, you can use the `antora` command to generate your site.
10
10
 
11
11
  ## How to Install
@@ -24,10 +24,10 @@ antora -v
24
24
  ```
25
25
 
26
26
  Next, install a site generator.
27
- The default site generator will be sufficient for most users.
27
+ The site generator provided by Antora will be sufficient for most users.
28
28
 
29
29
  ```sh
30
- npm install -g @antora/site-generator-default
30
+ npm install -g @antora/site-generator
31
31
  ```
32
32
 
33
33
  The `antora` command (specifically the implicit `generate` subcommand) will look for this package by default.
package/lib/cli.js CHANGED
@@ -1,64 +1,74 @@
1
- #!/usr/bin/env node
2
-
3
1
  'use strict'
4
2
 
3
+ const buildPlaybook = require('@antora/playbook-builder')
5
4
  const cli = require('./commander')
6
- // Q: can we ask the playbook builder for the config schema?
7
- const configSchema = require('@antora/playbook-builder/lib/config/schema')
8
5
  const convict = require('@antora/playbook-builder/lib/solitary-convict')
9
- const { finalizeLogger } = require('@antora/logger')
10
6
  const ospath = require('path')
11
7
  const userRequire = require('@antora/user-require-helper')
12
8
 
13
- const DEFAULT_GENERATOR = '@antora/site-generator-default'
14
9
  const { version: VERSION } = require('../package.json')
15
10
 
16
11
  async function run (argv = process.argv) {
17
- const args = argv.slice(2)
18
- return cli.parseAsync(args.length ? args : ['help'], { from: 'user' })
12
+ return cli.parseAsync((argv = argv.slice(2)).length ? argv : ['help'], { from: 'user' })
19
13
  }
20
14
 
21
- function exitWithError (err, showStack, msg = undefined) {
22
- if (!msg) msg = err.message || err
23
- if (showStack) {
24
- let stack
25
- if ((stack = err.backtrace)) {
26
- msg = [`error: ${msg}`, ...stack.slice(1)].join('\n')
27
- } else if ((stack = err.stack)) {
28
- if (err instanceof SyntaxError) {
29
- let loc
30
- ;[loc, stack] = stack.split(/\n+(?=SyntaxError: )/)
31
- msg = stack.replace('\n', `\n at ${loc}\n`)
32
- } else if (stack.startsWith(`${err.name}: ${msg}\n`)) {
33
- msg = stack
34
- } else {
35
- msg = [msg, ...stack.split('\n').slice(1)].join('\n')
36
- }
37
- } else {
38
- msg = `error: ${msg} (no stack)`
39
- }
40
- console.error(msg)
15
+ function exitWithError (err, opts, msg = undefined) {
16
+ const { getLogger, configureLogger } = requireLogger()
17
+ let errMessage = String(
18
+ err instanceof Error ? err.message : Object.assign((err = new Error(String(err))), { stack: undefined }).message
19
+ )
20
+ const name = errMessage.startsWith('asciidoctor: FAILED: ')
21
+ ? (errMessage = errMessage.slice(21)) && 'asciidoctor'
22
+ : cli.name()
23
+ if (!msg) msg = errMessage
24
+ if (!getLogger(null)) {
25
+ configureLogger({ format: 'pretty', level: opts.silent ? 'silent' : 'fatal', failureLevel: 'fatal' })
26
+ }
27
+ if (opts.stacktrace) {
28
+ getLogger(name).fatal(err, msg)
41
29
  } else {
42
- console.error(`error: ${msg}\nAdd the --stacktrace option to see the cause.`)
30
+ getLogger(name).fatal({ hint: 'Add the --stacktrace option to see the cause of the error.' }, msg)
43
31
  }
44
- process.exit(1)
32
+ return exit()
33
+ }
34
+
35
+ function exit () {
36
+ return requireLogger()
37
+ .finalizeLogger()
38
+ .then((failOnExit) => process.exit(process.exitCode || (failOnExit ? 1 : 0)))
45
39
  }
46
40
 
47
41
  function getTTYColumns () {
48
42
  return process.env.COLUMNS || process.stdout.columns || 80
49
43
  }
50
44
 
45
+ function outputError (str, write) {
46
+ write(str.replace(/^error: /, cli.name() + ': '))
47
+ }
48
+
49
+ function requireLogger (fromPath = undefined, moduleName = '@antora/logger') {
50
+ try {
51
+ return (
52
+ requireLogger.cache ||
53
+ (requireLogger.cache = fromPath ? userRequire(moduleName, { paths: [fromPath] }) : require(moduleName))
54
+ ) // require('@antora/logger')
55
+ } catch {
56
+ return fromPath && (requireLogger.cache = require(moduleName))
57
+ }
58
+ }
59
+
51
60
  cli
52
61
  .allowExcessArguments(false)
53
- .configureOutput({ getOutHelpWidth: getTTYColumns, getErrHelpWidth: getTTYColumns })
62
+ .configureOutput({ getOutHelpWidth: getTTYColumns, getErrHelpWidth: getTTYColumns, outputError })
54
63
  .storeOptionsAsProperties()
55
64
  .name('antora')
56
65
  .version(
57
66
  {
58
67
  toString () {
59
- const buffer = [`@antora/cli: ${VERSION}`]
68
+ const generator = cli._findCommand('generate').getOptionValue('generator')
69
+ const buffer = ['@antora/cli: ' + VERSION]
60
70
  let generatorVersion
61
- const generatorPackageJson = DEFAULT_GENERATOR + '/package.json'
71
+ const generatorPackageJson = generator + '/package.json'
62
72
  try {
63
73
  generatorVersion = require(generatorPackageJson).version
64
74
  } catch {
@@ -66,7 +76,7 @@ cli
66
76
  generatorVersion = require(require.resolve(generatorPackageJson, { paths: [''] })).version
67
77
  } catch {}
68
78
  }
69
- buffer.push(DEFAULT_GENERATOR + ': ' + (generatorVersion || 'not installed'))
79
+ buffer.push(generator + ': ' + (generatorVersion || 'not installed'))
70
80
  return buffer.join('\n')
71
81
  },
72
82
  },
@@ -76,69 +86,73 @@ cli
76
86
  .description('A modular, multi-repository documentation site generator for AsciiDoc.')
77
87
  .usage('[options] [[command] [args]]')
78
88
  .helpOption('-h, --help', 'Output usage information.')
79
- .addHelpText(
80
- 'after',
81
- function () {
82
- const name = this.name()
83
- return this.createHelp().wrap(
89
+ .addHelpText('after', () => {
90
+ const name = cli.name()
91
+ return cli
92
+ .createHelp()
93
+ .wrap(
84
94
  ` \nRun '${name} <command> --help' to see options and examples for a command (e.g., ${name} generate --help).`,
85
95
  getTTYColumns(),
86
96
  0
87
97
  )
88
- }.bind(cli)
89
- )
98
+ })
90
99
  .option('-r, --require <library>', 'Require library (aka node module) or script path before executing command.')
91
100
  .on('option:require', (requireRequest) => (cli.requireRequests = cli.requireRequests || []).push(requireRequest))
92
101
  .option('--stacktrace', 'Print the stacktrace to the console if the application fails.')
93
102
 
94
103
  cli
95
104
  .command('generate <playbook>', { isDefault: true })
96
- .description('Generate a documentation site specified in <playbook>.')
97
- .optionsFromConvict(convict(configSchema), { exclude: 'playbook' })
98
- .addOption(
99
- cli
100
- .createOption('--generator <library>', 'The site generator library.')
101
- .default(DEFAULT_GENERATOR, DEFAULT_GENERATOR)
102
- )
105
+ .description('Generate a documentation site as specified by <playbook>.')
106
+ .optionsFromConvict(convict(buildPlaybook.defaultSchema), { exclude: 'playbook' })
107
+ .trackOptions()
103
108
  .action(async (playbookFile, options, command) => {
104
- const dot = ospath.resolve(playbookFile, '..')
105
- const userRequireContext = { dot, paths: [dot, __dirname] }
109
+ const errorOpts = { stacktrace: cli.stacktrace, silent: command.silent }
110
+ const playbookDir = ospath.resolve(playbookFile, '..')
111
+ const userRequireContext = { dot: playbookDir, paths: [playbookDir, __dirname] }
106
112
  if (cli.requireRequests) {
107
113
  try {
108
114
  cli.requireRequests.forEach((requireRequest) => userRequire(requireRequest, userRequireContext))
109
115
  } catch (err) {
110
- exitWithError(err, cli.stacktrace)
116
+ return exitWithError(err, errorOpts)
111
117
  }
112
118
  }
113
- const generator = options.generator
119
+ const args = command.optionArgs.concat('--playbook', playbookFile)
120
+ let generator, generatorPath, playbook
121
+ try {
122
+ playbook = buildPlaybook(args, process.env, buildPlaybook.defaultSchema, (config) => {
123
+ try {
124
+ generatorPath = userRequire.resolve((generator = config.get('antora.generator')), userRequireContext)
125
+ } catch {}
126
+ try {
127
+ requireLogger(generatorPath).configureLogger(config.getModel('runtime.log'), playbookDir)
128
+ } catch {}
129
+ })
130
+ } catch (err) {
131
+ return exitWithError(err, errorOpts)
132
+ }
114
133
  let generateSite
115
134
  try {
116
- generateSite = userRequire(generator, userRequireContext)
135
+ generateSite =
136
+ (generateSite = require(generatorPath || userRequire.resolve(generator, userRequireContext))).length === 1
137
+ ? generateSite.bind(null, playbook)
138
+ : generateSite.bind(null, args, process.env)
117
139
  } catch (err) {
118
140
  let msg = 'Generator not found or failed to load.'
119
141
  if (generator && generator.charAt() !== '.') msg += ` Try installing the '${generator}' package.`
120
- exitWithError(err, cli.stacktrace, msg)
142
+ return exitWithError(err, errorOpts, msg)
121
143
  }
122
- const args = cli.rawArgs.slice(cli.rawArgs.indexOf(command.name()) + 1)
123
- args.splice(args.indexOf(playbookFile), 0, '--playbook')
124
- // TODO support passing a preloaded convict config as third option; gets new args and env
125
- return generateSite(args, process.env)
126
- .then(finalizeLogger)
127
- .then((failOnExit) => process.exit(failOnExit ? 1 : process.exitCode))
128
- .catch((err) => finalizeLogger().then(() => exitWithError(err, cli.stacktrace)))
144
+ return generateSite().then(exit, (err) => exitWithError(err, errorOpts))
129
145
  })
130
146
  .options.sort((a, b) => a.long.localeCompare(b.long))
131
147
 
132
148
  cli.command('help [command]', { hidden: true }).action((name, options, command) => {
133
149
  if (name) {
134
- const helpCommand = cli.commands.find((candidate) => candidate.name() === name)
150
+ const helpCommand = cli._findCommand(name)
135
151
  if (helpCommand) {
136
152
  helpCommand.help()
137
153
  } else {
138
- console.error(
139
- `'${name}' is not a valid command in ${cli.name()}. See '${cli.name()} --help' for a list of commands.`
140
- )
141
- process.exit(1)
154
+ const message = `error: unknown command '${name}'. See '${cli.name()} --help' for a list of commands.`
155
+ cli._displayError(1, 'commander.unknownCommand', message)
142
156
  }
143
157
  } else {
144
158
  cli.help()
@@ -0,0 +1,14 @@
1
+ 'use strict'
2
+
3
+ const { Command } = require('commander')
4
+
5
+ Command.prototype.trackOptions = function () {
6
+ const optionArgs = (this.optionArgs = [])
7
+ for (const eventName of this.eventNames().filter((name) => name.startsWith('option:'))) {
8
+ this.on(eventName, function () {
9
+ optionArgs.push(`--${eventName.slice(7)}`)
10
+ if (arguments.length) optionArgs.push(arguments[0])
11
+ })
12
+ }
13
+ return this
14
+ }
package/lib/commander.js CHANGED
@@ -2,5 +2,6 @@
2
2
 
3
3
  const commander = require('commander')
4
4
  require('./commander/options-from-convict')
5
+ require('./commander/track-options')
5
6
 
6
7
  module.exports = commander
package/lib/index.js ADDED
@@ -0,0 +1,14 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * The command line interface (CLI) for Antora.
5
+ *
6
+ * Provides a built-in set of commands to run Antora. The default command is
7
+ * generate. The generate command builds the specified playbook, configures the
8
+ * logger, then requires and invokes the generator function. When the generator
9
+ * function completes or fails, the generate command finalizes the logger and
10
+ * exits with the specified exit code.
11
+ *
12
+ * @namespace cli
13
+ */
14
+ module.exports = require('./cli')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/cli",
3
- "version": "3.0.0-alpha.9",
3
+ "version": "3.0.0-beta.4",
4
4
  "description": "The command line interface for Antora.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "OpenDevise Inc. (https://opendevise.com)",
@@ -13,23 +13,25 @@
13
13
  "bugs": {
14
14
  "url": "https://gitlab.com/antora/antora/issues"
15
15
  },
16
- "main": "lib/cli.js",
16
+ "main": "lib/index.js",
17
17
  "bin": {
18
18
  "antora": "bin/antora"
19
19
  },
20
20
  "dependencies": {
21
- "@antora/logger": "3.0.0-alpha.9",
22
- "@antora/playbook-builder": "3.0.0-alpha.9",
21
+ "@antora/logger": "3.0.0-beta.4",
22
+ "@antora/playbook-builder": "3.0.0-beta.4",
23
23
  "@antora/user-require-helper": "~2.0",
24
- "commander": "~7.2"
24
+ "commander": "~8.3"
25
25
  },
26
26
  "devDependencies": {
27
- "@antora/site-publisher": "3.0.0-alpha.9",
28
- "convict": "~6.1",
29
- "kapok-js": "~0.10"
27
+ "@antora/site-publisher": "3.0.0-beta.4",
28
+ "@asciidoctor/core": "~2.2",
29
+ "convict": "~6.2",
30
+ "kapok-js": "~0.10",
31
+ "node-git-server": "~0.6"
30
32
  },
31
33
  "engines": {
32
- "node": ">=10.17.0"
34
+ "node": ">=12.21.0"
33
35
  },
34
36
  "files": [
35
37
  "bin/",
@@ -43,5 +45,6 @@
43
45
  "static site",
44
46
  "web publishing"
45
47
  ],
46
- "gitHead": "a504d6889819b548e8a5416a7194cbb6f9a93e93"
48
+ "gitHead": "8a142499e9f1a9e0631777796e06dd6c010d3a90",
49
+ "readmeFilename": "README.md"
47
50
  }