@node-core/utils 6.3.1 → 6.3.3

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.
@@ -306,48 +306,59 @@ 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
315
  const CVE_RE = /^CVE-ID\s*:\s*(\S+)$/im;
320
316
 
321
- this.startAmending();
322
-
323
- const rev = this.getCurrentRev();
324
- const original = runSync('git', [
325
- 'show', 'HEAD', '-s', '--format=%B'
326
- ]).trim();
327
-
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
- // original commit message and see if it outputs any trailers.
331
- const originalTrailers = runSync('git', [
319
+ // commit message and see if it outputs any trailers.
320
+ const interpretTrailers = commitMessage => runSync('git', [
332
321
  'interpret-trailers', '--parse', '--no-divider'
333
322
  ], {
334
- input: `${original}\n`
323
+ input: `${commitMessage}\n`
335
324
  });
325
+
326
+ const originalTrailers = interpretTrailers(original);
336
327
  const containCVETrailer = CVE_RE.test(originalTrailers);
337
328
 
338
- const metadata = this.metadata.trim().split('\n');
339
- const amended = original.slice(0, -originalTrailers.length).trim().split('\n');
329
+ const amended = original.trim().split('\n');
330
+ let keptTrailers = [];
331
+ if (originalTrailers) {
332
+ const stillInTrailers = () => {
333
+ const result = interpretTrailers(amended.join('\n'));
334
+ return result.length && originalTrailers.startsWith(result.trim());
335
+ };
336
+ // Remove all lines until we find an empty string, which should get of all
337
+ // trailers in most cases.
338
+ amended.splice(amended.lastIndexOf(''), Infinity);
339
+ for (let i = amended.length - 1; amended[i] === '' || stillInTrailers(); i--) {
340
+ // Remove last line until git no longer detects any trailers
341
+ amended.pop();
342
+ }
340
343
 
341
- // Only keep existing trailers that we won't add ourselves
342
- const keptTrailers = originalTrailers.split('\n').filter(line =>
343
- !!line &&
344
- (!PR_RE.test(line) || this.backport) &&
345
- !BACKPORT_RE.test(line) &&
346
- !REVIEW_RE.test(line));
347
- amended.push('', ...keptTrailers);
344
+ // Only keep existing trailers that we won't add ourselves
345
+ const trailersToFilterOut = ['BACKPORT-PR-URL', 'REVIEWED-BY'];
346
+ if (!this.backport) trailersToFilterOut.push('PR-URL');
347
+ keptTrailers = originalTrailers
348
+ .split('\n')
349
+ .map(trailer => {
350
+ const separatorIndex = trailer.indexOf(':');
351
+ return [trailer.slice(0, separatorIndex), trailer.slice(separatorIndex + 2)];
352
+ })
353
+ .slice(0, -1) // Remove the last line return entry
354
+ .filter(
355
+ ([key]) => !trailersToFilterOut.includes(key.toUpperCase())
356
+ );
357
+ }
358
+ amended.push('', ...keptTrailers.map(([key, value]) => `${key}: ${value}`));
348
359
 
349
- for (const line of metadata) {
350
- if (keptTrailers.includes(line)) {
360
+ for (const line of metadata.trim().split('\n')) {
361
+ if (keptTrailers.some((trailer) => line.toUpperCase() === trailer.join(': ').toUpperCase())) {
351
362
  cli.warn(`Found ${line}, skipping..`);
352
363
  continue;
353
364
  }
@@ -399,8 +410,24 @@ export default class LandingSession extends Session {
399
410
  amended.push('CVE-ID: ' + cveID);
400
411
  }
401
412
  }
413
+ return amended.join('\n');
414
+ }
415
+
416
+ async amend() {
417
+ const { cli } = this;
418
+ if (!this.readyToAmend()) {
419
+ cli.warn('Not yet ready to amend, run `git node land --abort`');
420
+ return;
421
+ }
422
+
423
+ this.startAmending();
424
+
425
+ const rev = this.getCurrentRev();
426
+ const original = runSync('git', [
427
+ 'show', 'HEAD', '-s', '--format=%B'
428
+ ]).trim();
402
429
 
403
- const message = amended.join('\n');
430
+ const message = await this.generateAmendedMessage(original);
404
431
  const messageFile = this.saveMessage(rev, message);
405
432
  cli.separator('New Message');
406
433
  cli.log(message.trim());