@antora/playbook-builder 3.2.0-alpha.6 → 3.2.0-alpha.9
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/lib/build-playbook.js +44 -8
- package/lib/solitary-convict.js +44 -27
- package/package.json +8 -3
package/lib/build-playbook.js
CHANGED
|
@@ -4,6 +4,8 @@ const convict = require('./solitary-convict')
|
|
|
4
4
|
const defaultSchema = require('./config/schema')
|
|
5
5
|
const fs = require('node:fs')
|
|
6
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('node: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
|
|
32
|
-
const
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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})`
|
package/lib/solitary-convict.js
CHANGED
|
@@ -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
|
|
@@ -51,16 +52,23 @@ function registerFormats (convict) {
|
|
|
51
52
|
coerce: (val, config, name) => {
|
|
52
53
|
if (config == null) return val
|
|
53
54
|
const accum = config.has(name) ? config.get(name) : {}
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const entries = yaml.load(val, { schema: COERCE_SCHEMA })
|
|
56
|
+
for (const entry of Array.isArray(entries) ? entries : [entries]) {
|
|
57
|
+
let k = entry
|
|
58
|
+
let v = ''
|
|
59
|
+
const equalsIdx = entry.indexOf('=')
|
|
60
|
+
if (~equalsIdx) {
|
|
61
|
+
if (!(k = entry.slice(0, equalsIdx))) continue
|
|
62
|
+
v = entry.slice(equalsIdx + 1)
|
|
63
|
+
}
|
|
59
64
|
let parsed = v
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
if (v) {
|
|
66
|
+
const match = v.match(YAML_PREFIX_RX)
|
|
67
|
+
if (match) {
|
|
68
|
+
try {
|
|
69
|
+
parsed = yaml.load(match[1] === 'auto' ? v.slice(7) : v, { schema: yaml.CORE_SCHEMA })
|
|
70
|
+
} catch {}
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
73
|
accum[k] = parsed
|
|
66
74
|
}
|
|
@@ -83,20 +91,26 @@ function registerFormats (convict) {
|
|
|
83
91
|
coerce: (val, config, name) => {
|
|
84
92
|
if (config == null) return val
|
|
85
93
|
const accum = config.has(name) ? config.get(name) : {}
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
const entries = yaml.load(val, { schema: COERCE_SCHEMA })
|
|
95
|
+
for (const entry of Array.isArray(entries) ? entries : [entries]) {
|
|
96
|
+
let k = entry
|
|
97
|
+
let v = ''
|
|
98
|
+
const equalsIdx = entry.indexOf('=')
|
|
99
|
+
if (~equalsIdx) {
|
|
100
|
+
if (!(k = entry.slice(0, equalsIdx))) continue
|
|
101
|
+
v = entry.slice(equalsIdx + 1)
|
|
102
|
+
}
|
|
103
|
+
let parsed = v
|
|
104
|
+
if (v) {
|
|
105
|
+
const match = v.match(YAML_PREFIX_RX)
|
|
106
|
+
if (match) {
|
|
107
|
+
try {
|
|
108
|
+
parsed = yaml.load(match[1] === 'auto' ? v.slice(7) : v, { schema: yaml.CORE_SCHEMA })
|
|
109
|
+
if (parsed && !~PRIMITIVE_TYPES.indexOf(parsed.constructor)) parsed = v
|
|
110
|
+
} catch {}
|
|
97
111
|
}
|
|
98
|
-
accum[~k.indexOf('-') ? k.replace(/-/g, '_') : k] = parsed
|
|
99
112
|
}
|
|
113
|
+
accum[~k.indexOf('-') ? k.replace(/-/g, '_') : k] = parsed
|
|
100
114
|
}
|
|
101
115
|
return accum
|
|
102
116
|
},
|
|
@@ -107,16 +121,16 @@ function registerFormats (convict) {
|
|
|
107
121
|
if (!Array.isArray(val)) throw new Error('must be an array')
|
|
108
122
|
},
|
|
109
123
|
coerce: (val, config, name) => {
|
|
110
|
-
const accum = config
|
|
111
|
-
val.split(',')
|
|
112
|
-
if (~accum.indexOf(v))
|
|
124
|
+
const accum = config?.has(name) ? config.get(name) : []
|
|
125
|
+
for (const v of val.split(',')) {
|
|
126
|
+
if (~accum.indexOf(v)) continue
|
|
113
127
|
const match = accum.find((it) => it.constructor === Object && it.id === v)
|
|
114
128
|
if (match) {
|
|
115
129
|
if (match.enabled === false) match.enabled = true
|
|
116
130
|
} else {
|
|
117
131
|
accum.push(v)
|
|
118
132
|
}
|
|
119
|
-
}
|
|
133
|
+
}
|
|
120
134
|
return accum
|
|
121
135
|
},
|
|
122
136
|
})
|
|
@@ -166,7 +180,10 @@ function registerFormats (convict) {
|
|
|
166
180
|
}
|
|
167
181
|
if (~parsedUrl.pathname.indexOf('%20')) throw new Error('pathname segment must not contain spaces')
|
|
168
182
|
},
|
|
169
|
-
coerce: (val) =>
|
|
183
|
+
coerce: (val) => {
|
|
184
|
+
if (!val || val === '~') return null
|
|
185
|
+
return val.length > 1 && val.charAt(val.length - 1) === '/' ? val.slice(0, -1) : val
|
|
186
|
+
},
|
|
170
187
|
})
|
|
171
188
|
}
|
|
172
189
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/playbook-builder",
|
|
3
|
-
"version": "3.2.0-alpha.
|
|
3
|
+
"version": "3.2.0-alpha.9",
|
|
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)",
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
"Hubert SABLONNIÈRE <hubert.sablonniere@gmail.com>"
|
|
11
11
|
],
|
|
12
12
|
"homepage": "https://antora.org",
|
|
13
|
-
"repository":
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://gitlab.com/antora/antora.git",
|
|
16
|
+
"directory": "packages/playbook-builder"
|
|
17
|
+
},
|
|
14
18
|
"bugs": {
|
|
15
19
|
"url": "https://gitlab.com/antora/antora/issues"
|
|
16
20
|
},
|
|
@@ -26,7 +30,8 @@
|
|
|
26
30
|
"@iarna/toml": "~2.2",
|
|
27
31
|
"convict": "~6.2",
|
|
28
32
|
"js-yaml": "~4.1",
|
|
29
|
-
"json5": "~2.2"
|
|
33
|
+
"json5": "~2.2",
|
|
34
|
+
"yargs-parser": "~20.2"
|
|
30
35
|
},
|
|
31
36
|
"engines": {
|
|
32
37
|
"node": ">=18.0.0"
|