@biffo/cli 0.296.17 → 0.297.1
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/index.js +85 -106
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -573,7 +573,25 @@ import { execSync as execSync2 } from "child_process";
|
|
|
573
573
|
import { existsSync as existsSync15, rmSync as rmSync5 } from "fs";
|
|
574
574
|
import { join as join16, resolve as resolve3 } from "path";
|
|
575
575
|
import chalk4 from "chalk";
|
|
576
|
-
|
|
576
|
+
|
|
577
|
+
// src/lib/exec.ts
|
|
578
|
+
import { execa as rawExeca } from "execa";
|
|
579
|
+
var execTimeoutMs = () => {
|
|
580
|
+
const raw = process.env.BIFFO_EXEC_TIMEOUT_MS;
|
|
581
|
+
const parsed = raw === void 0 ? Number.NaN : Number(raw);
|
|
582
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 9e5;
|
|
583
|
+
};
|
|
584
|
+
var execa = (file, args, options) => {
|
|
585
|
+
const opts = options ?? {};
|
|
586
|
+
const supplied = "stdin" in opts || "input" in opts;
|
|
587
|
+
return rawExeca(file, args ?? [], {
|
|
588
|
+
...supplied ? {} : { stdin: "ignore" },
|
|
589
|
+
timeout: execTimeoutMs(),
|
|
590
|
+
...opts
|
|
591
|
+
});
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
// src/commands/core-upgrade.ts
|
|
577
595
|
import { Command as Command3 } from "commander";
|
|
578
596
|
|
|
579
597
|
// src/adapters/git/index.ts
|
|
@@ -581,7 +599,6 @@ import { randomUUID } from "crypto";
|
|
|
581
599
|
import { existsSync as existsSync6, mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
|
|
582
600
|
import { tmpdir as tmpdir2 } from "os";
|
|
583
601
|
import { join as join6 } from "path";
|
|
584
|
-
import { execa as execa2 } from "execa";
|
|
585
602
|
|
|
586
603
|
// src/lib/core-upgrade.ts
|
|
587
604
|
import { isUtf8 } from "buffer";
|
|
@@ -597,7 +614,6 @@ import {
|
|
|
597
614
|
} from "fs";
|
|
598
615
|
import { tmpdir } from "os";
|
|
599
616
|
import { dirname as dirname3, join as join5 } from "path";
|
|
600
|
-
import { execa } from "execa";
|
|
601
617
|
import { z as z4 } from "zod";
|
|
602
618
|
|
|
603
619
|
// src/lib/core-ownership-guard.ts
|
|
@@ -953,7 +969,7 @@ var GitAdapter = class {
|
|
|
953
969
|
async configuredIdentity(cwd) {
|
|
954
970
|
const read2 = async (key) => {
|
|
955
971
|
try {
|
|
956
|
-
const { stdout } = await
|
|
972
|
+
const { stdout } = await execa("git", ["config", "--get", key], cwd ? { cwd } : {});
|
|
957
973
|
return stdout.trim() || null;
|
|
958
974
|
} catch {
|
|
959
975
|
return null;
|
|
@@ -963,7 +979,7 @@ var GitAdapter = class {
|
|
|
963
979
|
}
|
|
964
980
|
async isGitRepo(cwd) {
|
|
965
981
|
try {
|
|
966
|
-
await
|
|
982
|
+
await execa("git", ["rev-parse", "--is-inside-work-tree"], { cwd });
|
|
967
983
|
return true;
|
|
968
984
|
} catch {
|
|
969
985
|
return false;
|
|
@@ -988,7 +1004,7 @@ var GitAdapter = class {
|
|
|
988
1004
|
const dir = mkdtempSync2(join6(tmpdir2(), `${namePrefix}-${randomUUID().slice(0, 8)}-`));
|
|
989
1005
|
const cloneUrl = token ? injectToken(repoUrl, token) : repoUrl;
|
|
990
1006
|
try {
|
|
991
|
-
await
|
|
1007
|
+
await execa("git", ["clone", "--depth", "1", cloneUrl, dir]);
|
|
992
1008
|
} catch (err) {
|
|
993
1009
|
rmSync2(dir, { recursive: true, force: true });
|
|
994
1010
|
throw gitFailure(`Failed to clone ${repoUrl}`, err, [token]);
|
|
@@ -1011,7 +1027,7 @@ var GitAdapter = class {
|
|
|
1011
1027
|
const dir = mkdtempSync2(join6(tmpdir2(), `${namePrefix}-${randomUUID().slice(0, 8)}-`));
|
|
1012
1028
|
const cloneUrl = token ? injectToken(repoUrl, token) : repoUrl;
|
|
1013
1029
|
try {
|
|
1014
|
-
await
|
|
1030
|
+
await execa("git", ["clone", cloneUrl, dir]);
|
|
1015
1031
|
} catch (err) {
|
|
1016
1032
|
rmSync2(dir, { recursive: true, force: true });
|
|
1017
1033
|
throw gitFailure(`Failed to clone ${repoUrl}`, err, [token]);
|
|
@@ -1035,26 +1051,26 @@ var GitAdapter = class {
|
|
|
1035
1051
|
* repo uses (#559).
|
|
1036
1052
|
*/
|
|
1037
1053
|
async init(cwd, initialBranch = "dev") {
|
|
1038
|
-
await
|
|
1054
|
+
await execa("git", ["init", "-b", initialBranch], { cwd });
|
|
1039
1055
|
}
|
|
1040
1056
|
/** Adds a remote. Fails if a remote with this name already exists. */
|
|
1041
1057
|
async addRemote(cwd, name, url) {
|
|
1042
|
-
await
|
|
1058
|
+
await execa("git", ["remote", "add", name, url], { cwd });
|
|
1043
1059
|
}
|
|
1044
1060
|
async add(cwd, paths) {
|
|
1045
|
-
await
|
|
1061
|
+
await execa("git", ["add", ...paths], { cwd });
|
|
1046
1062
|
}
|
|
1047
1063
|
async commit(cwd, message) {
|
|
1048
|
-
await
|
|
1064
|
+
await execa("git", ["commit", "-m", message], { cwd });
|
|
1049
1065
|
}
|
|
1050
1066
|
/** The current branch name (e.g. "dev"). */
|
|
1051
1067
|
async currentBranch(cwd) {
|
|
1052
|
-
const { stdout } = await
|
|
1068
|
+
const { stdout } = await execa("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd });
|
|
1053
1069
|
return stdout.trim();
|
|
1054
1070
|
}
|
|
1055
1071
|
/** True if the working tree or index has uncommitted changes. */
|
|
1056
1072
|
async hasUncommittedChanges(cwd) {
|
|
1057
|
-
const { stdout } = await
|
|
1073
|
+
const { stdout } = await execa("git", ["status", "--porcelain"], { cwd });
|
|
1058
1074
|
return stdout.trim().length > 0;
|
|
1059
1075
|
}
|
|
1060
1076
|
/** Best-effort fetch of the tracking remote, so the ahead/behind check below
|
|
@@ -1062,13 +1078,13 @@ var GitAdapter = class {
|
|
|
1062
1078
|
* offline or a missing remote must not block an upgrade on its own — the
|
|
1063
1079
|
* ahead/behind check that follows simply works from whatever is local. */
|
|
1064
1080
|
async fetch(cwd, remote = "origin") {
|
|
1065
|
-
await
|
|
1081
|
+
await execa("git", ["fetch", "--quiet", remote], { cwd, reject: false });
|
|
1066
1082
|
}
|
|
1067
1083
|
/** HEAD's position relative to its upstream. `hasUpstream` is false when the
|
|
1068
1084
|
* branch tracks nothing (or HEAD is detached), in which case currency cannot
|
|
1069
1085
|
* be established and ahead/behind are 0 (#394). */
|
|
1070
1086
|
async aheadBehind(cwd) {
|
|
1071
|
-
const { stdout, exitCode } = await
|
|
1087
|
+
const { stdout, exitCode } = await execa(
|
|
1072
1088
|
"git",
|
|
1073
1089
|
["rev-list", "--left-right", "--count", "HEAD...@{upstream}"],
|
|
1074
1090
|
{ cwd, reject: false }
|
|
@@ -1079,7 +1095,7 @@ var GitAdapter = class {
|
|
|
1079
1095
|
}
|
|
1080
1096
|
/** The fetch URL of a remote (default "origin"). */
|
|
1081
1097
|
async getRemoteUrl(cwd, remote = "origin") {
|
|
1082
|
-
const { stdout } = await
|
|
1098
|
+
const { stdout } = await execa("git", ["remote", "get-url", remote], { cwd });
|
|
1083
1099
|
return stdout.trim();
|
|
1084
1100
|
}
|
|
1085
1101
|
/**
|
|
@@ -1092,7 +1108,7 @@ var GitAdapter = class {
|
|
|
1092
1108
|
* SHA as an honest "could not determine", never as license to invent one.
|
|
1093
1109
|
*/
|
|
1094
1110
|
async resolveDefaultBranchSha(repoUrl) {
|
|
1095
|
-
const { stdout, exitCode } = await
|
|
1111
|
+
const { stdout, exitCode } = await execa("git", ["ls-remote", "--exit-code", repoUrl, "HEAD"], {
|
|
1096
1112
|
reject: false
|
|
1097
1113
|
});
|
|
1098
1114
|
if (exitCode !== 0) return null;
|
|
@@ -1110,7 +1126,7 @@ var GitAdapter = class {
|
|
|
1110
1126
|
* equally best-effort call.
|
|
1111
1127
|
*/
|
|
1112
1128
|
async fetchPrune(cwd, remote = "origin") {
|
|
1113
|
-
await
|
|
1129
|
+
await execa("git", ["fetch", "--quiet", "--prune", remote], { cwd, reject: false });
|
|
1114
1130
|
}
|
|
1115
1131
|
/**
|
|
1116
1132
|
* Is `cwd` the primary checkout, rather than a linked worktree?
|
|
@@ -1127,8 +1143,8 @@ var GitAdapter = class {
|
|
|
1127
1143
|
async isPrimaryWorktree(cwd) {
|
|
1128
1144
|
const opts = { cwd, reject: false };
|
|
1129
1145
|
const [dir, common] = await Promise.all([
|
|
1130
|
-
|
|
1131
|
-
|
|
1146
|
+
execa("git", ["rev-parse", "--absolute-git-dir"], opts),
|
|
1147
|
+
execa("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], opts)
|
|
1132
1148
|
]);
|
|
1133
1149
|
if (dir.exitCode !== 0 || common.exitCode !== 0) return true;
|
|
1134
1150
|
return dir.stdout.trim() === common.stdout.trim();
|
|
@@ -1140,7 +1156,7 @@ var GitAdapter = class {
|
|
|
1140
1156
|
* annotations vary, and this has to survive paths with spaces.
|
|
1141
1157
|
*/
|
|
1142
1158
|
async listWorktrees(cwd) {
|
|
1143
|
-
const { stdout, exitCode } = await
|
|
1159
|
+
const { stdout, exitCode } = await execa("git", ["worktree", "list", "--porcelain"], {
|
|
1144
1160
|
cwd,
|
|
1145
1161
|
reject: false
|
|
1146
1162
|
});
|
|
@@ -1158,7 +1174,7 @@ var GitAdapter = class {
|
|
|
1158
1174
|
}
|
|
1159
1175
|
/** How many commits `branch` is behind `base`; null when it cannot be measured. */
|
|
1160
1176
|
async countBehind(cwd, branch, base) {
|
|
1161
|
-
const { stdout, exitCode } = await
|
|
1177
|
+
const { stdout, exitCode } = await execa("git", ["rev-list", "--count", `${branch}..${base}`], {
|
|
1162
1178
|
cwd,
|
|
1163
1179
|
reject: false
|
|
1164
1180
|
});
|
|
@@ -1168,7 +1184,7 @@ var GitAdapter = class {
|
|
|
1168
1184
|
}
|
|
1169
1185
|
/** A file's contents at a ref, or null when it is absent there. */
|
|
1170
1186
|
async showFileAtRef(cwd, ref, path) {
|
|
1171
|
-
const { stdout, exitCode } = await
|
|
1187
|
+
const { stdout, exitCode } = await execa("git", ["show", `${ref}:${path}`], {
|
|
1172
1188
|
cwd,
|
|
1173
1189
|
reject: false
|
|
1174
1190
|
});
|
|
@@ -1176,7 +1192,7 @@ var GitAdapter = class {
|
|
|
1176
1192
|
}
|
|
1177
1193
|
/** Every local branch with its upstream and tracking state (#758). */
|
|
1178
1194
|
async listBranchRefs(cwd) {
|
|
1179
|
-
const { stdout, exitCode } = await
|
|
1195
|
+
const { stdout, exitCode } = await execa(
|
|
1180
1196
|
"git",
|
|
1181
1197
|
["for-each-ref", `--format=${BRANCH_REF_FORMAT}`, "refs/heads"],
|
|
1182
1198
|
{ cwd, reject: false }
|
|
@@ -1194,12 +1210,12 @@ var GitAdapter = class {
|
|
|
1194
1210
|
* passes branches whose upstream git reports as gone.
|
|
1195
1211
|
*/
|
|
1196
1212
|
async deleteBranch(cwd, branch) {
|
|
1197
|
-
const { exitCode } = await
|
|
1213
|
+
const { exitCode } = await execa("git", ["branch", "-D", branch], { cwd, reject: false });
|
|
1198
1214
|
return exitCode === 0;
|
|
1199
1215
|
}
|
|
1200
1216
|
/** Create and switch to a new branch. Fails if it already exists. */
|
|
1201
1217
|
async createBranch(cwd, branch) {
|
|
1202
|
-
await
|
|
1218
|
+
await execa("git", ["switch", "-c", branch], { cwd });
|
|
1203
1219
|
}
|
|
1204
1220
|
/**
|
|
1205
1221
|
* Switch to an existing branch. Fails if it does not exist, and — deliberately
|
|
@@ -1208,7 +1224,7 @@ var GitAdapter = class {
|
|
|
1208
1224
|
* putting back.
|
|
1209
1225
|
*/
|
|
1210
1226
|
async switchBranch(cwd, branch) {
|
|
1211
|
-
await
|
|
1227
|
+
await execa("git", ["switch", branch], { cwd });
|
|
1212
1228
|
}
|
|
1213
1229
|
/**
|
|
1214
1230
|
* Push the current HEAD to `branch` on the remote. When `token` is given and
|
|
@@ -1232,7 +1248,7 @@ var GitAdapter = class {
|
|
|
1232
1248
|
if (authed !== url) target = authed;
|
|
1233
1249
|
}
|
|
1234
1250
|
try {
|
|
1235
|
-
await
|
|
1251
|
+
await execa("git", ["push", target, `HEAD:refs/heads/${branch}`], { cwd });
|
|
1236
1252
|
} catch (err) {
|
|
1237
1253
|
throw gitFailure(`Failed to push branch '${branch}' to remote '${remote}'`, err, [opts.token]);
|
|
1238
1254
|
}
|
|
@@ -1283,9 +1299,9 @@ var GitAdapter = class {
|
|
|
1283
1299
|
*/
|
|
1284
1300
|
async setUpstreamAfterPush(cwd, branch, remote) {
|
|
1285
1301
|
const opts = { cwd, reject: false };
|
|
1286
|
-
await
|
|
1287
|
-
await
|
|
1288
|
-
await
|
|
1302
|
+
await execa("git", ["update-ref", `refs/remotes/${remote}/${branch}`, "HEAD"], opts);
|
|
1303
|
+
await execa("git", ["config", `branch.${branch}.remote`, remote], opts);
|
|
1304
|
+
await execa("git", ["config", `branch.${branch}.merge`, `refs/heads/${branch}`], opts);
|
|
1289
1305
|
}
|
|
1290
1306
|
};
|
|
1291
1307
|
function injectToken(repoUrl, token) {
|
|
@@ -4296,7 +4312,7 @@ var defaultRunCommand = async (command, cwd) => {
|
|
|
4296
4312
|
const [bin, ...args] = command;
|
|
4297
4313
|
if (!bin) return { ok: false, error: "empty command" };
|
|
4298
4314
|
try {
|
|
4299
|
-
await
|
|
4315
|
+
await execa(bin, args, {
|
|
4300
4316
|
cwd,
|
|
4301
4317
|
// TWO REASONS THIS HUNG FOR 29 HOURS, AND THE FIX NEEDS BOTH.
|
|
4302
4318
|
//
|
|
@@ -8707,7 +8723,6 @@ import chalk15 from "chalk";
|
|
|
8707
8723
|
import { Command as Command15 } from "commander";
|
|
8708
8724
|
|
|
8709
8725
|
// src/adapters/plugin-migrations/index.ts
|
|
8710
|
-
import { execa as execa4 } from "execa";
|
|
8711
8726
|
import { join as join28 } from "path";
|
|
8712
8727
|
var PluginMigrationsAdapter = class {
|
|
8713
8728
|
/**
|
|
@@ -8732,7 +8747,7 @@ var PluginMigrationsAdapter = class {
|
|
|
8732
8747
|
}
|
|
8733
8748
|
let result;
|
|
8734
8749
|
try {
|
|
8735
|
-
result = await
|
|
8750
|
+
result = await execa("uv", args, { cwd: join28(cwd, "services", "api") });
|
|
8736
8751
|
} catch (err) {
|
|
8737
8752
|
const cause = err;
|
|
8738
8753
|
if (cause.code === "ENOENT") {
|
|
@@ -8751,7 +8766,6 @@ var PluginMigrationsAdapter = class {
|
|
|
8751
8766
|
// src/lib/plugin-provenance.ts
|
|
8752
8767
|
import { existsSync as existsSync28, readFileSync as readFileSync21, writeFileSync as writeFileSync10 } from "fs";
|
|
8753
8768
|
import { join as join29 } from "path";
|
|
8754
|
-
import { execa as execa5 } from "execa";
|
|
8755
8769
|
var PLUGIN_PROVENANCE_FILENAME = ".biffo-plugin-provenance.json";
|
|
8756
8770
|
function isPluginProvenance(value) {
|
|
8757
8771
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -8813,7 +8827,7 @@ function resolveRegistryProvenance(repoUrl, sha) {
|
|
|
8813
8827
|
}
|
|
8814
8828
|
async function isGitWorkingTree(dir) {
|
|
8815
8829
|
try {
|
|
8816
|
-
await
|
|
8830
|
+
await execa("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
|
|
8817
8831
|
return true;
|
|
8818
8832
|
} catch {
|
|
8819
8833
|
return false;
|
|
@@ -8821,7 +8835,7 @@ async function isGitWorkingTree(dir) {
|
|
|
8821
8835
|
}
|
|
8822
8836
|
async function tryGit(cwd, args) {
|
|
8823
8837
|
try {
|
|
8824
|
-
const { stdout } = await
|
|
8838
|
+
const { stdout } = await execa("git", args, { cwd });
|
|
8825
8839
|
return stdout.trim() || null;
|
|
8826
8840
|
} catch {
|
|
8827
8841
|
return null;
|
|
@@ -8870,7 +8884,6 @@ function vendorPluginSeed(pluginSourceDir, manifest, cwd) {
|
|
|
8870
8884
|
// src/lib/plugin-source-copy.ts
|
|
8871
8885
|
import { copyFileSync as copyFileSync2, cpSync as cpSync4, mkdirSync as mkdirSync10 } from "fs";
|
|
8872
8886
|
import { basename, dirname as dirname9, join as join31 } from "path";
|
|
8873
|
-
import { execa as execa6 } from "execa";
|
|
8874
8887
|
var LOCAL_COPY_EXCLUDES = /* @__PURE__ */ new Set([
|
|
8875
8888
|
".git",
|
|
8876
8889
|
".venv",
|
|
@@ -8904,14 +8917,14 @@ async function copyPluginSource(sourceDir, targetDir) {
|
|
|
8904
8917
|
}
|
|
8905
8918
|
async function isGitWorkingTree2(dir) {
|
|
8906
8919
|
try {
|
|
8907
|
-
await
|
|
8920
|
+
await execa("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
|
|
8908
8921
|
return true;
|
|
8909
8922
|
} catch {
|
|
8910
8923
|
return false;
|
|
8911
8924
|
}
|
|
8912
8925
|
}
|
|
8913
8926
|
async function listGitFiles(dir) {
|
|
8914
|
-
const { stdout } = await
|
|
8927
|
+
const { stdout } = await execa(
|
|
8915
8928
|
"git",
|
|
8916
8929
|
["ls-files", "--cached", "--others", "--exclude-standard", "-z"],
|
|
8917
8930
|
{ cwd: dir }
|
|
@@ -9851,7 +9864,6 @@ import { cpSync as cpSync6, existsSync as existsSync36, mkdirSync as mkdirSync12
|
|
|
9851
9864
|
import { join as join38, relative as relative7, resolve as resolve17 } from "path";
|
|
9852
9865
|
import chalk19 from "chalk";
|
|
9853
9866
|
import { Command as Command20 } from "commander";
|
|
9854
|
-
import { execa as execa7 } from "execa";
|
|
9855
9867
|
import inquirer7 from "inquirer";
|
|
9856
9868
|
var pluginUpgradeCommand = new Command20("upgrade").description(
|
|
9857
9869
|
"Upgrade an installed plugin to a new minor version (biffo plugin upgrade <name>@<new-minor>) or refresh it in place from a local, unpublished checkout (biffo plugin upgrade --local <path>)"
|
|
@@ -10180,7 +10192,7 @@ var defaultRunCommand2 = async (command, cwd) => {
|
|
|
10180
10192
|
const [bin, ...args] = command;
|
|
10181
10193
|
if (!bin) return { ok: false, error: "empty command" };
|
|
10182
10194
|
try {
|
|
10183
|
-
await
|
|
10195
|
+
await execa(bin, args, {
|
|
10184
10196
|
cwd,
|
|
10185
10197
|
// TWO REASONS THIS HUNG FOR 29 HOURS, AND THE FIX NEEDS BOTH.
|
|
10186
10198
|
//
|
|
@@ -10590,7 +10602,6 @@ import { Command as Command24 } from "commander";
|
|
|
10590
10602
|
// src/scripts/check-adr-numbering.ts
|
|
10591
10603
|
import { existsSync as existsSync39 } from "fs";
|
|
10592
10604
|
import { join as join40 } from "path";
|
|
10593
|
-
import { execa as execa8 } from "execa";
|
|
10594
10605
|
|
|
10595
10606
|
// src/lib/adr-numbering-guard.ts
|
|
10596
10607
|
import { existsSync as existsSync38, readdirSync as readdirSync15, readFileSync as readFileSync29 } from "fs";
|
|
@@ -10664,7 +10675,7 @@ function formatAdrReservedRangeViolations(violations, reservedUpTo = TEMPLATE_AD
|
|
|
10664
10675
|
|
|
10665
10676
|
// src/scripts/check-adr-numbering.ts
|
|
10666
10677
|
async function runAdrNumberingCheck() {
|
|
10667
|
-
const root = (await
|
|
10678
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
10668
10679
|
const adrDir = join40(root, "docs", "ADR");
|
|
10669
10680
|
if (!existsSync39(adrDir)) {
|
|
10670
10681
|
console.log("\u2713 ADR numbering guard: no docs/ADR/ directory \u2014 nothing to compare");
|
|
@@ -10705,7 +10716,6 @@ Already accepted? List it in docs/ADR/${ALLOWLIST_FILENAME} instead of leaving t
|
|
|
10705
10716
|
|
|
10706
10717
|
// src/scripts/check-branch-protection.ts
|
|
10707
10718
|
import { Octokit as Octokit2 } from "@octokit/rest";
|
|
10708
|
-
import { execa as execa9 } from "execa";
|
|
10709
10719
|
|
|
10710
10720
|
// src/lib/branch-protection-apply.ts
|
|
10711
10721
|
var CONTEXT_CONSISTENCY_THRESHOLD = 2 / 3;
|
|
@@ -10832,7 +10842,7 @@ async function resolveRepo(explicit) {
|
|
|
10832
10842
|
}
|
|
10833
10843
|
return { owner, repo };
|
|
10834
10844
|
}
|
|
10835
|
-
const { stdout } = await
|
|
10845
|
+
const { stdout } = await execa("git", ["remote", "get-url", "origin"]);
|
|
10836
10846
|
const m = /github\.com[:/]([^/]+)\/(.+?)(?:\.git)?$/.exec(stdout.trim());
|
|
10837
10847
|
if (!m?.[1] || !m[2]) {
|
|
10838
10848
|
console.error(
|
|
@@ -10963,9 +10973,6 @@ async function runBranchProtectionCheck(explicitRepo, options = {}) {
|
|
|
10963
10973
|
console.log(`\u2713 branch-protection guard: ${owner}/${repo} (${audited.join(", ")}) OK`);
|
|
10964
10974
|
}
|
|
10965
10975
|
|
|
10966
|
-
// src/scripts/check-claim-invocation.ts
|
|
10967
|
-
import { execa as execa10 } from "execa";
|
|
10968
|
-
|
|
10969
10976
|
// src/lib/claim-invocation-parity.ts
|
|
10970
10977
|
import { existsSync as existsSync40, readFileSync as readFileSync30, readdirSync as readdirSync16 } from "fs";
|
|
10971
10978
|
import { join as join41 } from "path";
|
|
@@ -11090,7 +11097,7 @@ function formatParityViolations(violations) {
|
|
|
11090
11097
|
|
|
11091
11098
|
// src/scripts/check-claim-invocation.ts
|
|
11092
11099
|
async function runClaimInvocationCheck() {
|
|
11093
|
-
const root = (await
|
|
11100
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11094
11101
|
const docs = distributedAgentsDocs(root);
|
|
11095
11102
|
console.log(
|
|
11096
11103
|
`audited ${docs.length} distributed AGENTS.md (${docs.map((d) => d.path).join(", ") || "none"}) under ${root}`
|
|
@@ -11112,7 +11119,6 @@ async function runClaimInvocationCheck() {
|
|
|
11112
11119
|
// src/scripts/check-codeql-suppression.ts
|
|
11113
11120
|
import { existsSync as existsSync41 } from "fs";
|
|
11114
11121
|
import { join as join43, relative as relative8 } from "path";
|
|
11115
|
-
import { execa as execa11 } from "execa";
|
|
11116
11122
|
|
|
11117
11123
|
// src/lib/codeql-suppression-guard.ts
|
|
11118
11124
|
import { readdirSync as readdirSync17, readFileSync as readFileSync31, statSync as statSync9 } from "fs";
|
|
@@ -11183,7 +11189,7 @@ function sweepCodeqlSuppressionComments(root) {
|
|
|
11183
11189
|
|
|
11184
11190
|
// src/scripts/check-codeql-suppression.ts
|
|
11185
11191
|
async function runCodeqlSuppressionCheck() {
|
|
11186
|
-
const root = (await
|
|
11192
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11187
11193
|
const scanRoot = join43(root, "cli", "src");
|
|
11188
11194
|
if (!existsSync41(scanRoot)) {
|
|
11189
11195
|
console.log(
|
|
@@ -11208,9 +11214,6 @@ async function runCodeqlSuppressionCheck() {
|
|
|
11208
11214
|
console.log("\u2713 codeql-suppression guard: no dead `codeql[...]` suppression comment found");
|
|
11209
11215
|
}
|
|
11210
11216
|
|
|
11211
|
-
// src/scripts/check-cognito-invite-template.ts
|
|
11212
|
-
import { execa as execa12 } from "execa";
|
|
11213
|
-
|
|
11214
11217
|
// src/lib/cognito-invite-template-guard.ts
|
|
11215
11218
|
import { readdirSync as readdirSync18, readFileSync as readFileSync32, statSync as statSync10 } from "fs";
|
|
11216
11219
|
import { join as join44 } from "path";
|
|
@@ -11316,7 +11319,7 @@ function checkCognitoInviteTemplates(repoRoot) {
|
|
|
11316
11319
|
|
|
11317
11320
|
// src/scripts/check-cognito-invite-template.ts
|
|
11318
11321
|
async function runCognitoInviteTemplateCheck() {
|
|
11319
|
-
const root = (await
|
|
11322
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11320
11323
|
const files = findModuleTerraformFiles(root);
|
|
11321
11324
|
console.log(`audited ${files.length} .tf file(s) under modules/ under ${root}`);
|
|
11322
11325
|
if (files.length === 0) {
|
|
@@ -11339,7 +11342,6 @@ async function runCognitoInviteTemplateCheck() {
|
|
|
11339
11342
|
|
|
11340
11343
|
// src/scripts/check-core-direct-paths.ts
|
|
11341
11344
|
import { join as join46 } from "path";
|
|
11342
|
-
import { execa as execa13 } from "execa";
|
|
11343
11345
|
|
|
11344
11346
|
// src/lib/core-direct-paths-audit.ts
|
|
11345
11347
|
import { existsSync as existsSync42, readFileSync as readFileSync33, readdirSync as readdirSync19, statSync as statSync11 } from "fs";
|
|
@@ -11667,7 +11669,7 @@ function auditSiblingCoreDirectPaths(params) {
|
|
|
11667
11669
|
|
|
11668
11670
|
// src/scripts/check-core-direct-paths.ts
|
|
11669
11671
|
async function runCoreDirectPathsCheck(opts = {}) {
|
|
11670
|
-
const root = (await
|
|
11672
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11671
11673
|
const sibling = opts.sibling ?? "sibling-template (self-check)";
|
|
11672
11674
|
const frontendSrcDir = opts.frontendSrc ?? join46(root, "_skeletons", "sibling-template", "apps", "frontend", "src");
|
|
11673
11675
|
let coreApiSrcDir;
|
|
@@ -11721,7 +11723,6 @@ async function runCoreDirectPathsCheck(opts = {}) {
|
|
|
11721
11723
|
}
|
|
11722
11724
|
|
|
11723
11725
|
// src/scripts/check-core-ownership.ts
|
|
11724
|
-
import { execa as execa14 } from "execa";
|
|
11725
11726
|
var BOLD = "\x1B[1m";
|
|
11726
11727
|
var DIM = "\x1B[2m";
|
|
11727
11728
|
var RED = "\x1B[31m";
|
|
@@ -11732,7 +11733,7 @@ async function runOwnershipCheck(argv) {
|
|
|
11732
11733
|
const stagedFlag = args.indexOf("--staged");
|
|
11733
11734
|
const staged = stagedFlag !== -1;
|
|
11734
11735
|
const messageFile = staged ? args[stagedFlag + 1] : void 0;
|
|
11735
|
-
const root = (await
|
|
11736
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11736
11737
|
const ownership = classifyRepoOwnership(root);
|
|
11737
11738
|
if (ownership === "template") {
|
|
11738
11739
|
console.log("\u2713 core ownership guard: skipped \u2014 this is the template, which owns these paths.");
|
|
@@ -11748,7 +11749,7 @@ async function runOwnershipCheck(argv) {
|
|
|
11748
11749
|
let deletedFiles = [];
|
|
11749
11750
|
let commitMessage = "";
|
|
11750
11751
|
if (staged) {
|
|
11751
|
-
const { stdout } = await
|
|
11752
|
+
const { stdout } = await execa("git", ["diff", "--cached", "--name-status"], { cwd: root });
|
|
11752
11753
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
11753
11754
|
if (messageFile) {
|
|
11754
11755
|
const { readFileSync: readFileSync45, existsSync: existsSync54 } = await import("fs");
|
|
@@ -11760,18 +11761,18 @@ async function runOwnershipCheck(argv) {
|
|
|
11760
11761
|
console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
|
|
11761
11762
|
process.exit(2);
|
|
11762
11763
|
}
|
|
11763
|
-
await
|
|
11764
|
-
const { stdout } = await
|
|
11764
|
+
await execa("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
|
|
11765
|
+
const { stdout } = await execa("git", ["diff", "--name-status", `origin/${base}...HEAD`], {
|
|
11765
11766
|
cwd: root
|
|
11766
11767
|
});
|
|
11767
11768
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
11768
|
-
const { stdout: log2 } = await
|
|
11769
|
+
const { stdout: log2 } = await execa("git", ["log", "--format=%B", `origin/${base}..HEAD`], {
|
|
11769
11770
|
cwd: root,
|
|
11770
11771
|
reject: false
|
|
11771
11772
|
});
|
|
11772
11773
|
commitMessage = log2;
|
|
11773
11774
|
}
|
|
11774
|
-
const { stdout: gitBranch } = await
|
|
11775
|
+
const { stdout: gitBranch } = await execa("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
11775
11776
|
cwd: root,
|
|
11776
11777
|
reject: false
|
|
11777
11778
|
});
|
|
@@ -11852,9 +11853,6 @@ ${BOLD}If the divergence is deliberate${OFF}
|
|
|
11852
11853
|
process.exit(1);
|
|
11853
11854
|
}
|
|
11854
11855
|
|
|
11855
|
-
// src/scripts/check-eventbridge-log-permissions.ts
|
|
11856
|
-
import { execa as execa15 } from "execa";
|
|
11857
|
-
|
|
11858
11856
|
// src/lib/eventbridge-log-permission-guard.ts
|
|
11859
11857
|
import { readFileSync as readFileSync34, readdirSync as readdirSync20, statSync as statSync12 } from "fs";
|
|
11860
11858
|
import { join as join47 } from "path";
|
|
@@ -12030,7 +12028,7 @@ function auditEventBridgeLogPermissions(root) {
|
|
|
12030
12028
|
|
|
12031
12029
|
// src/scripts/check-eventbridge-log-permissions.ts
|
|
12032
12030
|
async function runEventBridgeLogPermissionCheck() {
|
|
12033
|
-
const root = (await
|
|
12031
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12034
12032
|
let report;
|
|
12035
12033
|
try {
|
|
12036
12034
|
report = auditEventBridgeLogPermissions(root);
|
|
@@ -12069,7 +12067,6 @@ async function runEventBridgeLogPermissionCheck() {
|
|
|
12069
12067
|
// src/scripts/check-instance-adoption.ts
|
|
12070
12068
|
import { existsSync as existsSync43 } from "fs";
|
|
12071
12069
|
import { join as join48 } from "path";
|
|
12072
|
-
import { execa as execa16 } from "execa";
|
|
12073
12070
|
async function runInstanceAdoptionCheck(opts = {}) {
|
|
12074
12071
|
if (!opts.instanceDir) {
|
|
12075
12072
|
console.error(
|
|
@@ -12083,7 +12080,7 @@ async function runInstanceAdoptionCheck(opts = {}) {
|
|
|
12083
12080
|
);
|
|
12084
12081
|
process.exit(2);
|
|
12085
12082
|
}
|
|
12086
|
-
const root = (await
|
|
12083
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12087
12084
|
const theirsDir = opts.theirsDir ?? root;
|
|
12088
12085
|
const instanceLabel = opts.instance ?? join48(opts.instanceDir).split("/").filter(Boolean).pop();
|
|
12089
12086
|
const report = checkInstanceAdoption(theirsDir, opts.instanceDir);
|
|
@@ -12106,9 +12103,6 @@ async function runInstanceAdoptionCheck(opts = {}) {
|
|
|
12106
12103
|
process.exit(1);
|
|
12107
12104
|
}
|
|
12108
12105
|
|
|
12109
|
-
// src/scripts/check-lambda-output.ts
|
|
12110
|
-
import { execa as execa17 } from "execa";
|
|
12111
|
-
|
|
12112
12106
|
// src/lib/lambda-output-guard.ts
|
|
12113
12107
|
import { readFileSync as readFileSync36 } from "fs";
|
|
12114
12108
|
import { join as join50 } from "path";
|
|
@@ -12269,7 +12263,7 @@ function checkLambdaOutput(repoRoot) {
|
|
|
12269
12263
|
|
|
12270
12264
|
// src/scripts/check-lambda-output.ts
|
|
12271
12265
|
async function runLambdaOutputCheck() {
|
|
12272
|
-
const root = (await
|
|
12266
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12273
12267
|
const files = findWorkflowFiles(root);
|
|
12274
12268
|
console.log(`audited ${files.length} workflow file(s) under ${root}`);
|
|
12275
12269
|
if (files.length === 0) {
|
|
@@ -12291,7 +12285,6 @@ async function runLambdaOutputCheck() {
|
|
|
12291
12285
|
}
|
|
12292
12286
|
|
|
12293
12287
|
// src/scripts/check-migration-body-change.ts
|
|
12294
|
-
import { execa as execa18 } from "execa";
|
|
12295
12288
|
import { existsSync as existsSync45 } from "fs";
|
|
12296
12289
|
import { join as join51 } from "path";
|
|
12297
12290
|
|
|
@@ -12348,11 +12341,11 @@ var GREEN = "\x1B[32m";
|
|
|
12348
12341
|
var YELLOW2 = "\x1B[33m";
|
|
12349
12342
|
var OFF2 = "\x1B[0m";
|
|
12350
12343
|
async function showAt(ref, path, cwd) {
|
|
12351
|
-
const result = await
|
|
12344
|
+
const result = await execa("git", ["show", `${ref}:${path}`], { cwd, reject: false });
|
|
12352
12345
|
return result.exitCode === 0 ? result.stdout : null;
|
|
12353
12346
|
}
|
|
12354
12347
|
async function runMigrationBodyChangeCheck(argv) {
|
|
12355
|
-
const root = (await
|
|
12348
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12356
12349
|
if (isInstanceRepo(root)) {
|
|
12357
12350
|
console.log(
|
|
12358
12351
|
`\u2713 migration body-change guard: skipped \u2014 this is an instance (${INSTANCE_CORE_FILE} present). Its migrations/versions/ is a carried, user-owned copy, not the template source this guard protects.`
|
|
@@ -12368,8 +12361,8 @@ async function runMigrationBodyChangeCheck(argv) {
|
|
|
12368
12361
|
console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
|
|
12369
12362
|
process.exit(2);
|
|
12370
12363
|
}
|
|
12371
|
-
await
|
|
12372
|
-
const { stdout } = await
|
|
12364
|
+
await execa("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
|
|
12365
|
+
const { stdout } = await execa(
|
|
12373
12366
|
"git",
|
|
12374
12367
|
[
|
|
12375
12368
|
"diff",
|
|
@@ -12463,7 +12456,6 @@ ${BOLD2}What to do${OFF2}
|
|
|
12463
12456
|
// src/scripts/check-pipe-trap.ts
|
|
12464
12457
|
import { readFileSync as readFileSync37, readdirSync as readdirSync22 } from "fs";
|
|
12465
12458
|
import { join as join52, relative as relative9 } from "path";
|
|
12466
|
-
import { execa as execa19 } from "execa";
|
|
12467
12459
|
|
|
12468
12460
|
// src/lib/pipe-trap-guard.ts
|
|
12469
12461
|
var STATUS_BEARING = [
|
|
@@ -12575,7 +12567,7 @@ function shellFiles(root) {
|
|
|
12575
12567
|
return out;
|
|
12576
12568
|
}
|
|
12577
12569
|
async function runPipeTrapCheck() {
|
|
12578
|
-
const root = (await
|
|
12570
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12579
12571
|
const files = shellFiles(root);
|
|
12580
12572
|
console.log(`audited ${files.length} shell file(s) under scripts/ and .githooks/ under ${root}`);
|
|
12581
12573
|
if (files.length === 0) {
|
|
@@ -12601,9 +12593,6 @@ async function runPipeTrapCheck() {
|
|
|
12601
12593
|
console.log(`\u2713 Pipe-trap guard: no status-bearing command is piped away`);
|
|
12602
12594
|
}
|
|
12603
12595
|
|
|
12604
|
-
// src/scripts/check-plugin-allowlist-convention.ts
|
|
12605
|
-
import { execa as execa20 } from "execa";
|
|
12606
|
-
|
|
12607
12596
|
// src/lib/plugin-allowlist-convention.ts
|
|
12608
12597
|
import { readFileSync as readFileSync38 } from "fs";
|
|
12609
12598
|
import { join as join53 } from "path";
|
|
@@ -12713,7 +12702,7 @@ Plugins would be rejected by require_service_principal (ADR-0009). Fix the glob,
|
|
|
12713
12702
|
|
|
12714
12703
|
// src/scripts/check-plugin-allowlist-convention.ts
|
|
12715
12704
|
async function runPluginAllowlistConventionCheck() {
|
|
12716
|
-
const root = (await
|
|
12705
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12717
12706
|
let violations;
|
|
12718
12707
|
try {
|
|
12719
12708
|
violations = checkAllowlistConvention(root);
|
|
@@ -12740,7 +12729,6 @@ async function runPluginAllowlistConventionCheck() {
|
|
|
12740
12729
|
// src/scripts/check-plugin-collisions.ts
|
|
12741
12730
|
import { existsSync as existsSync47 } from "fs";
|
|
12742
12731
|
import { join as join55 } from "path";
|
|
12743
|
-
import { execa as execa21 } from "execa";
|
|
12744
12732
|
|
|
12745
12733
|
// src/lib/plugin-collision-guard.ts
|
|
12746
12734
|
import { existsSync as existsSync46, readdirSync as readdirSync23, statSync as statSync14 } from "fs";
|
|
@@ -12810,7 +12798,7 @@ function formatCollisions(collisions) {
|
|
|
12810
12798
|
|
|
12811
12799
|
// src/scripts/check-plugin-collisions.ts
|
|
12812
12800
|
async function runPluginCollisionCheck() {
|
|
12813
|
-
const root = (await
|
|
12801
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12814
12802
|
const servicesDir = join55(root, "services");
|
|
12815
12803
|
if (!existsSync47(servicesDir)) {
|
|
12816
12804
|
console.log("\u2713 plugin collision guard: no services/ directory \u2014 nothing to compare");
|
|
@@ -12828,9 +12816,6 @@ async function runPluginCollisionCheck() {
|
|
|
12828
12816
|
console.log("\u2713 plugin collision guard: OK");
|
|
12829
12817
|
}
|
|
12830
12818
|
|
|
12831
|
-
// src/scripts/check-plugin-terraform.ts
|
|
12832
|
-
import { execa as execa22 } from "execa";
|
|
12833
|
-
|
|
12834
12819
|
// src/lib/plugin-terraform-guard.ts
|
|
12835
12820
|
import { existsSync as existsSync48, readFileSync as readFileSync39, readdirSync as readdirSync24 } from "fs";
|
|
12836
12821
|
import { dirname as dirname10, join as join56, relative as relative10, sep as sep4 } from "path";
|
|
@@ -12902,7 +12887,7 @@ function formatViolations(violations) {
|
|
|
12902
12887
|
|
|
12903
12888
|
// src/scripts/check-plugin-terraform.ts
|
|
12904
12889
|
async function runPluginTerraformCheck() {
|
|
12905
|
-
const root = (await
|
|
12890
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12906
12891
|
const violations = checkPluginTerraform(root);
|
|
12907
12892
|
if (violations.length > 0) {
|
|
12908
12893
|
console.error("\u2717 plugin Terraform guard: event subscriptions with no infrastructure\n");
|
|
@@ -12915,7 +12900,6 @@ async function runPluginTerraformCheck() {
|
|
|
12915
12900
|
// src/scripts/check-plugin-tool-supply.ts
|
|
12916
12901
|
import { existsSync as existsSync50 } from "fs";
|
|
12917
12902
|
import { join as join58 } from "path";
|
|
12918
|
-
import { execa as execa23 } from "execa";
|
|
12919
12903
|
|
|
12920
12904
|
// src/lib/plugin-tool-supply-audit.ts
|
|
12921
12905
|
import { existsSync as existsSync49, readFileSync as readFileSync40, readdirSync as readdirSync25, statSync as statSync15 } from "fs";
|
|
@@ -13867,7 +13851,7 @@ function auditPluginToolSupply(pluginsRoot) {
|
|
|
13867
13851
|
|
|
13868
13852
|
// src/scripts/check-plugin-tool-supply.ts
|
|
13869
13853
|
async function runPluginToolSupplyCheck() {
|
|
13870
|
-
const root = (await
|
|
13854
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
13871
13855
|
let allOk = true;
|
|
13872
13856
|
const pluginsRoot = join58(root, "services", "_plugins");
|
|
13873
13857
|
if (!existsSync50(pluginsRoot)) {
|
|
@@ -13946,9 +13930,6 @@ async function runPluginToolSupplyCheck() {
|
|
|
13946
13930
|
}
|
|
13947
13931
|
}
|
|
13948
13932
|
|
|
13949
|
-
// src/scripts/check-release-subject.ts
|
|
13950
|
-
import { execa as execa24 } from "execa";
|
|
13951
|
-
|
|
13952
13933
|
// src/lib/release-version.ts
|
|
13953
13934
|
var MINOR_TYPES = /* @__PURE__ */ new Set(["feat"]);
|
|
13954
13935
|
var SUBJECT = /^([a-z]+)(?:\([^)]*\))?(!)?:\s+\S/;
|
|
@@ -13984,7 +13965,7 @@ async function fetchPrTitleViaGh({
|
|
|
13984
13965
|
PR_NUMBER,
|
|
13985
13966
|
GH_REPO
|
|
13986
13967
|
}) {
|
|
13987
|
-
const { stdout } = await
|
|
13968
|
+
const { stdout } = await execa(
|
|
13988
13969
|
"gh",
|
|
13989
13970
|
["pr", "view", PR_NUMBER, "--repo", GH_REPO, "--json", "title", "--jq", ".title"],
|
|
13990
13971
|
{ env: { ...process.env, GH_TOKEN } }
|
|
@@ -14020,7 +14001,7 @@ async function resolveReleaseSubject({
|
|
|
14020
14001
|
);
|
|
14021
14002
|
}
|
|
14022
14003
|
}
|
|
14023
|
-
return (await
|
|
14004
|
+
return (await execa("git", ["log", "-1", "--format=%s"], { cwd })).stdout.trim();
|
|
14024
14005
|
}
|
|
14025
14006
|
async function runReleaseSubjectCheck(argv) {
|
|
14026
14007
|
const base = process.env["GITHUB_BASE_REF"] ?? argv[0];
|
|
@@ -14028,9 +14009,9 @@ async function runReleaseSubjectCheck(argv) {
|
|
|
14028
14009
|
console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
|
|
14029
14010
|
process.exit(2);
|
|
14030
14011
|
}
|
|
14031
|
-
const root = (await
|
|
14032
|
-
await
|
|
14033
|
-
const { stdout } = await
|
|
14012
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
14013
|
+
await execa("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
|
|
14014
|
+
const { stdout } = await execa("git", ["diff", "--name-only", `origin/${base}...HEAD`], {
|
|
14034
14015
|
cwd: root
|
|
14035
14016
|
});
|
|
14036
14017
|
const changedFiles = stdout.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
@@ -14283,7 +14264,6 @@ async function runSharedFileReductionCheck(args) {
|
|
|
14283
14264
|
// src/scripts/check-skeleton-drift.ts
|
|
14284
14265
|
import { existsSync as existsSync51, readdirSync as readdirSync27 } from "fs";
|
|
14285
14266
|
import { join as join60 } from "path";
|
|
14286
|
-
import { execa as execa25 } from "execa";
|
|
14287
14267
|
|
|
14288
14268
|
// src/lib/skeleton-drift-guard.ts
|
|
14289
14269
|
import { readFileSync as readFileSync43, readdirSync as readdirSync26, statSync as statSync16 } from "fs";
|
|
@@ -14412,7 +14392,7 @@ function discoverSkeletons(root) {
|
|
|
14412
14392
|
return entries.filter((name) => existsSync51(join60(skeletonsDir, name, ".github", "workflows", "ci.yml"))).sort();
|
|
14413
14393
|
}
|
|
14414
14394
|
async function runSkeletonDriftCheck() {
|
|
14415
|
-
const root = (await
|
|
14395
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
14416
14396
|
const skeletons = discoverSkeletons(root);
|
|
14417
14397
|
let filesConsidered = 0;
|
|
14418
14398
|
for (const name of skeletons) {
|
|
@@ -14444,9 +14424,8 @@ async function runSkeletonDriftCheck() {
|
|
|
14444
14424
|
}
|
|
14445
14425
|
|
|
14446
14426
|
// src/scripts/check-terraform-input.ts
|
|
14447
|
-
import { execa as execa26 } from "execa";
|
|
14448
14427
|
async function runTerraformInputCheck() {
|
|
14449
|
-
const root = (await
|
|
14428
|
+
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
14450
14429
|
const files = findWorkflowFiles(root);
|
|
14451
14430
|
console.log(`audited ${files.length} workflow file(s) under ${root}`);
|
|
14452
14431
|
if (files.length === 0) {
|