@node-core/utils 6.3.0 → 6.3.2

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/auth.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import { ClientRequest } from 'node:http';
3
3
 
4
+ // eslint-disable-next-line import/no-unresolved
4
5
  import ghauth from 'ghauth';
5
6
 
6
7
  import { clearCachedConfig, encryptValue, getMergedConfig, getNcurcPath } from './config.js';
@@ -306,63 +306,54 @@ export default class LandingSession extends Session {
306
306
  await this.tryCompleteLanding(commitInfo);
307
307
  }
308
308
 
309
- async amend() {
310
- const { cli } = this;
311
- if (!this.readyToAmend()) {
312
- cli.warn('Not yet ready to amend, run `git node land --abort`');
313
- return;
314
- }
309
+ async generateAmendedMessage(original) {
310
+ const { cli, metadata } = this;
315
311
 
316
312
  const BACKPORT_RE = /^BACKPORT-PR-URL\s*:\s*(\S+)$/i;
317
313
  const PR_RE = /^PR-URL\s*:\s*(\S+)$/i;
318
314
  const REVIEW_RE = /^Reviewed-By\s*:\s*(\S+)$/i;
319
- const CVE_RE = /^CVE-ID\s*:\s*(\S+)$/i;
320
-
321
- this.startAmending();
322
-
323
- const rev = this.getCurrentRev();
324
- const original = runSync('git', [
325
- 'show', 'HEAD', '-s', '--format=%B'
326
- ]).trim();
315
+ const CVE_RE = /^CVE-ID\s*:\s*(\S+)$/im;
327
316
 
328
317
  // git has very specific rules about what is a trailer and what is not.
329
318
  // Instead of trying to implement those ourselves, let git parse the
330
319
  // original commit message and see if it outputs any trailers.
331
- const originalHasTrailers = runSync('git', [
320
+ const originalTrailers = runSync('git', [
332
321
  'interpret-trailers', '--parse', '--no-divider'
333
322
  ], {
334
323
  input: `${original}\n`
335
- }).trim().length !== 0;
336
-
337
- const metadata = this.metadata.trim().split('\n');
338
- // Filtering out metadata that we will add ourselves:
339
- const isFiltered = line =>
340
- (!PR_RE.test(line) || this.backport) &&
341
- !BACKPORT_RE.test(line) &&
342
- !REVIEW_RE.test(line);
343
- const amended = original.split('\n').filter(isFiltered);
344
-
345
- // If the original commit message already contains trailers (such as
346
- // "Co-authored-by"), we simply add our own metadata after those. Otherwise,
347
- // we have to add an empty line so that git recognizes our own metadata as
348
- // trailers in the amended commit message.
349
- if (!originalHasTrailers) {
350
- amended.push('');
324
+ }).split('\n').map(trailer => {
325
+ const separatorIndex = trailer.indexOf(':');
326
+ return [trailer.slice(0, separatorIndex), trailer.slice(separatorIndex + 2)];
327
+ }).slice(0, -1); // Remove the last line return entry
328
+
329
+ const containCVETrailer = CVE_RE.test(originalTrailers);
330
+
331
+ const filterTrailer = (line) => ([key]) =>
332
+ line.startsWith(key) &&
333
+ new RegExp(`^${RegExp.escape?.(key) ?? key}\\s*:`).test(line);
334
+ const amended = original.trim().split('\n')
335
+ .filter(line =>
336
+ !line.includes(':') ||
337
+ !originalTrailers.some(filterTrailer(line)));
338
+ for (let i = amended.length - 1; amended[i] === ''; i--) {
339
+ amended.pop();
351
340
  }
352
341
 
353
- let containCVETrailer = false;
354
- for (const line of metadata) {
355
- if (line.length !== 0 && original.includes(line) && !isFiltered(line)) {
356
- containCVETrailer ||= CVE_RE.test(line);
357
- if (originalHasTrailers) {
358
- cli.warn(`Found ${line}, skipping..`);
359
- continue;
360
- } else {
361
- cli.error('Git found no trailers in the original commit message, ' +
362
- `but '${line}' is present and should be a trailer.`);
363
- process.exit(1); // make it work with git rebase -x
364
- }
342
+ // Only keep existing trailers that we won't add ourselves
343
+ const trailersToFilterOut = ['BACKPORT-PR-URL', 'REVIEWED-BY'];
344
+ if (!this.backport) trailersToFilterOut.push('PR-URL');
345
+ const keptTrailers = originalTrailers.filter(
346
+ ([key]) => !trailersToFilterOut.includes(key.toUpperCase())
347
+ );
348
+ amended.push('', ...keptTrailers.map(([key, value]) => `${key}: ${value}`));
349
+
350
+ for (const line of metadata.trim().split('\n')) {
351
+ const foundMatchingTrailer = keptTrailers.find(filterTrailer(line));
352
+ if (foundMatchingTrailer && line === foundMatchingTrailer.join(': ')) {
353
+ cli.warn(`Found ${line}, skipping..`);
354
+ continue;
365
355
  }
356
+
366
357
  if (BACKPORT_RE.test(line)) {
367
358
  const prIndex =
368
359
  (amended.findIndex(datum => PR_RE.test(datum)) + 1) ||
@@ -410,8 +401,24 @@ export default class LandingSession extends Session {
410
401
  amended.push('CVE-ID: ' + cveID);
411
402
  }
412
403
  }
404
+ return amended.join('\n');
405
+ }
406
+
407
+ async amend() {
408
+ const { cli } = this;
409
+ if (!this.readyToAmend()) {
410
+ cli.warn('Not yet ready to amend, run `git node land --abort`');
411
+ return;
412
+ }
413
+
414
+ this.startAmending();
415
+
416
+ const rev = this.getCurrentRev();
417
+ const original = runSync('git', [
418
+ 'show', 'HEAD', '-s', '--format=%B'
419
+ ]).trim();
413
420
 
414
- const message = amended.join('\n');
421
+ const message = await this.generateAmendedMessage(original);
415
422
  const messageFile = this.saveMessage(rev, message);
416
423
  cli.separator('New Message');
417
424
  cli.log(message.trim());
package/lib/session.js CHANGED
@@ -127,6 +127,7 @@ export default class Session {
127
127
  writeJson(this.sessionPath, {
128
128
  state: STARTED,
129
129
  prid: this.prid,
130
+ backport: this.backport,
130
131
  // Filter out getters, those are likely encrypted data we don't need on the session.
131
132
  config: Object.entries(Object.getOwnPropertyDescriptors(this.config))
132
133
  .reduce((pv, [key, desc]) => {
@@ -271,6 +272,7 @@ export default class Session {
271
272
  const sess = this.session;
272
273
  if (sess.prid) {
273
274
  this.prid = sess.prid;
275
+ this.backport = sess.backport;
274
276
  this.config = sess.config;
275
277
  }
276
278
  return this;