mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-09 02:08:19 +01:00
train S5: merge #3862 at 97595f41ee v1.93.7.0
This commit is contained in:
commit
86bb621fa2
21 files changed
+247
-88
No files matched your search
@@ -37,6 +37,7 @@ import * as path from 'node:path';
|
||||
import { EXIT, exitTableHelp, type ShipReceipt } from '../lib/headless-artifacts';
|
||||
import { resultLine, resultLineWithDocs } from '../lib/result-codes';
|
||||
import { versionAtRef } from '../lib/restamp';
|
||||
import { branchSides, type BranchSide } from '../lib/stamp-only';
|
||||
import { runScriptSync } from '../lib/script-invocation';
|
||||
import { readPregateFile, verifyPregate } from '../lib/pregate/index';
|
||||
import { isUnavailable, loadPolicyFromBase, matchesAny, policyUnavailableLine, resolveBaseBranch, runningGstackVersion, stampFilesInTree, validatePolicy, type ShipPolicy } from '../lib/ship-policy';
|
||||
@@ -495,7 +496,7 @@ function productRules(repoRoot: string, base: string, outputs: readonly string[]
|
||||
* change, such as a CHANGELOG fragment next to the base's changelog.d/README.md
|
||||
* (GST-343, #3606), into the product patch-id at one head only.
|
||||
*/
|
||||
function productSpec(repoRoot: string, rules: ProductRules, from: string, to: string, branch?: { touched: ReadonlySet<string>; sides: ReadonlyArray<readonly [string, string]> }): { changed: Array<{ path: string; class: ReturnType<typeof classifyCarryPath> }>; product: string[]; tests: string[] } | undefined {
|
||||
function productSpec(repoRoot: string, rules: ProductRules, from: string, to: string, branch?: { touched: ReadonlySet<string>; sides: ReadonlyArray<readonly [string, string]>; own: (rel: string) => BranchSide | undefined }): { changed: Array<{ path: string; class: ReturnType<typeof classifyCarryPath> }>; product: string[]; tests: string[] } | undefined {
|
||||
const changedRaw = git(['diff', '--name-only', from, to], repoRoot);
|
||||
if (changedRaw === undefined) return undefined;
|
||||
const blobAt = (ref: string, p: string): string | null => { const r = spawnSync('git', ['show', `${ref}:${p}`], { cwd: repoRoot, encoding: 'utf8', timeout: 30_000, maxBuffer: 16 * 1024 * 1024 }); return r.status === 0 ? r.stdout : null; };
|
||||
@@ -507,7 +508,7 @@ function productSpec(repoRoot: string, rules: ProductRules, from: string, to: st
|
||||
const versions = new Map<string, string | null>();
|
||||
const version = (ref: string) => { if (!versions.has(ref)) versions.set(ref, versionAt(ref)); return versions.get(ref)!; };
|
||||
const stamped = (p: string) => matchesAny(rules.metadata, p) && !matchesAny(rules.extra.outputs, p);
|
||||
const classify = (p: string, a: string, b: string) => classifyCarryPath(p, rules.extra, stamped(p) ? { before: blobAt(a, p), after: blobAt(b, p), oldVersion: version(a), newVersion: version(b), templates: rules.templates } : undefined);
|
||||
const classify = (p: string, a: string, b: string) => classifyCarryPath(p, rules.extra, stamped(p) ? { before: blobAt(a, p), after: blobAt(b, p), oldVersion: version(a), newVersion: version(b), templates: rules.templates, side: a === from && b === to ? branch?.own(p) : undefined } : undefined);
|
||||
const changed = changedRaw.split('\n').filter(Boolean).map(p => ({ path: p, class: classify(p, from, to) }));
|
||||
const excludeGlobs = (globs: readonly string[]) => globs.map(g => `:(exclude,glob)${g}`);
|
||||
const demoted = !branch ? changed.filter(c => c.class === 'product' && matchesAny(rules.metadata, c.path)).map(c => c.path)
|
||||
@@ -620,7 +621,7 @@ function cmdCarry(rest: string[], json: boolean): number {
|
||||
const listed = [touchedPaths(repoRoot, fromBase, from), touchedPaths(repoRoot, headBase, head)];
|
||||
if (!listed[0] || !listed[1]) return refused('RECEIPT_CARRY_REFUSED', `git could not list the paths the branch touched against ${base}; run /ship on ${head.slice(0, 12)}`);
|
||||
const touched = new Set([...listed[0], ...listed[1]]);
|
||||
const spec = productSpec(repoRoot, rules, from, head, { touched, sides: [[fromBase, from], [headBase, head]] });
|
||||
const spec = productSpec(repoRoot, rules, from, head, { touched, sides: [[fromBase, from], [headBase, head]], own: branchSides(repoRoot, baseRef, from, '') });
|
||||
if (!spec) return refused('RECEIPT_CARRY_REFUSED', `git diff ${from.slice(0, 12)} ${head.slice(0, 12)} failed`);
|
||||
const { changed } = spec;
|
||||
const productFrom = patchId(repoRoot, fromBase, from, spec.product);
|
||||
|
||||
@@ -64,10 +64,10 @@ function main(argv: string[]): number {
|
||||
if (predSha || predPr || predRef) predecessor = { pr: predPr ?? predecessor?.pr ?? null, recordedHead: predSha ?? predecessor?.recordedHead ?? null, ref: predRef ?? null };
|
||||
|
||||
const policyFrom = flag(argv, '--policy-from') ?? 'base';
|
||||
const base = resolveBaseBranch(repoRoot, flag(argv, '--base'));
|
||||
let loaded: LoadedPolicy;
|
||||
if (policyFrom === 'head') loaded = loadPolicyFromHead(repoRoot);
|
||||
else {
|
||||
const base = resolveBaseBranch(repoRoot, flag(argv, '--base'));
|
||||
const l = loadPolicyFromBase(repoRoot, base);
|
||||
if (isUnavailable(l)) { process.stderr.write(policyUnavailableLine('gstack-tree-receipt', base, l.detail) + '\n'); return EXIT.refused; }
|
||||
loaded = l;
|
||||
@@ -76,7 +76,7 @@ function main(argv: string[]): number {
|
||||
|
||||
const receipt = buildReceipt({
|
||||
repoRoot, gated, current: flag(argv, '--current'), policy: loaded.policy, policyLabel: loaded.source.kind === 'head' ? 'head (unreviewed)' : loaded.source.label,
|
||||
predecessor, bundlePath: flag(argv, '--bundle'), rerunCommand: flag(argv, '--rerun-command'),
|
||||
predecessor, bundlePath: flag(argv, '--bundle'), rerunCommand: flag(argv, '--rerun-command'), baseRef: `origin/${base}`,
|
||||
});
|
||||
if ('error' in receipt) { process.stderr.write(resultLine('gstack-tree-receipt', receipt.code, receipt.error) + '\n'); return EXIT.fail; }
|
||||
process.stdout.write(json ? JSON.stringify(receipt) + '\n' : renderReceipt(receipt));
|
||||
|
||||
Reference in new issue
Block a user