@npmcli/template-oss 4.22.0 → 4.23.1
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/bin/apply.js +2 -5
- package/bin/check.js +2 -4
- package/bin/release-manager.js +1 -1
- package/bin/release-please.js +22 -18
- package/lib/apply/apply-files.js +14 -19
- package/lib/apply/apply-version.js +1 -5
- package/lib/apply/index.js +1 -4
- package/lib/check/check-apply.js +38 -38
- package/lib/check/check-changelog.js +1 -4
- package/lib/check/check-engines.js +5 -6
- package/lib/check/check-gitignore.js +14 -14
- package/lib/check/check-required.js +13 -15
- package/lib/check/check-unwanted.js +2 -3
- package/lib/check/index.js +9 -8
- package/lib/config.js +86 -35
- package/lib/content/SECURITY-md.hbs +1 -1
- package/lib/content/_job-release-integration-yml.hbs +2 -0
- package/lib/content/action-create-check-yml.hbs +1 -1
- package/lib/content/action-install-latest-npm-yml.hbs +1 -1
- package/lib/content/ci-release-yml.hbs +2 -2
- package/lib/content/eslintrc-js.hbs +4 -5
- package/lib/content/gitignore.hbs +0 -3
- package/lib/content/index.js +33 -32
- package/lib/content/package-json.hbs +12 -2
- package/lib/content/post-dependabot-yml.hbs +2 -3
- package/lib/content/prettier-js.hbs +6 -0
- package/lib/content/prettierignore.hbs +3 -0
- package/lib/index.js +3 -3
- package/lib/release/changelog.js +28 -31
- package/lib/release/node-workspace-format.js +12 -12
- package/lib/release/release-manager.js +61 -76
- package/lib/release/release-please.js +50 -58
- package/lib/release/util.js +11 -8
- package/lib/util/ci-versions.js +3 -3
- package/lib/util/dependabot.js +2 -2
- package/lib/util/files.js +25 -22
- package/lib/util/git.js +7 -4
- package/lib/util/gitignore.js +13 -11
- package/lib/util/has-package.js +7 -12
- package/lib/util/import-or-require.js +1 -1
- package/lib/util/json-diff.js +22 -21
- package/lib/util/merge.js +19 -16
- package/lib/util/output.js +8 -5
- package/lib/util/parser.js +77 -70
- package/lib/util/path.js +4 -4
- package/lib/util/template.js +11 -10
- package/package.json +12 -7
package/lib/util/has-package.js
CHANGED
|
@@ -39,16 +39,11 @@ const getSpecVersion = (spec, where) => {
|
|
|
39
39
|
return null
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const isVersion =
|
|
42
|
+
const isVersion = s => s instanceof semver.SemVer
|
|
43
43
|
|
|
44
44
|
// Returns whether the pkg has the dependency in a semver
|
|
45
45
|
// compatible version in one or more locationscccc
|
|
46
|
-
const hasPackage = (
|
|
47
|
-
pkg,
|
|
48
|
-
spec,
|
|
49
|
-
locations = installLocations,
|
|
50
|
-
path
|
|
51
|
-
) => {
|
|
46
|
+
const hasPackage = (pkg, spec, locations = installLocations, path) => {
|
|
52
47
|
const name = npa(spec).name
|
|
53
48
|
const requested = getSpecVersion(spec)
|
|
54
49
|
|
|
@@ -57,16 +52,16 @@ const hasPackage = (
|
|
|
57
52
|
}
|
|
58
53
|
|
|
59
54
|
const existingByLocation = locations
|
|
60
|
-
.map(
|
|
61
|
-
.filter(
|
|
62
|
-
.map(
|
|
55
|
+
.map(location => pkg[location])
|
|
56
|
+
.filter(deps => has(deps, name))
|
|
57
|
+
.map(deps => getSpecVersion(`${name}@${deps[name]}`, path))
|
|
63
58
|
.filter(Boolean)
|
|
64
59
|
|
|
65
|
-
return existingByLocation.some(
|
|
60
|
+
return existingByLocation.some(existing => {
|
|
66
61
|
if (existing === true) {
|
|
67
62
|
return true
|
|
68
63
|
}
|
|
69
|
-
switch ([existing, requested].map(
|
|
64
|
+
switch ([existing, requested].map(t => (isVersion(t) ? 'VER' : 'RNG')).join('-')) {
|
|
70
65
|
case `VER-VER`:
|
|
71
66
|
// two versions, use semver.eq to check equality
|
|
72
67
|
return semver.eq(existing, requested)
|
package/lib/util/json-diff.js
CHANGED
|
@@ -6,28 +6,29 @@ const j = (obj, replacer = null) => JSON.stringify(obj, replacer, 2)
|
|
|
6
6
|
|
|
7
7
|
// DELETE is a special string that will be the value of updated if it exists
|
|
8
8
|
// but should be deleted
|
|
9
|
-
const jsonDiff = (s1, s2, DELETE) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
const jsonDiff = (s1, s2, DELETE) =>
|
|
10
|
+
diff(s1, s2)
|
|
11
|
+
.map(({ op, path, value }) => {
|
|
12
|
+
// there could be cases where a whole object is reported
|
|
13
|
+
// as missing and the expected value does not need to show
|
|
14
|
+
// special DELETED values so filter those out here
|
|
15
|
+
const msgVal = j(value, (_, v) => (v === DELETE ? undefined : v))
|
|
16
|
+
const prev = j(get(s1, path))
|
|
17
|
+
const key = j(path.reduce((acc, p) => acc + (typeof p === 'number' ? `[${p}]` : `.${p}`)))
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const msg = (...args) => format('%s is %s, expected %s', ...args)
|
|
20
|
+
const AD = msg(key, 'missing', msgVal)
|
|
21
|
+
const RM = msg(key, prev, 'to be removed')
|
|
22
|
+
const UP = msg(key, prev, msgVal)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
if (op === 'replace') {
|
|
25
|
+
return value === DELETE ? RM : UP
|
|
26
|
+
} else if (op === 'add' && value !== DELETE) {
|
|
27
|
+
return AD
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.sort((a, b) => a.localeCompare(b))
|
|
32
|
+
.join('\n')
|
|
32
33
|
|
|
33
34
|
module.exports = jsonDiff
|
package/lib/util/merge.js
CHANGED
|
@@ -32,16 +32,17 @@ const mergeWith = (...args) => {
|
|
|
32
32
|
|
|
33
33
|
// Create a merge function that will run a set of customizer functions
|
|
34
34
|
const mergeWithCustomizers = (...customizers) => {
|
|
35
|
-
return (...objects) =>
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
return (...objects) =>
|
|
36
|
+
mergeWith({}, ...objects, (...args) => {
|
|
37
|
+
for (const customizer of customizers) {
|
|
38
|
+
const result = customizer(...args)
|
|
39
|
+
// undefined means the customizer will defer to the next one
|
|
40
|
+
// the default behavior of undefined in lodash is to merge
|
|
41
|
+
if (result !== undefined) {
|
|
42
|
+
return result
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
+
})
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
const customizers = {
|
|
@@ -52,14 +53,16 @@ const customizers = {
|
|
|
52
53
|
}
|
|
53
54
|
},
|
|
54
55
|
// Merge arrays if their key matches one of the passed in keys
|
|
55
|
-
mergeArrays:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
mergeArrays:
|
|
57
|
+
(...keys) =>
|
|
58
|
+
(value, srcValue, key) => {
|
|
59
|
+
if (Array.isArray(srcValue)) {
|
|
60
|
+
if (keys.includes(key)) {
|
|
61
|
+
return (Array.isArray(value) ? value : []).concat(srcValue)
|
|
62
|
+
}
|
|
63
|
+
return srcValue
|
|
59
64
|
}
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
},
|
|
65
|
+
},
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
module.exports = {
|
package/lib/util/output.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const indent = (v, i = 2) => {
|
|
2
2
|
if (Array.isArray(v)) {
|
|
3
|
-
return v.map(
|
|
3
|
+
return v.map(a => indent(a, i)).join('\n')
|
|
4
4
|
}
|
|
5
|
-
return v
|
|
5
|
+
return v
|
|
6
|
+
.toString()
|
|
7
|
+
.split('\n')
|
|
8
|
+
.map(l => ' '.repeat(i) + l)
|
|
9
|
+
.join('\n')
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
const output = () => {
|
|
@@ -15,13 +19,12 @@ const output = () => {
|
|
|
15
19
|
}
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
const outputProblems =
|
|
22
|
+
const outputProblems = problems => {
|
|
19
23
|
const o = output()
|
|
20
24
|
o.push('', 'Some problems were detected:')
|
|
21
25
|
o.sep()
|
|
22
26
|
for (const { title, body, solution } of problems) {
|
|
23
|
-
const [solutionTitle, ...solutionRest] = Array.isArray(solution)
|
|
24
|
-
? solution : [solution]
|
|
27
|
+
const [solutionTitle, ...solutionRest] = Array.isArray(solution) ? solution : [solution]
|
|
25
28
|
o.push(title, '', indent(body), '', `To correct it: ${solutionTitle}`)
|
|
26
29
|
if (solutionRest.length) {
|
|
27
30
|
o.push('', indent(solutionRest))
|
package/lib/util/parser.js
CHANGED
|
@@ -27,7 +27,7 @@ const traverse = (value, visit, keys = []) => {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
const fsOk =
|
|
30
|
+
const fsOk = code => error => {
|
|
31
31
|
if (error.code === 'ENOENT') {
|
|
32
32
|
return null
|
|
33
33
|
}
|
|
@@ -37,107 +37,114 @@ const fsOk = (code) => (error) => {
|
|
|
37
37
|
class Base {
|
|
38
38
|
static types = []
|
|
39
39
|
static header = 'This file is automatically added by {{ __NAME__ }}. Do not edit.'
|
|
40
|
-
comment =
|
|
40
|
+
comment = v => v
|
|
41
41
|
merge = false // supply a merge function which runs on prepare for certain types
|
|
42
42
|
DELETE = template.DELETE
|
|
43
43
|
|
|
44
|
-
constructor
|
|
44
|
+
constructor(target, source, options, fileOptions) {
|
|
45
45
|
this.target = target
|
|
46
46
|
this.source = source
|
|
47
47
|
this.options = options
|
|
48
48
|
this.fileOptions = fileOptions
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
header
|
|
51
|
+
header() {
|
|
52
52
|
if (typeof this.comment === 'function') {
|
|
53
53
|
return this.comment(this.template(this.constructor.header || ''))
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
clean
|
|
57
|
+
clean() {
|
|
58
58
|
if (this.fileOptions.clean) {
|
|
59
59
|
return fs.rm(this.target).catch(fsOk())
|
|
60
60
|
}
|
|
61
61
|
return null
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
read
|
|
64
|
+
read(s) {
|
|
65
65
|
if (Array.isArray(s)) {
|
|
66
66
|
return Promise.all(s.map(f => this.read(f)))
|
|
67
67
|
}
|
|
68
68
|
return fs.readFile(s, { encoding: 'utf-8' })
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
template
|
|
71
|
+
template(s) {
|
|
72
72
|
if (Array.isArray(s)) {
|
|
73
73
|
return Promise.all(s.map(f => this.template(f)))
|
|
74
74
|
}
|
|
75
75
|
return template(s, this.options)
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
parse
|
|
78
|
+
parse(s) {
|
|
79
79
|
return s
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
prepare
|
|
82
|
+
prepare(s) {
|
|
83
83
|
const header = this.header()
|
|
84
84
|
return header ? `${header}\n\n${s}` : s
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
prepareTarget
|
|
87
|
+
prepareTarget(s) {
|
|
88
88
|
return s
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
toString
|
|
91
|
+
toString(s) {
|
|
92
92
|
return s.toString()
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
async write
|
|
95
|
+
async write(s) {
|
|
96
96
|
// XXX: find more efficient way to do this. we can build all possible dirs before get here
|
|
97
97
|
await fs.mkdir(dirname(this.target), { owner: 'inherit', recursive: true, force: true })
|
|
98
98
|
return fs.writeFile(this.target, this.toString(s), { owner: 'inherit' })
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
diffPatch
|
|
101
|
+
diffPatch(t, s) {
|
|
102
102
|
// create a patch and strip out the filename. if it ends up an empty string
|
|
103
103
|
// then return true since the files are equal
|
|
104
|
-
return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n'))
|
|
105
|
-
.split('\n').slice(4).join('\n')
|
|
104
|
+
return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n')).split('\n').slice(4).join('\n')
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
diff
|
|
107
|
+
diff(t, s) {
|
|
109
108
|
return this.diffPatch(t, s)
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
// the apply methods are the only ones that should be called publically
|
|
113
112
|
// XXX: everything is allowed to be overridden in base classes but we could
|
|
114
113
|
// find a different solution than making everything public
|
|
115
|
-
applyWrite
|
|
116
|
-
return
|
|
117
|
-
.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
114
|
+
applyWrite() {
|
|
115
|
+
return (
|
|
116
|
+
Promise.resolve(this.clean())
|
|
117
|
+
.then(() => this.read(this.source))
|
|
118
|
+
// replace template vars first, this will throw for nonexistant vars
|
|
119
|
+
// because it must be parseable after this step
|
|
120
|
+
.then(s => this.template(s))
|
|
121
|
+
// parse into whatever data structure is necessary for maniuplating
|
|
122
|
+
// diffing, merging, etc. by default its a string
|
|
123
|
+
.then(s => {
|
|
124
|
+
this.sourcePreParse = s
|
|
125
|
+
return this.parse(s)
|
|
126
|
+
})
|
|
127
|
+
// prepare the source for writing and diffing, pass in current
|
|
128
|
+
// target for merging. errors parsing or preparing targets are ok here
|
|
129
|
+
.then(s =>
|
|
130
|
+
this.applyTarget()
|
|
131
|
+
.catch(() => null)
|
|
132
|
+
.then(t => this.prepare(s, t)),
|
|
133
|
+
)
|
|
134
|
+
.then(s => this.write(s))
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
applyTarget() {
|
|
139
|
+
return (
|
|
140
|
+
Promise.resolve(this.read(this.target))
|
|
141
|
+
.then(s => this.parse(s))
|
|
142
|
+
// for only preparing the target for diffing
|
|
143
|
+
.then(s => this.prepareTarget(s))
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async applyDiff() {
|
|
141
148
|
// handle if old does not exist
|
|
142
149
|
const targetError = 'ETARGETERROR'
|
|
143
150
|
const target = await this.applyTarget().catch(fsOk(targetError))
|
|
@@ -148,10 +155,10 @@ class Base {
|
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
const source = await Promise.resolve(this.read(this.source))
|
|
151
|
-
.then(
|
|
152
|
-
.then(
|
|
158
|
+
.then(s => this.template(s))
|
|
159
|
+
.then(s => this.parse(s))
|
|
153
160
|
// gets the target to diff against in case it needs to merge, etc
|
|
154
|
-
.then(
|
|
161
|
+
.then(s => this.prepare(s, target))
|
|
155
162
|
|
|
156
163
|
// if there was a target error then there is no need to diff
|
|
157
164
|
// so we just show the source with an error message
|
|
@@ -174,28 +181,28 @@ class Base {
|
|
|
174
181
|
}
|
|
175
182
|
|
|
176
183
|
class Gitignore extends Base {
|
|
177
|
-
static types = ['codeowners', '.gitignore']
|
|
178
|
-
comment =
|
|
184
|
+
static types = ['codeowners', '.gitignore', '.prettierignore']
|
|
185
|
+
comment = c => `# ${c}`
|
|
179
186
|
}
|
|
180
187
|
|
|
181
188
|
class Js extends Base {
|
|
182
189
|
static types = ['*.js', '*.cjs']
|
|
183
|
-
comment =
|
|
190
|
+
comment = c => `/* ${c} */`
|
|
184
191
|
}
|
|
185
192
|
|
|
186
193
|
class Ini extends Base {
|
|
187
194
|
static types = ['*.ini']
|
|
188
|
-
comment =
|
|
195
|
+
comment = c => `; ${c}`
|
|
189
196
|
|
|
190
|
-
toString
|
|
197
|
+
toString(s) {
|
|
191
198
|
return typeof s === 'string' ? s : ini.stringify(s)
|
|
192
199
|
}
|
|
193
200
|
|
|
194
|
-
parse
|
|
201
|
+
parse(s) {
|
|
195
202
|
return typeof s === 'string' ? ini.parse(s) : s
|
|
196
203
|
}
|
|
197
204
|
|
|
198
|
-
prepare
|
|
205
|
+
prepare(s, t) {
|
|
199
206
|
let source = s
|
|
200
207
|
if (typeof this.merge === 'function' && t) {
|
|
201
208
|
source = this.merge(t, s)
|
|
@@ -203,7 +210,7 @@ class Ini extends Base {
|
|
|
203
210
|
return super.prepare(this.toString(source))
|
|
204
211
|
}
|
|
205
212
|
|
|
206
|
-
diff
|
|
213
|
+
diff(t, s) {
|
|
207
214
|
return jsonDiff(this.parse(t), this.parse(s), this.DELETE)
|
|
208
215
|
}
|
|
209
216
|
}
|
|
@@ -215,14 +222,14 @@ class IniMerge extends Ini {
|
|
|
215
222
|
|
|
216
223
|
class Markdown extends Base {
|
|
217
224
|
static types = ['*.md']
|
|
218
|
-
comment =
|
|
225
|
+
comment = c => `<!-- ${c} -->`
|
|
219
226
|
}
|
|
220
227
|
|
|
221
228
|
class Yml extends Base {
|
|
222
229
|
static types = ['*.yml']
|
|
223
|
-
comment =
|
|
230
|
+
comment = c => ` ${c}`
|
|
224
231
|
|
|
225
|
-
toString
|
|
232
|
+
toString(s) {
|
|
226
233
|
try {
|
|
227
234
|
return s.toString({ lineWidth: 0, indent: 2 })
|
|
228
235
|
} catch (err) {
|
|
@@ -231,22 +238,22 @@ class Yml extends Base {
|
|
|
231
238
|
}
|
|
232
239
|
}
|
|
233
240
|
|
|
234
|
-
parse
|
|
241
|
+
parse(s) {
|
|
235
242
|
return yaml.parseDocument(s)
|
|
236
243
|
}
|
|
237
244
|
|
|
238
|
-
prepare
|
|
245
|
+
prepare(s) {
|
|
239
246
|
s.commentBefore = this.header()
|
|
240
247
|
return this.toString(s)
|
|
241
248
|
}
|
|
242
249
|
|
|
243
|
-
prepareTarget
|
|
250
|
+
prepareTarget(s) {
|
|
244
251
|
return this.toString(s)
|
|
245
252
|
}
|
|
246
253
|
}
|
|
247
254
|
|
|
248
255
|
class YmlMerge extends Yml {
|
|
249
|
-
prepare
|
|
256
|
+
prepare(source, t) {
|
|
250
257
|
if (t === null) {
|
|
251
258
|
// If target does not exist or is in an
|
|
252
259
|
// error state, we cant do anything but write
|
|
@@ -256,7 +263,7 @@ class YmlMerge extends Yml {
|
|
|
256
263
|
|
|
257
264
|
const key = [].concat(this.key)
|
|
258
265
|
|
|
259
|
-
const getId =
|
|
266
|
+
const getId = node => {
|
|
260
267
|
const index = node.items.findIndex(p => p.key?.value === this.id)
|
|
261
268
|
return index !== -1 ? node.items[index].value?.value : node.toJSON()
|
|
262
269
|
}
|
|
@@ -284,20 +291,20 @@ class Json extends Base {
|
|
|
284
291
|
static types = ['*.json']
|
|
285
292
|
// its a json comment! not really but we do add a special key
|
|
286
293
|
// to json objects
|
|
287
|
-
comment =
|
|
294
|
+
comment = c => ({ [`//${this.options.config.__NAME__}`]: c })
|
|
288
295
|
|
|
289
|
-
toString
|
|
290
|
-
return JSON.stringify(s, (_, v) => v === this.DELETE ? undefined : v, 2).trim() + '\n'
|
|
296
|
+
toString(s) {
|
|
297
|
+
return JSON.stringify(s, (_, v) => (v === this.DELETE ? undefined : v), 2).trim() + '\n'
|
|
291
298
|
}
|
|
292
299
|
|
|
293
|
-
parse
|
|
300
|
+
parse(s) {
|
|
294
301
|
if (Array.isArray(s)) {
|
|
295
302
|
return s.map(f => this.parse(f)).reduce((a, f) => this.merge(a, f), {})
|
|
296
303
|
}
|
|
297
304
|
return jsonParse(s)
|
|
298
305
|
}
|
|
299
306
|
|
|
300
|
-
prepare
|
|
307
|
+
prepare(s, t) {
|
|
301
308
|
let source = s
|
|
302
309
|
if (typeof this.merge === 'function' && t) {
|
|
303
310
|
source = this.merge(t, s)
|
|
@@ -305,7 +312,7 @@ class Json extends Base {
|
|
|
305
312
|
return setFirst(this.header(), source)
|
|
306
313
|
}
|
|
307
314
|
|
|
308
|
-
diff
|
|
315
|
+
diff(t, s) {
|
|
309
316
|
return jsonDiff(t, s, this.DELETE)
|
|
310
317
|
}
|
|
311
318
|
}
|
|
@@ -322,7 +329,7 @@ class JsonMergeNoComment extends JsonMerge {
|
|
|
322
329
|
class PackageJson extends JsonMerge {
|
|
323
330
|
static types = ['package.json']
|
|
324
331
|
|
|
325
|
-
async prepare
|
|
332
|
+
async prepare(s, t) {
|
|
326
333
|
// merge new source with current pkg content
|
|
327
334
|
const update = super.prepare(s, t)
|
|
328
335
|
|
|
@@ -336,7 +343,7 @@ class PackageJson extends JsonMerge {
|
|
|
336
343
|
return update
|
|
337
344
|
}
|
|
338
345
|
|
|
339
|
-
async write
|
|
346
|
+
async write(s) {
|
|
340
347
|
const pkg = await NpmPackageJson.load(dirname(this.target))
|
|
341
348
|
pkg.update(s)
|
|
342
349
|
traverse(pkg.content, (keys, value) => {
|
|
@@ -378,7 +385,7 @@ for (const parser of Object.values(Parsers)) {
|
|
|
378
385
|
}
|
|
379
386
|
}
|
|
380
387
|
|
|
381
|
-
const getParser =
|
|
388
|
+
const getParser = file => {
|
|
382
389
|
for (const [type, parser] of parserLookup) {
|
|
383
390
|
if (minimatch(file, type, { nocase: true, dot: true, matchBase: true })) {
|
|
384
391
|
return parser
|
package/lib/util/path.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const { posix, win32 } = require('path')
|
|
2
2
|
|
|
3
|
-
const makePosix =
|
|
4
|
-
const deglob =
|
|
5
|
-
const posixDir =
|
|
6
|
-
const posixGlob =
|
|
3
|
+
const makePosix = v => v.split(win32.sep).join(posix.sep)
|
|
4
|
+
const deglob = v => makePosix(v).replace(/[/*]+$/, '')
|
|
5
|
+
const posixDir = v => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
|
|
6
|
+
const posixGlob = str => `${posixDir(str)}**`
|
|
7
7
|
|
|
8
8
|
module.exports = {
|
|
9
9
|
makePosix,
|
package/lib/util/template.js
CHANGED
|
@@ -4,12 +4,12 @@ const { Range } = require('semver')
|
|
|
4
4
|
const fs = require('fs')
|
|
5
5
|
const DELETE = '__DELETE__'
|
|
6
6
|
|
|
7
|
-
const safeValues =
|
|
8
|
-
[key, new Handlebars.SafeString(value)])
|
|
7
|
+
const safeValues = obj => Object.entries(obj).map(([key, value]) => [key, new Handlebars.SafeString(value)])
|
|
9
8
|
|
|
10
|
-
const partialName =
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const partialName = s =>
|
|
10
|
+
basename(s, extname(s)) // remove extension
|
|
11
|
+
.replace(/^_/, '') // remove leading underscore
|
|
12
|
+
.replace(/-([a-z])/g, (_, g) => g.toUpperCase()) // camelcase
|
|
13
13
|
|
|
14
14
|
const makePartials = (dir, isBase) => {
|
|
15
15
|
const partials = fs.readdirSync(dir).reduce((acc, f) => {
|
|
@@ -32,15 +32,16 @@ const makePartials = (dir, isBase) => {
|
|
|
32
32
|
Handlebars.registerPartial(partials)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const setupHandlebars =
|
|
35
|
+
const setupHandlebars = dirs => {
|
|
36
36
|
Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
|
|
37
|
+
Handlebars.registerHelper('extGlob', arr => `{${arr.join(',')}}`)
|
|
37
38
|
Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
|
|
38
39
|
Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
|
|
39
|
-
Handlebars.registerHelper('quote',
|
|
40
|
-
Handlebars.registerHelper('last',
|
|
41
|
-
Handlebars.registerHelper('json',
|
|
40
|
+
Handlebars.registerHelper('quote', arr => arr.map(a => `'${a}'`))
|
|
41
|
+
Handlebars.registerHelper('last', arr => arr[arr.length - 1])
|
|
42
|
+
Handlebars.registerHelper('json', c => JSON.stringify(c))
|
|
42
43
|
Handlebars.registerHelper('del', () => JSON.stringify(DELETE))
|
|
43
|
-
Handlebars.registerHelper('semverRangeMajor',
|
|
44
|
+
Handlebars.registerHelper('semverRangeMajor', v => new Range(v).set[0][0].semver.major)
|
|
44
45
|
Handlebars.registerHelper('lte', (a, b) => a <= b)
|
|
45
46
|
|
|
46
47
|
if (Array.isArray(dirs)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/template-oss",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.23.1",
|
|
4
4
|
"description": "templated files used in npm CLI team oss projects",
|
|
5
5
|
"main": "lib/content/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,17 +10,18 @@
|
|
|
10
10
|
"template-oss-release-manager": "bin/release-manager.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"lint": "eslint
|
|
14
|
-
"lintfix": "npm run
|
|
13
|
+
"lint": "npm run eslint && npm run prettier -- --check",
|
|
14
|
+
"lintfix": "npm run eslint -- --fix && npm run prettier -- --write",
|
|
15
15
|
"posttest": "npm run lint",
|
|
16
16
|
"snap": "tap",
|
|
17
17
|
"test": "tap",
|
|
18
18
|
"template-oss-apply": "template-oss-apply --force",
|
|
19
19
|
"postlint": "template-oss-check",
|
|
20
20
|
"postinstall": "template-oss-apply",
|
|
21
|
+
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
|
|
22
|
+
"prettier": "prettier \"**/*.{js,cjs,ts,mjs,jsx,tsx,json}\"",
|
|
21
23
|
"test-all": "npm run test -ws -iwr --if-present",
|
|
22
|
-
"lint-all": "npm run lint -ws -iwr --if-present"
|
|
23
|
-
"test:record": "TAP_SNAPSHOT=1 NOCK_RECORD=1 tap"
|
|
24
|
+
"lint-all": "npm run lint -ws -iwr --if-present"
|
|
24
25
|
},
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"minimatch": "^9.0.2",
|
|
57
58
|
"npm-package-arg": "^11.0.1",
|
|
58
59
|
"proc-log": "^4.0.0",
|
|
59
|
-
"release-please": "16.
|
|
60
|
+
"release-please": "16.12.0",
|
|
60
61
|
"semver": "^7.3.5",
|
|
61
62
|
"undici": "^6.7.0",
|
|
62
63
|
"yaml": "^2.1.1"
|
|
@@ -66,9 +67,12 @@
|
|
|
66
67
|
"lib/"
|
|
67
68
|
],
|
|
68
69
|
"devDependencies": {
|
|
70
|
+
"@github/prettier-config": "0.0.6",
|
|
69
71
|
"@npmcli/eslint-config": "^4.0.0",
|
|
70
72
|
"@npmcli/template-oss": "file:./",
|
|
73
|
+
"eslint-config-prettier": "^9.1.0",
|
|
71
74
|
"nock": "^13.3.8",
|
|
75
|
+
"prettier": "^3.2.5",
|
|
72
76
|
"tap": "^16.0.0"
|
|
73
77
|
},
|
|
74
78
|
"tap": {
|
|
@@ -86,7 +90,8 @@
|
|
|
86
90
|
},
|
|
87
91
|
"templateOSS": {
|
|
88
92
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
89
|
-
"publish": true
|
|
93
|
+
"publish": true,
|
|
94
|
+
"prettier": true
|
|
90
95
|
},
|
|
91
96
|
"engines": {
|
|
92
97
|
"node": "^18.17.0 || >=20.5.0"
|