@antora/playbook-builder 3.1.14 → 3.2.0-alpha.10

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.
@@ -2,8 +2,10 @@
2
2
 
3
3
  const convict = require('./solitary-convict')
4
4
  const defaultSchema = require('./config/schema')
5
- const fs = require('fs')
6
- const ospath = require('path')
5
+ const fs = require('node:fs')
6
+ const ospath = require('node:path')
7
+ const parseArgs = require('yargs-parser')
8
+ const yaml = require('js-yaml')
7
9
 
8
10
  /**
9
11
  * Builds a playbook object according to the provided schema from the specified
@@ -28,8 +30,22 @@ const ospath = require('path')
28
30
  * marked in the schema as preserve, all keys in the playbook are camelCased.
29
31
  */
30
32
  function buildPlaybook (args = [], env = process.env, schema = defaultSchema, beforeValidate = undefined) {
31
- const config = Object.assign(convict(schema, { args, env }), { getModel })
32
- const playbook = config.has('playbook') && config.get('playbook')
33
+ const parsedArgs = parseArgs(args, { configuration: { 'dot-notation': false } })
34
+ const opts = { args: [], env: {} }
35
+ const config = Object.assign(convict(schema, opts), { getModel, getSchema })
36
+ Object.assign(opts, { args, env })
37
+ let playbook
38
+ if ('playbook' in schema) {
39
+ const playbookEnv = schema.playbook.env
40
+ if (playbookEnv != null) playbook = env[playbookEnv]
41
+ const playbookArg = schema.playbook.arg
42
+ if (playbookArg != null) playbook = parsedArgs[playbookArg] ?? playbook
43
+ if (playbook === undefined) {
44
+ if (config.has('playbook')) playbook = config.get('playbook')
45
+ } else {
46
+ config.set('playbook', playbook)
47
+ }
48
+ }
33
49
  let absPlaybookPath
34
50
  if (playbook) {
35
51
  if (ospath.extname((absPlaybookPath = ospath.resolve(playbook)))) {
@@ -50,10 +66,11 @@ function buildPlaybook (args = [], env = process.env, schema = defaultSchema, be
50
66
  }
51
67
  }
52
68
  try {
53
- if (playbook) {
54
- config.loadFile(absPlaybookPath)
55
- if (playbook !== absPlaybookPath) config.set('playbook', absPlaybookPath)
56
- }
69
+ Object.assign(opts, { args: [] })
70
+ playbook ? config.loadFile(absPlaybookPath) : config.load({})
71
+ importArguments(config, parsedArgs)
72
+ Object.assign(opts, { args })
73
+ if (playbook && playbook !== absPlaybookPath) config.set('playbook', absPlaybookPath)
57
74
  const beforeValidateFromSchema = config._def[Symbol.for('convict.beforeValidate')]
58
75
  if (beforeValidateFromSchema) beforeValidateFromSchema(config)
59
76
  if (beforeValidate) beforeValidate(config)
@@ -82,9 +99,8 @@ function camelCaseKeys (o, stopPaths = [], p = '') {
82
99
  function getModel (name) {
83
100
  let config = this
84
101
  const data = config.get(name)
85
- let schema = config._schema
102
+ const schema = config.getSchema(name)
86
103
  if (name) {
87
- schema = name.split('.').reduce((accum, key) => accum._cvtProperties[key], schema)
88
104
  config = Object.assign(convict(name.split('.').reduce((def, key) => def[key], config._def)), { _instance: data })
89
105
  }
90
106
  config.validate({ allowed: 'strict' })
@@ -97,6 +113,10 @@ function getModel (name) {
97
113
  return model
98
114
  }
99
115
 
116
+ function getSchema (name) {
117
+ return name ? name.split('.').reduce((accum, key) => accum._cvtProperties[key], this._schema) : this._schema
118
+ }
119
+
100
120
  function getStopPaths (schemaProperties, schemaPath = [], stopPaths = []) {
101
121
  for (const [key, { preserve, _cvtProperties }] of Object.entries(schemaProperties)) {
102
122
  if (preserve) {
@@ -110,6 +130,22 @@ function getStopPaths (schemaProperties, schemaPath = [], stopPaths = []) {
110
130
  return stopPaths
111
131
  }
112
132
 
133
+ function importArguments (config, args) {
134
+ for (const [argName, configKey] of Object.entries(config._argv)) {
135
+ const argVal = args[argName]
136
+ if (argVal === undefined) continue
137
+ const argFormat = config.getSchema(configKey).format
138
+ let argValStr = argVal
139
+ if (argFormat === 'map' || argFormat === 'primitive-map') {
140
+ const dumpOpts = { condenseFlow: true, flowLevel: 0, noCompatMode: true, quotingType: '"' }
141
+ argValStr = yaml.dump(Array.isArray(argVal) ? argVal : [argVal], dumpOpts)
142
+ } else if (Array.isArray(argVal)) {
143
+ argValStr = argVal.join(',')
144
+ }
145
+ config.set(configKey, argValStr)
146
+ }
147
+ }
148
+
113
149
  function getDetails (playbook, absPlaybookPath) {
114
150
  if (playbook === absPlaybookPath) return ''
115
151
  return ` (${ospath.isAbsolute(playbook) ? '' : 'cwd: ' + process.cwd() + ', '}playbook: ${playbook})`
@@ -175,6 +175,11 @@ module.exports = {
175
175
  format: 'int',
176
176
  default: 1,
177
177
  },
178
+ fetch_depth: {
179
+ doc: 'Preferred number of commits to fetch from remote repository. 0 indicates full history.',
180
+ format: 'int',
181
+ default: 1,
182
+ },
178
183
  plugins: {
179
184
  credential_manager: {
180
185
  doc: 'A require request for a plugin to replace the built-in credential manager used by the git client.',
@@ -5,9 +5,10 @@ const json = require('json5')
5
5
  const toml = require('@iarna/toml')
6
6
  const yaml = require('js-yaml')
7
7
 
8
- const ARGS_SCANNER_RX = /(?:([^=,]+)|(?==))(?:,|$|=(|("|').*?\3|[^,]+)(?:,|$))/g
9
8
  const PRIMITIVE_TYPES = [Boolean, Number, String]
9
+ const COERCE_SCHEMA = yaml.FAILSAFE_SCHEMA
10
10
  const YAML_SCHEMA = yaml.CORE_SCHEMA.extend({ implicit: [yaml.types.merge] })
11
+ const YAML_PREFIX_RX = new RegExp('!!((?:auto|str|bool|int|float|seq|map)(?= )|null(?=$))(?: |$)')
11
12
 
12
13
  /**
13
14
  * A convict function wrapper that registers custom formats and parsers and
@@ -59,16 +60,23 @@ function registerFormats (convict) {
59
60
  coerce: (val, config, name) => {
60
61
  if (config == null) return val
61
62
  const accum = config.has(name) ? config.get(name) : {}
62
- let match
63
- ARGS_SCANNER_RX.lastIndex = 0
64
- while ((match = ARGS_SCANNER_RX.exec(val))) {
65
- const [, k, v = ''] = match
66
- if (!k) continue
63
+ const entries = yaml.load(val, { schema: COERCE_SCHEMA })
64
+ for (const entry of Array.isArray(entries) ? entries : [entries]) {
65
+ let k = entry
66
+ let v = ''
67
+ const equalsIdx = entry.indexOf('=')
68
+ if (~equalsIdx) {
69
+ if (!(k = entry.slice(0, equalsIdx))) continue
70
+ v = entry.slice(equalsIdx + 1)
71
+ }
67
72
  let parsed = v
68
- if (parsed && parsed !== '-') {
69
- try {
70
- parsed = yaml.load(v, { schema: yaml.CORE_SCHEMA })
71
- } catch {}
73
+ if (v) {
74
+ const match = v.match(YAML_PREFIX_RX)
75
+ if (match) {
76
+ try {
77
+ parsed = yaml.load(match[1] === 'auto' ? v.slice(7) : v, { schema: yaml.CORE_SCHEMA })
78
+ } catch {}
79
+ }
72
80
  }
73
81
  accum[k] = parsed
74
82
  }
@@ -91,20 +99,26 @@ function registerFormats (convict) {
91
99
  coerce: (val, config, name) => {
92
100
  if (config == null) return val
93
101
  const accum = config.has(name) ? config.get(name) : {}
94
- let match
95
- ARGS_SCANNER_RX.lastIndex = 0
96
- while ((match = ARGS_SCANNER_RX.exec(val))) {
97
- const [, k, v] = match
98
- if (k) {
99
- let parsed
100
- if (v && v !== '-') {
101
- parsed = yaml.load(v, { schema: yaml.CORE_SCHEMA })
102
- if (parsed && PRIMITIVE_TYPES.indexOf(parsed.constructor) < 0) parsed = v
103
- } else {
104
- parsed = v || ''
102
+ const entries = yaml.load(val, { schema: COERCE_SCHEMA })
103
+ for (const entry of Array.isArray(entries) ? entries : [entries]) {
104
+ let k = entry
105
+ let v = ''
106
+ const equalsIdx = entry.indexOf('=')
107
+ if (~equalsIdx) {
108
+ if (!(k = entry.slice(0, equalsIdx))) continue
109
+ v = entry.slice(equalsIdx + 1)
110
+ }
111
+ let parsed = v
112
+ if (v) {
113
+ const match = v.match(YAML_PREFIX_RX)
114
+ if (match) {
115
+ try {
116
+ parsed = yaml.load(match[1] === 'auto' ? v.slice(7) : v, { schema: yaml.CORE_SCHEMA })
117
+ if (parsed && !~PRIMITIVE_TYPES.indexOf(parsed.constructor)) parsed = v
118
+ } catch {}
105
119
  }
106
- accum[~k.indexOf('-') ? k.replace(/-/g, '_') : k] = parsed
107
120
  }
121
+ accum[~k.indexOf('-') ? k.replace(/-/g, '_') : k] = parsed
108
122
  }
109
123
  return accum
110
124
  },
@@ -112,7 +126,7 @@ function registerFormats (convict) {
112
126
  convict.addFormat({
113
127
  name: 'require-array',
114
128
  validate: (val) => {
115
- if (!Array.isArray(val)) throw new Error('must be of type Array')
129
+ if (!Array.isArray(val)) throw new Error('must be an array')
116
130
  },
117
131
  coerce: (val, config, name) => {
118
132
  const accum = config?.has(name) ? config.get(name) : []
@@ -132,7 +146,7 @@ function registerFormats (convict) {
132
146
  name: 'boolean-or-string',
133
147
  validate: (val) => {
134
148
  if (!(val == null || val.constructor === String || val.constructor === Boolean)) {
135
- throw new Error('must be a boolean or string')
149
+ throw new Error('must be a boolean, string, or null')
136
150
  }
137
151
  },
138
152
  })
@@ -174,6 +188,10 @@ function registerFormats (convict) {
174
188
  }
175
189
  if (~parsedUrl.pathname.indexOf('%20')) throw new Error('pathname segment must not contain spaces')
176
190
  },
191
+ coerce: (val) => {
192
+ if (!val || val === '~') return null
193
+ return val.length > 1 && val.charAt(val.length - 1) === '/' ? val.slice(0, -1) : val
194
+ },
177
195
  })
178
196
  }
179
197
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/playbook-builder",
3
- "version": "3.1.14",
3
+ "version": "3.2.0-alpha.10",
4
4
  "description": "Builds a playbook object from user input for configuring successive documentation components in an Antora pipeline.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "OpenDevise Inc. (https://opendevise.com)",
@@ -12,7 +12,8 @@
12
12
  "homepage": "https://antora.org",
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://gitlab.com/antora/antora.git"
15
+ "url": "git+https://gitlab.com/antora/antora.git",
16
+ "directory": "packages/playbook-builder"
16
17
  },
17
18
  "bugs": {
18
19
  "url": "https://gitlab.com/antora/antora/issues"
@@ -29,10 +30,11 @@
29
30
  "@iarna/toml": "~2.2",
30
31
  "convict": "~6.2",
31
32
  "js-yaml": "~4.1",
32
- "json5": "~2.2"
33
+ "json5": "~2.2",
34
+ "yargs-parser": "~20.2"
33
35
  },
34
36
  "engines": {
35
- "node": ">=16.0.0"
37
+ "node": ">=18.0.0"
36
38
  },
37
39
  "files": [
38
40
  "lib/"
@@ -47,7 +49,7 @@
47
49
  ],
48
50
  "scripts": {
49
51
  "test": "_mocha",
50
- "prepublishOnly": "npx -y downdoc --prepublish",
51
- "postpublish": "npx -y downdoc --postpublish"
52
+ "prepublishOnly": "npx -y downdoc@latest --prepublish",
53
+ "postpublish": "npx -y downdoc@latest --postpublish"
52
54
  }
53
55
  }