@npmcli/template-oss 4.21.4 → 4.23.0
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 -39
- 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/LICENSE-md.hbs +2 -2
- package/lib/content/_job-matrix-yml.hbs +10 -0
- package/lib/content/_job-release-integration-yml.hbs +5 -10
- package/lib/content/_step-git-yml.hbs +1 -1
- package/lib/content/_step-node-yml.hbs +1 -1
- package/lib/content/action-create-check-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 +39 -38
- package/lib/content/package-json.hbs +12 -2
- package/lib/content/prettier-js.hbs +6 -0
- package/lib/content/prettierignore.hbs +3 -0
- package/lib/content/release-yml.hbs +3 -3
- package/lib/index.js +3 -3
- package/lib/release/changelog.js +41 -44
- package/lib/release/node-workspace-format.js +29 -16
- package/lib/release/release-manager.js +61 -76
- package/lib/release/release-please.js +50 -61
- 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 +34 -32
- package/lib/util/git.js +8 -5
- 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 +86 -70
- package/lib/util/path.js +4 -4
- package/lib/util/template.js +13 -9
- package/package.json +13 -8
- package/lib/release/node-workspace.js +0 -103
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,101 +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
|
+
if (Array.isArray(s)) {
|
|
66
|
+
return Promise.all(s.map(f => this.read(f)))
|
|
67
|
+
}
|
|
65
68
|
return fs.readFile(s, { encoding: 'utf-8' })
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
template
|
|
71
|
+
template(s) {
|
|
72
|
+
if (Array.isArray(s)) {
|
|
73
|
+
return Promise.all(s.map(f => this.template(f)))
|
|
74
|
+
}
|
|
69
75
|
return template(s, this.options)
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
parse
|
|
78
|
+
parse(s) {
|
|
73
79
|
return s
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
prepare
|
|
82
|
+
prepare(s) {
|
|
77
83
|
const header = this.header()
|
|
78
84
|
return header ? `${header}\n\n${s}` : s
|
|
79
85
|
}
|
|
80
86
|
|
|
81
|
-
prepareTarget
|
|
87
|
+
prepareTarget(s) {
|
|
82
88
|
return s
|
|
83
89
|
}
|
|
84
90
|
|
|
85
|
-
toString
|
|
91
|
+
toString(s) {
|
|
86
92
|
return s.toString()
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
async write
|
|
95
|
+
async write(s) {
|
|
90
96
|
// XXX: find more efficient way to do this. we can build all possible dirs before get here
|
|
91
97
|
await fs.mkdir(dirname(this.target), { owner: 'inherit', recursive: true, force: true })
|
|
92
98
|
return fs.writeFile(this.target, this.toString(s), { owner: 'inherit' })
|
|
93
99
|
}
|
|
94
100
|
|
|
95
|
-
diffPatch
|
|
101
|
+
diffPatch(t, s) {
|
|
96
102
|
// create a patch and strip out the filename. if it ends up an empty string
|
|
97
103
|
// then return true since the files are equal
|
|
98
|
-
return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n'))
|
|
99
|
-
.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')
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
diff
|
|
107
|
+
diff(t, s) {
|
|
103
108
|
return this.diffPatch(t, s)
|
|
104
109
|
}
|
|
105
110
|
|
|
106
111
|
// the apply methods are the only ones that should be called publically
|
|
107
112
|
// XXX: everything is allowed to be overridden in base classes but we could
|
|
108
113
|
// find a different solution than making everything public
|
|
109
|
-
applyWrite
|
|
110
|
-
return
|
|
111
|
-
.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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() {
|
|
135
148
|
// handle if old does not exist
|
|
136
149
|
const targetError = 'ETARGETERROR'
|
|
137
150
|
const target = await this.applyTarget().catch(fsOk(targetError))
|
|
@@ -142,10 +155,10 @@ class Base {
|
|
|
142
155
|
}
|
|
143
156
|
|
|
144
157
|
const source = await Promise.resolve(this.read(this.source))
|
|
145
|
-
.then(
|
|
146
|
-
.then(
|
|
158
|
+
.then(s => this.template(s))
|
|
159
|
+
.then(s => this.parse(s))
|
|
147
160
|
// gets the target to diff against in case it needs to merge, etc
|
|
148
|
-
.then(
|
|
161
|
+
.then(s => this.prepare(s, target))
|
|
149
162
|
|
|
150
163
|
// if there was a target error then there is no need to diff
|
|
151
164
|
// so we just show the source with an error message
|
|
@@ -168,28 +181,28 @@ class Base {
|
|
|
168
181
|
}
|
|
169
182
|
|
|
170
183
|
class Gitignore extends Base {
|
|
171
|
-
static types = ['codeowners', '.gitignore']
|
|
172
|
-
comment =
|
|
184
|
+
static types = ['codeowners', '.gitignore', '.prettierignore']
|
|
185
|
+
comment = c => `# ${c}`
|
|
173
186
|
}
|
|
174
187
|
|
|
175
188
|
class Js extends Base {
|
|
176
189
|
static types = ['*.js', '*.cjs']
|
|
177
|
-
comment =
|
|
190
|
+
comment = c => `/* ${c} */`
|
|
178
191
|
}
|
|
179
192
|
|
|
180
193
|
class Ini extends Base {
|
|
181
194
|
static types = ['*.ini']
|
|
182
|
-
comment =
|
|
195
|
+
comment = c => `; ${c}`
|
|
183
196
|
|
|
184
|
-
toString
|
|
197
|
+
toString(s) {
|
|
185
198
|
return typeof s === 'string' ? s : ini.stringify(s)
|
|
186
199
|
}
|
|
187
200
|
|
|
188
|
-
parse
|
|
201
|
+
parse(s) {
|
|
189
202
|
return typeof s === 'string' ? ini.parse(s) : s
|
|
190
203
|
}
|
|
191
204
|
|
|
192
|
-
prepare
|
|
205
|
+
prepare(s, t) {
|
|
193
206
|
let source = s
|
|
194
207
|
if (typeof this.merge === 'function' && t) {
|
|
195
208
|
source = this.merge(t, s)
|
|
@@ -197,7 +210,7 @@ class Ini extends Base {
|
|
|
197
210
|
return super.prepare(this.toString(source))
|
|
198
211
|
}
|
|
199
212
|
|
|
200
|
-
diff
|
|
213
|
+
diff(t, s) {
|
|
201
214
|
return jsonDiff(this.parse(t), this.parse(s), this.DELETE)
|
|
202
215
|
}
|
|
203
216
|
}
|
|
@@ -209,14 +222,14 @@ class IniMerge extends Ini {
|
|
|
209
222
|
|
|
210
223
|
class Markdown extends Base {
|
|
211
224
|
static types = ['*.md']
|
|
212
|
-
comment =
|
|
225
|
+
comment = c => `<!-- ${c} -->`
|
|
213
226
|
}
|
|
214
227
|
|
|
215
228
|
class Yml extends Base {
|
|
216
229
|
static types = ['*.yml']
|
|
217
|
-
comment =
|
|
230
|
+
comment = c => ` ${c}`
|
|
218
231
|
|
|
219
|
-
toString
|
|
232
|
+
toString(s) {
|
|
220
233
|
try {
|
|
221
234
|
return s.toString({ lineWidth: 0, indent: 2 })
|
|
222
235
|
} catch (err) {
|
|
@@ -225,22 +238,22 @@ class Yml extends Base {
|
|
|
225
238
|
}
|
|
226
239
|
}
|
|
227
240
|
|
|
228
|
-
parse
|
|
241
|
+
parse(s) {
|
|
229
242
|
return yaml.parseDocument(s)
|
|
230
243
|
}
|
|
231
244
|
|
|
232
|
-
prepare
|
|
245
|
+
prepare(s) {
|
|
233
246
|
s.commentBefore = this.header()
|
|
234
247
|
return this.toString(s)
|
|
235
248
|
}
|
|
236
249
|
|
|
237
|
-
prepareTarget
|
|
250
|
+
prepareTarget(s) {
|
|
238
251
|
return this.toString(s)
|
|
239
252
|
}
|
|
240
253
|
}
|
|
241
254
|
|
|
242
255
|
class YmlMerge extends Yml {
|
|
243
|
-
prepare
|
|
256
|
+
prepare(source, t) {
|
|
244
257
|
if (t === null) {
|
|
245
258
|
// If target does not exist or is in an
|
|
246
259
|
// error state, we cant do anything but write
|
|
@@ -250,7 +263,7 @@ class YmlMerge extends Yml {
|
|
|
250
263
|
|
|
251
264
|
const key = [].concat(this.key)
|
|
252
265
|
|
|
253
|
-
const getId =
|
|
266
|
+
const getId = node => {
|
|
254
267
|
const index = node.items.findIndex(p => p.key?.value === this.id)
|
|
255
268
|
return index !== -1 ? node.items[index].value?.value : node.toJSON()
|
|
256
269
|
}
|
|
@@ -278,17 +291,20 @@ class Json extends Base {
|
|
|
278
291
|
static types = ['*.json']
|
|
279
292
|
// its a json comment! not really but we do add a special key
|
|
280
293
|
// to json objects
|
|
281
|
-
comment =
|
|
294
|
+
comment = c => ({ [`//${this.options.config.__NAME__}`]: c })
|
|
282
295
|
|
|
283
|
-
toString
|
|
284
|
-
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'
|
|
285
298
|
}
|
|
286
299
|
|
|
287
|
-
parse
|
|
300
|
+
parse(s) {
|
|
301
|
+
if (Array.isArray(s)) {
|
|
302
|
+
return s.map(f => this.parse(f)).reduce((a, f) => this.merge(a, f), {})
|
|
303
|
+
}
|
|
288
304
|
return jsonParse(s)
|
|
289
305
|
}
|
|
290
306
|
|
|
291
|
-
prepare
|
|
307
|
+
prepare(s, t) {
|
|
292
308
|
let source = s
|
|
293
309
|
if (typeof this.merge === 'function' && t) {
|
|
294
310
|
source = this.merge(t, s)
|
|
@@ -296,7 +312,7 @@ class Json extends Base {
|
|
|
296
312
|
return setFirst(this.header(), source)
|
|
297
313
|
}
|
|
298
314
|
|
|
299
|
-
diff
|
|
315
|
+
diff(t, s) {
|
|
300
316
|
return jsonDiff(t, s, this.DELETE)
|
|
301
317
|
}
|
|
302
318
|
}
|
|
@@ -313,7 +329,7 @@ class JsonMergeNoComment extends JsonMerge {
|
|
|
313
329
|
class PackageJson extends JsonMerge {
|
|
314
330
|
static types = ['package.json']
|
|
315
331
|
|
|
316
|
-
async prepare
|
|
332
|
+
async prepare(s, t) {
|
|
317
333
|
// merge new source with current pkg content
|
|
318
334
|
const update = super.prepare(s, t)
|
|
319
335
|
|
|
@@ -327,7 +343,7 @@ class PackageJson extends JsonMerge {
|
|
|
327
343
|
return update
|
|
328
344
|
}
|
|
329
345
|
|
|
330
|
-
async write
|
|
346
|
+
async write(s) {
|
|
331
347
|
const pkg = await NpmPackageJson.load(dirname(this.target))
|
|
332
348
|
pkg.update(s)
|
|
333
349
|
traverse(pkg.content, (keys, value) => {
|
|
@@ -369,7 +385,7 @@ for (const parser of Object.values(Parsers)) {
|
|
|
369
385
|
}
|
|
370
386
|
}
|
|
371
387
|
|
|
372
|
-
const getParser =
|
|
388
|
+
const getParser = file => {
|
|
373
389
|
for (const [type, parser] of parserLookup) {
|
|
374
390
|
if (minimatch(file, type, { nocase: true, dot: true, matchBase: true })) {
|
|
375
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
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
const Handlebars = require('handlebars')
|
|
2
2
|
const { basename, extname, join } = require('path')
|
|
3
|
+
const { Range } = require('semver')
|
|
3
4
|
const fs = require('fs')
|
|
4
5
|
const DELETE = '__DELETE__'
|
|
5
6
|
|
|
6
|
-
const safeValues =
|
|
7
|
-
[key, new Handlebars.SafeString(value)])
|
|
7
|
+
const safeValues = obj => Object.entries(obj).map(([key, value]) => [key, new Handlebars.SafeString(value)])
|
|
8
8
|
|
|
9
|
-
const partialName =
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
12
13
|
|
|
13
14
|
const makePartials = (dir, isBase) => {
|
|
14
15
|
const partials = fs.readdirSync(dir).reduce((acc, f) => {
|
|
@@ -31,14 +32,17 @@ const makePartials = (dir, isBase) => {
|
|
|
31
32
|
Handlebars.registerPartial(partials)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
const setupHandlebars =
|
|
35
|
+
const setupHandlebars = dirs => {
|
|
35
36
|
Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
|
|
37
|
+
Handlebars.registerHelper('extGlob', arr => `{${arr.join(',')}}`)
|
|
36
38
|
Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
|
|
37
39
|
Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
|
|
38
|
-
Handlebars.registerHelper('quote',
|
|
39
|
-
Handlebars.registerHelper('last',
|
|
40
|
-
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))
|
|
41
43
|
Handlebars.registerHelper('del', () => JSON.stringify(DELETE))
|
|
44
|
+
Handlebars.registerHelper('semverRangeMajor', v => new Range(v).set[0][0].semver.major)
|
|
45
|
+
Handlebars.registerHelper('lte', (a, b) => a <= b)
|
|
42
46
|
|
|
43
47
|
if (Array.isArray(dirs)) {
|
|
44
48
|
const [baseDir, ...otherDirs] = dirs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/template-oss",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.23.0",
|
|
4
4
|
"description": "templated files used in npm CLI team oss projects",
|
|
5
5
|
"main": "lib/content/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,21 +10,22 @@
|
|
|
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",
|
|
27
|
-
"url": "https://github.com/npm/template-oss.git"
|
|
28
|
+
"url": "git+https://github.com/npm/template-oss.git"
|
|
28
29
|
},
|
|
29
30
|
"keywords": [
|
|
30
31
|
"npm",
|
|
@@ -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"
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
const { NodeWorkspace } = require('release-please/build/src/plugins/node-workspace')
|
|
2
|
-
const { parseConventionalCommits } = require('release-please/build/src/commit')
|
|
3
|
-
const { DEPS } = require('./util')
|
|
4
|
-
const { WORKSPACE_MESSAGE } = require('./node-workspace-format')
|
|
5
|
-
|
|
6
|
-
// This adds a preconfigure method to the release-please node-workspace plugin
|
|
7
|
-
// which fixes https://github.com/googleapis/release-please/issues/2089 for our
|
|
8
|
-
// use case. We should attempt to upstream this to release-please but it
|
|
9
|
-
// fundamentally changes the way the node-workspace plugin behaves so it might
|
|
10
|
-
// not be easy to land. For now we extend the base plugin and add one method
|
|
11
|
-
// which is much better than previously when we needed to fork and maintain
|
|
12
|
-
// release-please ourselves.
|
|
13
|
-
/* istanbul ignore next: TODO fix flaky tests and enable coverage */
|
|
14
|
-
class NpmNodeWorkspace extends NodeWorkspace {
|
|
15
|
-
updateCandidate (pr) {
|
|
16
|
-
// no-op so release-please node-workspace plugin does not add
|
|
17
|
-
// its broken changelog to the workspace releases. our changelog
|
|
18
|
-
// formatting and the preconfigure method below fix this.
|
|
19
|
-
return pr
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async preconfigure (strategiesByPath, commitsByPath, releasesByPath) {
|
|
23
|
-
// First build a list of all releases that will happen based on the
|
|
24
|
-
// conventional commits
|
|
25
|
-
const candidates = []
|
|
26
|
-
for (const path in strategiesByPath) {
|
|
27
|
-
const pullRequest = await strategiesByPath[path].buildReleasePullRequest(
|
|
28
|
-
parseConventionalCommits(commitsByPath[path]),
|
|
29
|
-
releasesByPath[path]
|
|
30
|
-
)
|
|
31
|
-
// Release please types say this sometimes will return undefined but I could not
|
|
32
|
-
// get any scenario where that was the case. If it was undefined we would want to
|
|
33
|
-
// just ignore it anyway.
|
|
34
|
-
/* istanbul ignore else */
|
|
35
|
-
if (pullRequest) {
|
|
36
|
-
candidates.push({
|
|
37
|
-
path,
|
|
38
|
-
pullRequest,
|
|
39
|
-
config: this.repositoryConfig[path],
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Then build the graph of all those releases + any other connected workspaces
|
|
45
|
-
const { allPackages, candidatesByPackage } = await this.buildAllPackages(candidates)
|
|
46
|
-
const graph = await this.buildGraph(allPackages)
|
|
47
|
-
const packageNamesToUpdate = this.packageNamesToUpdate(graph, candidatesByPackage)
|
|
48
|
-
const graphPackages = this.buildGraphOrder(graph, packageNamesToUpdate)
|
|
49
|
-
|
|
50
|
-
// Then build a list of all the updated versions
|
|
51
|
-
const updatedVersions = {}
|
|
52
|
-
for (const pkg of graphPackages) {
|
|
53
|
-
const path = this.pathFromPackage(pkg)
|
|
54
|
-
const packageName = this.packageNameFromPackage(pkg)
|
|
55
|
-
const existingCandidate = candidatesByPackage[packageName]
|
|
56
|
-
|
|
57
|
-
if (existingCandidate) {
|
|
58
|
-
// If there is an existing pull request use that version
|
|
59
|
-
updatedVersions[packageName] = existingCandidate.pullRequest?.version
|
|
60
|
-
} else {
|
|
61
|
-
// Otherwise build another pull request (that will be discarded) just
|
|
62
|
-
// to see what the version would be if it only contained a deps commit.
|
|
63
|
-
// This is to make sure we use any custom versioning or release strategy.
|
|
64
|
-
const releasePullRequest = await strategiesByPath[path].buildReleasePullRequest(
|
|
65
|
-
parseConventionalCommits([{ message: `${DEPS}: ${Math.random()}` }]),
|
|
66
|
-
releasesByPath[path]
|
|
67
|
-
)
|
|
68
|
-
updatedVersions[packageName] = releasePullRequest?.version
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Then go through all the packages again and add deps commits for each
|
|
73
|
-
// updated workspace
|
|
74
|
-
for (const pkg of graphPackages) {
|
|
75
|
-
const path = this.pathFromPackage(pkg)
|
|
76
|
-
const packageName = this.packageNameFromPackage(pkg)
|
|
77
|
-
const graphPackage = graph.get(packageName)
|
|
78
|
-
|
|
79
|
-
// Update dependency versions add a deps commit to each path so it gets
|
|
80
|
-
// processed later. This else never happens in our cases because our
|
|
81
|
-
// packages always have deps, but keeping this around to make it easier to
|
|
82
|
-
// upstream in the future.
|
|
83
|
-
/* istanbul ignore else */
|
|
84
|
-
if (graphPackage.deps) {
|
|
85
|
-
for (const depName of graphPackage.deps) {
|
|
86
|
-
const depVersion = updatedVersions[depName]
|
|
87
|
-
// Same as the above check, we always have a version here but technically
|
|
88
|
-
// we could not in which it would be safe to ignore it.
|
|
89
|
-
/* istanbul ignore else */
|
|
90
|
-
if (depVersion) {
|
|
91
|
-
commitsByPath[path].push({
|
|
92
|
-
message: WORKSPACE_MESSAGE(depName, depVersion.toString()),
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return strategiesByPath
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
module.exports = NpmNodeWorkspace
|