@lumy-pack/line-lore 0.0.6 → 0.0.7
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/dist/cli.mjs +202 -47
- package/dist/core/ancestry/ancestry.d.ts +14 -1
- package/dist/core/ancestry/index.d.ts +1 -1
- package/dist/core/pr-lookup/index.d.ts +1 -0
- package/dist/core/pr-lookup/pr-lookup.d.ts +18 -2
- package/dist/index.cjs +201 -46
- package/dist/index.mjs +201 -46
- package/dist/platform/github/github-adapter.d.ts +3 -1
- package/dist/platform/gitlab/gitlab-adapter.d.ts +3 -1
- package/dist/types/cache.d.ts +2 -0
- package/dist/types/git.d.ts +2 -0
- package/dist/types/platform.d.ts +3 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -387,6 +387,35 @@ async function findMergeCommit(commitSha, options) {
|
|
|
387
387
|
timeout: remaining
|
|
388
388
|
});
|
|
389
389
|
}
|
|
390
|
+
async function verifyMergeIntroducesCommit(targetSha, mergeResult, options) {
|
|
391
|
+
if (mergeResult.parentShas.length < 2) return true;
|
|
392
|
+
const firstParent = mergeResult.parentShas[0];
|
|
393
|
+
const branchParents = mergeResult.parentShas.slice(1);
|
|
394
|
+
const onMainline = await isAncestor(targetSha, firstParent, options);
|
|
395
|
+
if (onMainline === null) return false;
|
|
396
|
+
if (onMainline) return false;
|
|
397
|
+
for (const branchParent of branchParents) {
|
|
398
|
+
const onBranch = await isAncestor(targetSha, branchParent, options);
|
|
399
|
+
if (onBranch === null) return false;
|
|
400
|
+
if (onBranch) return true;
|
|
401
|
+
}
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
async function isAncestor(commitA, commitB, options) {
|
|
405
|
+
try {
|
|
406
|
+
const result = await gitExec(
|
|
407
|
+
["merge-base", "--is-ancestor", commitA, commitB],
|
|
408
|
+
{
|
|
409
|
+
cwd: options?.cwd,
|
|
410
|
+
timeout: options?.timeout ?? 5e3,
|
|
411
|
+
allowExitCodes: [1]
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
return result.exitCode === 0;
|
|
415
|
+
} catch {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
390
419
|
async function findMergeCommitWithArgs(commitSha, ref, extraArgs, options) {
|
|
391
420
|
try {
|
|
392
421
|
const result = await gitExec(
|
|
@@ -404,7 +433,25 @@ async function findMergeCommitWithArgs(commitSha, ref, extraArgs, options) {
|
|
|
404
433
|
);
|
|
405
434
|
const lines = filter4(result.stdout.trim().split("\n"), isTruthy4);
|
|
406
435
|
if (lines.length === 0) return null;
|
|
407
|
-
|
|
436
|
+
const candidateCount = Math.min(lines.length, MAX_CANDIDATES);
|
|
437
|
+
let verifiedCount = 0;
|
|
438
|
+
for (let i = 0; i < candidateCount; i++) {
|
|
439
|
+
const candidate = parseMergeLogLine(lines[i]);
|
|
440
|
+
if (!candidate) continue;
|
|
441
|
+
verifiedCount++;
|
|
442
|
+
const verified = await verifyMergeIntroducesCommit(
|
|
443
|
+
commitSha,
|
|
444
|
+
candidate,
|
|
445
|
+
options
|
|
446
|
+
);
|
|
447
|
+
if (verified) return candidate;
|
|
448
|
+
}
|
|
449
|
+
if (verifiedCount > 0 && options?.warnings) {
|
|
450
|
+
options.warnings.push(
|
|
451
|
+
`ancestry: all ${verifiedCount} merge candidate(s) failed verification for ${commitSha.slice(0, 8)}`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
return null;
|
|
408
455
|
} catch {
|
|
409
456
|
return null;
|
|
410
457
|
}
|
|
@@ -426,24 +473,39 @@ function parseMergeLogLine(line) {
|
|
|
426
473
|
const subject = parts.slice(subjectStart).join(" ");
|
|
427
474
|
return { mergeCommitSha, parentShas, subject };
|
|
428
475
|
}
|
|
429
|
-
function
|
|
476
|
+
async function getCommitSubject(sha, options) {
|
|
477
|
+
try {
|
|
478
|
+
const result = await gitExec(["log", "-1", "--format=%s", sha], {
|
|
479
|
+
cwd: options?.cwd,
|
|
480
|
+
timeout: options?.timeout ?? 5e3
|
|
481
|
+
});
|
|
482
|
+
const subject = result.stdout.trim();
|
|
483
|
+
return subject || null;
|
|
484
|
+
} catch {
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function extractPRFromMergeMessage(subject, platform) {
|
|
430
489
|
const ghMatch = /Merge pull request #(\d+)/.exec(subject);
|
|
431
490
|
if (ghMatch) return parseInt(ghMatch[1], 10);
|
|
432
491
|
const squashMatch = /\(#(\d+)\)\s*$/.exec(subject);
|
|
433
492
|
if (squashMatch) return parseInt(squashMatch[1], 10);
|
|
434
|
-
|
|
435
|
-
|
|
493
|
+
if (!platform || platform === "gitlab" || platform === "gitlab-self-hosted") {
|
|
494
|
+
const glMatch = /See merge request\s+\S*!(\d+)\s*$/.exec(subject);
|
|
495
|
+
if (glMatch) return parseInt(glMatch[1], 10);
|
|
496
|
+
}
|
|
436
497
|
const adoMatch = /Merged PR (\d+):/.exec(subject);
|
|
437
498
|
if (adoMatch) return parseInt(adoMatch[1], 10);
|
|
438
499
|
return null;
|
|
439
500
|
}
|
|
440
|
-
var DEFAULT_ANCESTRY_TIMEOUT;
|
|
501
|
+
var DEFAULT_ANCESTRY_TIMEOUT, MAX_CANDIDATES;
|
|
441
502
|
var init_ancestry = __esm({
|
|
442
503
|
"src/core/ancestry/ancestry.ts"() {
|
|
443
504
|
"use strict";
|
|
444
505
|
init_esm_shims();
|
|
445
506
|
init_executor();
|
|
446
507
|
DEFAULT_ANCESTRY_TIMEOUT = 3e4;
|
|
508
|
+
MAX_CANDIDATES = 10;
|
|
447
509
|
}
|
|
448
510
|
});
|
|
449
511
|
|
|
@@ -574,7 +636,8 @@ function toCachedPR(pr) {
|
|
|
574
636
|
url: pr.url,
|
|
575
637
|
mergeCommit: pr.mergeCommit,
|
|
576
638
|
baseBranch: pr.baseBranch,
|
|
577
|
-
mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : void 0
|
|
639
|
+
mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : void 0,
|
|
640
|
+
resolvedVia: pr.resolvedVia
|
|
578
641
|
};
|
|
579
642
|
}
|
|
580
643
|
function fromCachedPR(cached) {
|
|
@@ -589,7 +652,9 @@ function fromCachedPR(cached) {
|
|
|
589
652
|
url: cached.url,
|
|
590
653
|
mergeCommit: cached.mergeCommit,
|
|
591
654
|
baseBranch: cached.baseBranch,
|
|
592
|
-
mergedAt
|
|
655
|
+
mergedAt,
|
|
656
|
+
// Preserve original resolvedVia; fallback to url heuristic for legacy cache entries
|
|
657
|
+
resolvedVia: cached.resolvedVia ?? (cached.url ? "api" : "message")
|
|
593
658
|
};
|
|
594
659
|
}
|
|
595
660
|
async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
@@ -600,15 +665,30 @@ async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
|
600
665
|
const cached = await cache.get(commitSha);
|
|
601
666
|
if (cached) return fromCachedPR(cached);
|
|
602
667
|
if (options?.cacheOnly) return null;
|
|
668
|
+
const prSelectOptions = options?.preferredBase ? { preferredBase: options.preferredBase } : void 0;
|
|
669
|
+
if (adapter) {
|
|
670
|
+
const directPR = await adapter.getPRForCommit(commitSha, prSelectOptions);
|
|
671
|
+
if (directPR?.mergedAt) {
|
|
672
|
+
const result = { ...directPR, resolvedVia: "api" };
|
|
673
|
+
await cache.set(commitSha, toCachedPR(result));
|
|
674
|
+
return result;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
603
677
|
let mergeBasedPR = null;
|
|
604
678
|
const mergeResult = await findMergeCommit(commitSha, options);
|
|
605
679
|
if (mergeResult) {
|
|
606
|
-
const prNumber = extractPRFromMergeMessage(
|
|
680
|
+
const prNumber = extractPRFromMergeMessage(
|
|
681
|
+
mergeResult.subject,
|
|
682
|
+
options?.platform
|
|
683
|
+
);
|
|
607
684
|
if (prNumber) {
|
|
608
685
|
if (adapter) {
|
|
609
|
-
const prInfo = await adapter.getPRForCommit(
|
|
686
|
+
const prInfo = await adapter.getPRForCommit(
|
|
687
|
+
mergeResult.mergeCommitSha,
|
|
688
|
+
prSelectOptions
|
|
689
|
+
);
|
|
610
690
|
if (prInfo?.mergedAt) {
|
|
611
|
-
mergeBasedPR = prInfo;
|
|
691
|
+
mergeBasedPR = { ...prInfo, resolvedVia: "ancestry" };
|
|
612
692
|
}
|
|
613
693
|
}
|
|
614
694
|
if (!mergeBasedPR) {
|
|
@@ -618,7 +698,8 @@ async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
|
618
698
|
author: "",
|
|
619
699
|
url: "",
|
|
620
700
|
mergeCommit: mergeResult.mergeCommitSha,
|
|
621
|
-
baseBranch: ""
|
|
701
|
+
baseBranch: "",
|
|
702
|
+
resolvedVia: "ancestry"
|
|
622
703
|
};
|
|
623
704
|
}
|
|
624
705
|
if (!options?.deep || mergeBasedPR.mergedAt) {
|
|
@@ -631,11 +712,24 @@ async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
|
631
712
|
await cache.set(commitSha, toCachedPR(mergeBasedPR));
|
|
632
713
|
return mergeBasedPR;
|
|
633
714
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
715
|
+
const commitSubject = await getCommitSubject(commitSha, options);
|
|
716
|
+
if (commitSubject) {
|
|
717
|
+
const directPrNumber = extractPRFromMergeMessage(
|
|
718
|
+
commitSubject,
|
|
719
|
+
options?.platform
|
|
720
|
+
);
|
|
721
|
+
if (directPrNumber) {
|
|
722
|
+
const subjectPR = {
|
|
723
|
+
number: directPrNumber,
|
|
724
|
+
title: commitSubject,
|
|
725
|
+
author: "",
|
|
726
|
+
url: "",
|
|
727
|
+
mergeCommit: commitSha,
|
|
728
|
+
baseBranch: "",
|
|
729
|
+
resolvedVia: "message"
|
|
730
|
+
};
|
|
731
|
+
await cache.set(commitSha, toCachedPR(subjectPR));
|
|
732
|
+
return subjectPR;
|
|
639
733
|
}
|
|
640
734
|
}
|
|
641
735
|
if (!options?.skipPatchIdScan && _recursionDepth < MAX_RECURSION_DEPTH) {
|
|
@@ -696,6 +790,7 @@ init_errors();
|
|
|
696
790
|
// src/core/core.ts
|
|
697
791
|
init_esm_shims();
|
|
698
792
|
import { createHash as createHash2 } from "crypto";
|
|
793
|
+
import { dirname, isAbsolute, relative } from "path";
|
|
699
794
|
import { map as map8 } from "@winglet/common-utils";
|
|
700
795
|
|
|
701
796
|
// src/ast/index.ts
|
|
@@ -979,7 +1074,7 @@ async function checkGitHealth(options) {
|
|
|
979
1074
|
const cloneStatus = await checkCloneStatus({ cwd: options?.cwd });
|
|
980
1075
|
if (cloneStatus.partialClone) {
|
|
981
1076
|
hints.push(
|
|
982
|
-
"Partial clone detected. Patch-ID scan (Strategy
|
|
1077
|
+
"Partial clone detected. Patch-ID scan (Strategy 5) will be skipped to avoid blob downloads."
|
|
983
1078
|
);
|
|
984
1079
|
}
|
|
985
1080
|
if (cloneStatus.shallow) {
|
|
@@ -1095,7 +1190,7 @@ var GitHubAdapter = class {
|
|
|
1095
1190
|
return { authenticated: false, hostname: this.hostname };
|
|
1096
1191
|
}
|
|
1097
1192
|
}
|
|
1098
|
-
async getPRForCommit(sha) {
|
|
1193
|
+
async getPRForCommit(sha, options) {
|
|
1099
1194
|
if (this.scheduler.isRateLimited()) return null;
|
|
1100
1195
|
try {
|
|
1101
1196
|
const result = await shellExec(
|
|
@@ -1112,18 +1207,20 @@ var GitHubAdapter = class {
|
|
|
1112
1207
|
);
|
|
1113
1208
|
const prs = JSON.parse(result.stdout);
|
|
1114
1209
|
if (!isArray(prs) || prs.length === 0) return null;
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1210
|
+
let data = prs[0];
|
|
1211
|
+
if (options?.preferredBase) {
|
|
1212
|
+
const preferred = prs.find(
|
|
1213
|
+
(pr) => pr.base === options.preferredBase
|
|
1214
|
+
);
|
|
1215
|
+
if (preferred) data = preferred;
|
|
1216
|
+
}
|
|
1120
1217
|
return {
|
|
1121
1218
|
number: data.number,
|
|
1122
1219
|
title: data.title ?? "",
|
|
1123
1220
|
author: data.user ?? "",
|
|
1124
1221
|
url: data.html_url ?? "",
|
|
1125
1222
|
mergeCommit: data.merge_commit_sha ?? sha,
|
|
1126
|
-
baseBranch: data.base ??
|
|
1223
|
+
baseBranch: data.base ?? "",
|
|
1127
1224
|
mergedAt: data.merged_at
|
|
1128
1225
|
};
|
|
1129
1226
|
} catch {
|
|
@@ -1305,7 +1402,7 @@ var GitLabAdapter = class {
|
|
|
1305
1402
|
return { authenticated: false, hostname: this.hostname };
|
|
1306
1403
|
}
|
|
1307
1404
|
}
|
|
1308
|
-
async getPRForCommit(sha) {
|
|
1405
|
+
async getPRForCommit(sha, options) {
|
|
1309
1406
|
if (this.scheduler.isRateLimited()) return null;
|
|
1310
1407
|
try {
|
|
1311
1408
|
const result = await shellExec(
|
|
@@ -1329,18 +1426,20 @@ var GitLabAdapter = class {
|
|
|
1329
1426
|
return aTime - bTime;
|
|
1330
1427
|
});
|
|
1331
1428
|
if (mergedMRs.length === 0) return null;
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1429
|
+
let mr = mergedMRs[0];
|
|
1430
|
+
if (options?.preferredBase) {
|
|
1431
|
+
const preferred = mergedMRs.find(
|
|
1432
|
+
(m) => m.target_branch === options.preferredBase
|
|
1433
|
+
);
|
|
1434
|
+
if (preferred) mr = preferred;
|
|
1435
|
+
}
|
|
1337
1436
|
return {
|
|
1338
1437
|
number: mr.iid,
|
|
1339
1438
|
title: mr.title ?? "",
|
|
1340
1439
|
author: mr.author?.username ?? "",
|
|
1341
1440
|
url: mr.web_url ?? "",
|
|
1342
1441
|
mergeCommit: mr.merge_commit_sha ?? sha,
|
|
1343
|
-
baseBranch: mr.target_branch ??
|
|
1442
|
+
baseBranch: mr.target_branch ?? "",
|
|
1344
1443
|
mergedAt: mr.merged_at
|
|
1345
1444
|
};
|
|
1346
1445
|
} catch {
|
|
@@ -2148,6 +2247,28 @@ async function traverse(adapter, type, number, depth, maxDepth, nodes, edges, vi
|
|
|
2148
2247
|
|
|
2149
2248
|
// src/core/core.ts
|
|
2150
2249
|
init_pr_lookup2();
|
|
2250
|
+
function resolvedViaToTrackingMethod(resolvedVia) {
|
|
2251
|
+
switch (resolvedVia) {
|
|
2252
|
+
case "api":
|
|
2253
|
+
return "api";
|
|
2254
|
+
case "ancestry":
|
|
2255
|
+
return "ancestry-path";
|
|
2256
|
+
case "message":
|
|
2257
|
+
return "message-parse";
|
|
2258
|
+
case "patch-id":
|
|
2259
|
+
return "patch-id";
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
function resolvedViaToConfidence(resolvedVia) {
|
|
2263
|
+
switch (resolvedVia) {
|
|
2264
|
+
case "api":
|
|
2265
|
+
case "ancestry":
|
|
2266
|
+
return "exact";
|
|
2267
|
+
case "message":
|
|
2268
|
+
case "patch-id":
|
|
2269
|
+
return "heuristic";
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2151
2272
|
function computeFeatureFlags(operatingLevel, options) {
|
|
2152
2273
|
return {
|
|
2153
2274
|
astDiff: isAstAvailable() && !options.noAst,
|
|
@@ -2165,6 +2286,22 @@ async function resolveRepoIdentity(cwd) {
|
|
|
2165
2286
|
return { host: "_local", owner: "_", repo: "_unknown" };
|
|
2166
2287
|
}
|
|
2167
2288
|
}
|
|
2289
|
+
async function resolveFileContext(file, cwd) {
|
|
2290
|
+
if (cwd || !isAbsolute(file)) return { file, cwd };
|
|
2291
|
+
const fileDir = dirname(file);
|
|
2292
|
+
try {
|
|
2293
|
+
const result = await gitExec(["rev-parse", "--show-toplevel"], {
|
|
2294
|
+
cwd: fileDir
|
|
2295
|
+
});
|
|
2296
|
+
const repoRoot = result.stdout.trim();
|
|
2297
|
+
return {
|
|
2298
|
+
file: relative(repoRoot, file),
|
|
2299
|
+
cwd: repoRoot
|
|
2300
|
+
};
|
|
2301
|
+
} catch {
|
|
2302
|
+
return { file, cwd };
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2168
2305
|
async function detectPlatform2(options) {
|
|
2169
2306
|
const warnings = [];
|
|
2170
2307
|
let adapter = null;
|
|
@@ -2211,7 +2348,7 @@ async function runBlameAndAuth(adapter, options, execOptions) {
|
|
|
2211
2348
|
}
|
|
2212
2349
|
return { analyzed: blameResult.value, operatingLevel, warnings };
|
|
2213
2350
|
}
|
|
2214
|
-
async function processEntry(entry, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan) {
|
|
2351
|
+
async function processEntry(entry, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan, preferredBase) {
|
|
2215
2352
|
const nodes = [];
|
|
2216
2353
|
const commitNode = {
|
|
2217
2354
|
type: entry.isCosmetic ? "cosmetic_commit" : "original_commit",
|
|
@@ -2245,14 +2382,16 @@ async function processEntry(entry, featureFlags, adapter, options, execOptions,
|
|
|
2245
2382
|
cacheOnly: options.cacheOnly,
|
|
2246
2383
|
deep: featureFlags.deepTrace,
|
|
2247
2384
|
repoId,
|
|
2248
|
-
skipPatchIdScan
|
|
2385
|
+
skipPatchIdScan,
|
|
2386
|
+
preferredBase,
|
|
2387
|
+
platform: adapter?.platform
|
|
2249
2388
|
});
|
|
2250
2389
|
if (prInfo) {
|
|
2251
2390
|
nodes.push({
|
|
2252
2391
|
type: "pull_request",
|
|
2253
2392
|
sha: prInfo.mergeCommit,
|
|
2254
|
-
trackingMethod: prInfo.
|
|
2255
|
-
confidence: prInfo.
|
|
2393
|
+
trackingMethod: resolvedViaToTrackingMethod(prInfo.resolvedVia),
|
|
2394
|
+
confidence: resolvedViaToConfidence(prInfo.resolvedVia),
|
|
2256
2395
|
prNumber: prInfo.number,
|
|
2257
2396
|
prUrl: prInfo.url || void 0,
|
|
2258
2397
|
prTitle: prInfo.title || void 0,
|
|
@@ -2262,7 +2401,7 @@ async function processEntry(entry, featureFlags, adapter, options, execOptions,
|
|
|
2262
2401
|
}
|
|
2263
2402
|
return nodes;
|
|
2264
2403
|
}
|
|
2265
|
-
async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan) {
|
|
2404
|
+
async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan, preferredBase) {
|
|
2266
2405
|
const results = await Promise.allSettled(
|
|
2267
2406
|
map8(
|
|
2268
2407
|
analyzed,
|
|
@@ -2273,7 +2412,8 @@ async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOpt
|
|
|
2273
2412
|
options,
|
|
2274
2413
|
execOptions,
|
|
2275
2414
|
repoId,
|
|
2276
|
-
skipPatchIdScan
|
|
2415
|
+
skipPatchIdScan,
|
|
2416
|
+
preferredBase
|
|
2277
2417
|
)
|
|
2278
2418
|
)
|
|
2279
2419
|
);
|
|
@@ -2281,13 +2421,15 @@ async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOpt
|
|
|
2281
2421
|
}
|
|
2282
2422
|
var legacyCacheCleaned = false;
|
|
2283
2423
|
async function trace(options) {
|
|
2284
|
-
const
|
|
2424
|
+
const { file, cwd } = await resolveFileContext(options.file, options.cwd);
|
|
2425
|
+
const warnings = [];
|
|
2426
|
+
const execOptions = { cwd, warnings };
|
|
2285
2427
|
if (!legacyCacheCleaned) {
|
|
2286
2428
|
legacyCacheCleaned = true;
|
|
2287
2429
|
cleanupLegacyCache().catch(() => {
|
|
2288
2430
|
});
|
|
2289
2431
|
}
|
|
2290
|
-
const platform = await detectPlatform2(options);
|
|
2432
|
+
const platform = await detectPlatform2({ ...options, cwd });
|
|
2291
2433
|
let repoId;
|
|
2292
2434
|
if (platform.remote) {
|
|
2293
2435
|
repoId = {
|
|
@@ -2296,15 +2438,15 @@ async function trace(options) {
|
|
|
2296
2438
|
repo: platform.remote.repo
|
|
2297
2439
|
};
|
|
2298
2440
|
} else {
|
|
2299
|
-
repoId = await resolveRepoIdentity(
|
|
2441
|
+
repoId = await resolveRepoIdentity(cwd);
|
|
2300
2442
|
}
|
|
2301
2443
|
const blameAuth = await runBlameAndAuth(
|
|
2302
2444
|
platform.adapter,
|
|
2303
|
-
options,
|
|
2445
|
+
{ ...options, file, cwd },
|
|
2304
2446
|
execOptions
|
|
2305
2447
|
);
|
|
2306
2448
|
const operatingLevel = blameAuth.operatingLevel || platform.operatingLevel;
|
|
2307
|
-
|
|
2449
|
+
warnings.push(...platform.warnings, ...blameAuth.warnings);
|
|
2308
2450
|
if (options.cacheOnly && options.noCache) {
|
|
2309
2451
|
warnings.push(
|
|
2310
2452
|
"Both cacheOnly and noCache are set. cacheOnly takes precedence \u2014 cache reads are enabled."
|
|
@@ -2313,13 +2455,13 @@ async function trace(options) {
|
|
|
2313
2455
|
const featureFlags = computeFeatureFlags(operatingLevel, options);
|
|
2314
2456
|
let cloneStatus = { partialClone: false, shallow: false };
|
|
2315
2457
|
try {
|
|
2316
|
-
const result = await checkCloneStatus({ cwd
|
|
2458
|
+
const result = await checkCloneStatus({ cwd });
|
|
2317
2459
|
if (result) cloneStatus = result;
|
|
2318
2460
|
} catch {
|
|
2319
2461
|
}
|
|
2320
2462
|
if (cloneStatus.partialClone) {
|
|
2321
2463
|
warnings.push(
|
|
2322
|
-
"Partial clone detected. Patch-ID scan (Strategy
|
|
2464
|
+
"Partial clone detected. Patch-ID scan (Strategy 5) will be skipped to avoid blob downloads."
|
|
2323
2465
|
);
|
|
2324
2466
|
}
|
|
2325
2467
|
if (cloneStatus.shallow) {
|
|
@@ -2327,14 +2469,27 @@ async function trace(options) {
|
|
|
2327
2469
|
"Shallow repository detected. Ancestry-path results may be incomplete."
|
|
2328
2470
|
);
|
|
2329
2471
|
}
|
|
2472
|
+
let preferredBase;
|
|
2473
|
+
try {
|
|
2474
|
+
const branchResult = await gitExec(
|
|
2475
|
+
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
2476
|
+
execOptions
|
|
2477
|
+
);
|
|
2478
|
+
const branch = branchResult.stdout.trim();
|
|
2479
|
+
if (branch && branch !== "HEAD") {
|
|
2480
|
+
preferredBase = branch;
|
|
2481
|
+
}
|
|
2482
|
+
} catch {
|
|
2483
|
+
}
|
|
2330
2484
|
const nodes = await buildTraceNodes(
|
|
2331
2485
|
blameAuth.analyzed,
|
|
2332
2486
|
featureFlags,
|
|
2333
2487
|
platform.adapter,
|
|
2334
|
-
options,
|
|
2488
|
+
{ ...options, file, cwd },
|
|
2335
2489
|
execOptions,
|
|
2336
2490
|
repoId,
|
|
2337
|
-
cloneStatus.partialClone || void 0
|
|
2491
|
+
cloneStatus.partialClone || void 0,
|
|
2492
|
+
preferredBase
|
|
2338
2493
|
);
|
|
2339
2494
|
return { nodes, operatingLevel, featureFlags, warnings };
|
|
2340
2495
|
}
|
|
@@ -14,7 +14,9 @@ export declare class GitHubAdapter implements PlatformAdapter {
|
|
|
14
14
|
cwd?: string;
|
|
15
15
|
});
|
|
16
16
|
checkAuth(): Promise<AuthStatus>;
|
|
17
|
-
getPRForCommit(sha: string
|
|
17
|
+
getPRForCommit(sha: string, options?: {
|
|
18
|
+
preferredBase?: string;
|
|
19
|
+
}): Promise<PRInfo | null>;
|
|
18
20
|
private detectDefaultBranch;
|
|
19
21
|
getPRCommits(prNumber: number): Promise<string[]>;
|
|
20
22
|
getLinkedIssues(prNumber: number): Promise<IssueInfo[]>;
|
|
@@ -14,7 +14,9 @@ export declare class GitLabAdapter implements PlatformAdapter {
|
|
|
14
14
|
cwd?: string;
|
|
15
15
|
});
|
|
16
16
|
checkAuth(): Promise<AuthStatus>;
|
|
17
|
-
getPRForCommit(sha: string
|
|
17
|
+
getPRForCommit(sha: string, options?: {
|
|
18
|
+
preferredBase?: string;
|
|
19
|
+
}): Promise<PRInfo | null>;
|
|
18
20
|
private detectDefaultBranch;
|
|
19
21
|
getPRCommits(prNumber: number): Promise<string[]>;
|
|
20
22
|
getLinkedIssues(prNumber: number): Promise<IssueInfo[]>;
|
package/dist/types/cache.d.ts
CHANGED
package/dist/types/git.d.ts
CHANGED
package/dist/types/platform.d.ts
CHANGED
|
@@ -36,7 +36,9 @@ export interface RateLimitInfo {
|
|
|
36
36
|
export interface PlatformAdapter {
|
|
37
37
|
readonly platform: PlatformType;
|
|
38
38
|
checkAuth(): Promise<AuthStatus>;
|
|
39
|
-
getPRForCommit(sha: string
|
|
39
|
+
getPRForCommit(sha: string, options?: {
|
|
40
|
+
preferredBase?: string;
|
|
41
|
+
}): Promise<PRInfo | null>;
|
|
40
42
|
getPRCommits(prNumber: number): Promise<string[]>;
|
|
41
43
|
getLinkedIssues(prNumber: number): Promise<IssueInfo[]>;
|
|
42
44
|
getLinkedPRs(issueNumber: number): Promise<PRInfo[]>;
|
package/dist/version.d.ts
CHANGED