@tablation/crew 0.127.0 → 0.127.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/cli.js +54 -19
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -13253,7 +13253,7 @@ async function sandboxBuildTick(repos, deps, force = false) {
|
|
|
13253
13253
|
}
|
|
13254
13254
|
|
|
13255
13255
|
// src/doctor-checks.ts
|
|
13256
|
-
import { execFileSync as execFileSync9 } from "child_process";
|
|
13256
|
+
import { execFileSync as execFileSync9, spawnSync as spawnSync8 } from "child_process";
|
|
13257
13257
|
var PROBE_BRANCH = "crew-probe-branch";
|
|
13258
13258
|
var realGit = (cwd, args, env) => {
|
|
13259
13259
|
execFileSync9("git", args, { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
@@ -13386,6 +13386,21 @@ function managedRuntimeWarnings(kind, ship) {
|
|
|
13386
13386
|
}
|
|
13387
13387
|
return out;
|
|
13388
13388
|
}
|
|
13389
|
+
var MANAGED_GIT_EMAIL = "crew@tablation.dev";
|
|
13390
|
+
function readGlobalGitIdentity() {
|
|
13391
|
+
const get2 = (key) => {
|
|
13392
|
+
const res = spawnSync8("git", ["config", "--global", "--get", key], { encoding: "utf8" });
|
|
13393
|
+
const v = (res.stdout ?? "").trim();
|
|
13394
|
+
return res.status === 0 && v ? v : null;
|
|
13395
|
+
};
|
|
13396
|
+
return { name: get2("user.name"), email: get2("user.email") };
|
|
13397
|
+
}
|
|
13398
|
+
function managedGitIdentityWarnings(kind, identity) {
|
|
13399
|
+
if (kind !== "managed_instance" && kind !== "pooled_instance" && kind !== "pooled") return [];
|
|
13400
|
+
const missing = [identity.name ? "" : "user.name", identity.email ? "" : "user.email"].filter(Boolean);
|
|
13401
|
+
if (missing.length === 0) return [];
|
|
13402
|
+
return [`git ${missing.join(" and ")} not set for this user on a ${kind} ship; every commit crew makes here fails with "Committer identity unknown" (re-run \`crew provision\`, or \`git config --global user.name <ship name>\` and \`user.email ${MANAGED_GIT_EMAIL}\`)`];
|
|
13403
|
+
}
|
|
13389
13404
|
|
|
13390
13405
|
// src/selftest.ts
|
|
13391
13406
|
import { spawn as spawn6 } from "child_process";
|
|
@@ -13613,7 +13628,7 @@ function doctorSelftestLines(stored, toolchains) {
|
|
|
13613
13628
|
import { resolve as resolve7, dirname as dirname34, join as join56, basename as basename16 } from "path";
|
|
13614
13629
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
13615
13630
|
import { hostname as hostname5, homedir as homedir11 } from "os";
|
|
13616
|
-
import { spawnSync as
|
|
13631
|
+
import { spawnSync as spawnSync12 } from "child_process";
|
|
13617
13632
|
import { parse as parseYaml2 } from "yaml";
|
|
13618
13633
|
|
|
13619
13634
|
// src/argv.ts
|
|
@@ -14468,7 +14483,7 @@ function matchShipRows(ships, shipName2, machineId) {
|
|
|
14468
14483
|
}
|
|
14469
14484
|
|
|
14470
14485
|
// src/provision.ts
|
|
14471
|
-
import { spawnSync as
|
|
14486
|
+
import { spawnSync as spawnSync9 } from "child_process";
|
|
14472
14487
|
import { existsSync as existsSync34, readFileSync as readFileSync33, writeFileSync as writeFileSync26 } from "fs";
|
|
14473
14488
|
import { hostname as hostname2 } from "os";
|
|
14474
14489
|
import { parseDocument as parseDocument3, isMap as isMap2, isScalar } from "yaml";
|
|
@@ -14916,6 +14931,11 @@ async function runProvision(o, deps, write, human) {
|
|
|
14916
14931
|
emit("connect", `set ${key}`, { setting: key });
|
|
14917
14932
|
}
|
|
14918
14933
|
}
|
|
14934
|
+
if (isManagedShipKind(o.shipKind)) {
|
|
14935
|
+
summary.gitIdentity = deps.ensureGitIdentity(shipName2, MANAGED_GIT_EMAIL);
|
|
14936
|
+
if (summary.gitIdentity === "set") summary.changed = true;
|
|
14937
|
+
emit("git_identity", `git identity: ${summary.gitIdentity}`, { action: summary.gitIdentity });
|
|
14938
|
+
}
|
|
14919
14939
|
for (const host of o.forgeHosts) {
|
|
14920
14940
|
const token = o.tokens[host];
|
|
14921
14941
|
const stored = deps.storedToken(host);
|
|
@@ -15072,7 +15092,7 @@ function realProvisionDeps(crewHome) {
|
|
|
15072
15092
|
const env = { ...process.env, ...o.env };
|
|
15073
15093
|
delete env.CREW_FORGE_TOKEN;
|
|
15074
15094
|
for (const k of Object.keys(env)) if (k.startsWith("CREW_CONNECT_KEY_")) delete env[k];
|
|
15075
|
-
const res =
|
|
15095
|
+
const res = spawnSync9(bin, [...pre, ...args], { cwd: crewHome, encoding: "utf8", env, input: o.input, maxBuffer: 64 * 1024 * 1024 });
|
|
15076
15096
|
return { status: res.status ?? 1, stdout: res.stdout ?? "", stderr: `${res.stderr ?? ""}${res.error ? String(res.error) : ""}` };
|
|
15077
15097
|
};
|
|
15078
15098
|
const configFile = () => {
|
|
@@ -15120,15 +15140,15 @@ function realProvisionDeps(crewHome) {
|
|
|
15120
15140
|
if (mechanism === "systemd") {
|
|
15121
15141
|
const system = ctx.root || existsSync34(systemUnitPathFor(label));
|
|
15122
15142
|
const ctl = system ? ["systemctl"] : ["systemctl", "--user"];
|
|
15123
|
-
running =
|
|
15143
|
+
running = spawnSync9(ctl[0], [...ctl.slice(1), "is-active", "--quiet", `${label}.service`]).status === 0;
|
|
15124
15144
|
if (!system) {
|
|
15125
|
-
const out =
|
|
15145
|
+
const out = spawnSync9("loginctl", ["show-user", ctx.user, "-p", "Linger"], { encoding: "utf8" });
|
|
15126
15146
|
lingering = /Linger=yes/.test(out.stdout ?? "");
|
|
15127
15147
|
}
|
|
15128
15148
|
} else if (mechanism === "cron") {
|
|
15129
15149
|
running = true;
|
|
15130
15150
|
} else if (mechanism === "launchd") {
|
|
15131
|
-
running =
|
|
15151
|
+
running = spawnSync9("launchctl", ["list", label]).status === 0;
|
|
15132
15152
|
}
|
|
15133
15153
|
return { mechanism, unitsStale, running, lingering };
|
|
15134
15154
|
},
|
|
@@ -15149,6 +15169,17 @@ function realProvisionDeps(crewHome) {
|
|
|
15149
15169
|
if (wrote.length) writeFileSync26(file, doc.toString());
|
|
15150
15170
|
return wrote;
|
|
15151
15171
|
},
|
|
15172
|
+
ensureGitIdentity(name, email) {
|
|
15173
|
+
const have = readGlobalGitIdentity();
|
|
15174
|
+
let wrote = false;
|
|
15175
|
+
for (const [key, value2] of [["user.name", have.name ? null : name], ["user.email", have.email ? null : email]]) {
|
|
15176
|
+
if (value2 === null) continue;
|
|
15177
|
+
const res = spawnSync9("git", ["config", "--global", key, value2], { encoding: "utf8" });
|
|
15178
|
+
if (res.status !== 0) throw new Error(`git config --global ${key}: ${(res.stderr ?? "").trim() || `exited ${res.status}`}`);
|
|
15179
|
+
wrote = true;
|
|
15180
|
+
}
|
|
15181
|
+
return wrote ? "set" : "kept";
|
|
15182
|
+
},
|
|
15152
15183
|
storedToken(host) {
|
|
15153
15184
|
const res = spawnCrew(["credential", "get"], { input: `protocol=https
|
|
15154
15185
|
host=${host}
|
|
@@ -20738,7 +20769,7 @@ async function showLogEntry(route2, entryId, opts = {}) {
|
|
|
20738
20769
|
}
|
|
20739
20770
|
|
|
20740
20771
|
// src/repos-check.ts
|
|
20741
|
-
import { spawnSync as
|
|
20772
|
+
import { spawnSync as spawnSync11 } from "child_process";
|
|
20742
20773
|
import { readFileSync as readFileSync39 } from "fs";
|
|
20743
20774
|
import { basename as basename11 } from "path";
|
|
20744
20775
|
var POSIX_SHELL = /^(?:ba|z|da|k|a|mk)?sh$|^fish$/;
|
|
@@ -20747,10 +20778,10 @@ function checkHookSyntax(script, shell) {
|
|
|
20747
20778
|
const name = basename11(spec.bin).replace(/\.exe$/i, "").toLowerCase();
|
|
20748
20779
|
let run3;
|
|
20749
20780
|
if (POSIX_SHELL.test(name)) {
|
|
20750
|
-
run3 =
|
|
20781
|
+
run3 = spawnSync11(spec.bin, ["-n"], { input: script, encoding: "utf8" });
|
|
20751
20782
|
} else if (/^(pwsh|powershell)$/.test(name)) {
|
|
20752
20783
|
const parse3 = "$e=$null;[void][System.Management.Automation.Language.Parser]::ParseInput($env:CREW_CHECK_SCRIPT,[ref]$null,[ref]$e);if($e){$e|ForEach-Object{[Console]::Error.WriteLine($_.Message)};exit 1}";
|
|
20753
|
-
run3 =
|
|
20784
|
+
run3 = spawnSync11(spec.bin, ["-NoProfile", "-NonInteractive", "-Command", parse3], {
|
|
20754
20785
|
encoding: "utf8",
|
|
20755
20786
|
env: { ...process.env, CREW_CHECK_SCRIPT: script }
|
|
20756
20787
|
});
|
|
@@ -25831,7 +25862,7 @@ if (command === "passenger-sync-daemon") {
|
|
|
25831
25862
|
`
|
|
25832
25863
|
);
|
|
25833
25864
|
if (!dryRun) {
|
|
25834
|
-
|
|
25865
|
+
spawnSync12("systemctl", ["--user", "disable", "--now", `${label}.timer`], { cwd: CREW_HOME });
|
|
25835
25866
|
try {
|
|
25836
25867
|
unlinkSync5(staleTimer);
|
|
25837
25868
|
} catch {
|
|
@@ -25882,7 +25913,7 @@ if (command === "passenger-sync-daemon") {
|
|
|
25882
25913
|
async function doctorFix(o) {
|
|
25883
25914
|
const routes = await Promise.all(routesInScope(cfg.routes, named).map((c) => gatherHealth({ route: c.route, enabled: c.enabled, hasRepos: reposOf(c).length > 0 }, () => routeProblems(c))));
|
|
25884
25915
|
const unitExists = (p) => existsSync52(p);
|
|
25885
|
-
const crontab = o.host === "linux" ?
|
|
25916
|
+
const crontab = o.host === "linux" ? spawnSync12("crontab", ["-l"], { encoding: "utf8" }).stdout ?? "" : "";
|
|
25886
25917
|
const schedulerAbsent = o.host !== "windows" ? !schedulerInstalled(planInstall(cfg.ship, CREW_HOME, o.host, detectSystemd(), "run", installContext()), unitExists, crontab) : true;
|
|
25887
25918
|
const plan = planFix({ routes, schedulerAbsent, host: o.host });
|
|
25888
25919
|
for (const n of plan.notes) process.stdout.write(`fix: ${n}
|
|
@@ -27053,7 +27084,7 @@ ${cu.tail.trimEnd()}
|
|
|
27053
27084
|
}
|
|
27054
27085
|
let failed = false;
|
|
27055
27086
|
for (const cmd2 of commands) {
|
|
27056
|
-
const res2 =
|
|
27087
|
+
const res2 = spawnSync12(cmd2[0], cmd2.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
|
|
27057
27088
|
if (res2.stdout) process.stdout.write(res2.stdout);
|
|
27058
27089
|
if (res2.stderr) process.stderr.write(res2.stderr);
|
|
27059
27090
|
if (cmd2 === control.startCommand && (res2.error || res2.status !== 0)) {
|
|
@@ -27071,7 +27102,7 @@ ${cu.tail.trimEnd()}
|
|
|
27071
27102
|
`);
|
|
27072
27103
|
break;
|
|
27073
27104
|
}
|
|
27074
|
-
const res =
|
|
27105
|
+
const res = spawnSync12(cmd[0], cmd.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
|
|
27075
27106
|
if (res.stdout) process.stdout.write(res.stdout);
|
|
27076
27107
|
if (res.stderr) process.stderr.write(res.stderr);
|
|
27077
27108
|
if (daemonSub !== "status" && (res.error || res.status !== 0)) {
|
|
@@ -29528,7 +29559,7 @@ ${where.join("\n")}`);
|
|
|
29528
29559
|
process.stdout.write(upOutput(res, terminal));
|
|
29529
29560
|
const opener = openerFor(process.platform);
|
|
29530
29561
|
if (opener && shouldOpen({ open: flag("open"), noOpen: flag("no-open"), json: jsonP, terminal })) {
|
|
29531
|
-
const r =
|
|
29562
|
+
const r = spawnSync12(opener, [res.url], { stdio: "ignore" });
|
|
29532
29563
|
if (r.error || r.status !== 0) process.stderr.write(`crew periscope: could not open ${res.url} with ${opener}
|
|
29533
29564
|
`);
|
|
29534
29565
|
}
|
|
@@ -29776,7 +29807,7 @@ ${where.join("\n")}`);
|
|
|
29776
29807
|
}
|
|
29777
29808
|
const host = hostPlatform();
|
|
29778
29809
|
const control = host === "windows" ? null : planDaemonControl(CREW_HOME, host, detectSystemd());
|
|
29779
|
-
const unitStatus = control?.statusCommand ?
|
|
29810
|
+
const unitStatus = control?.statusCommand ? spawnSync12(control.statusCommand[0], control.statusCommand.slice(1), { cwd: CREW_HOME, encoding: "utf8" }) : null;
|
|
29780
29811
|
const unitRunning = unitStatus !== null && !unitStatus.error && unitStatus.status === 0;
|
|
29781
29812
|
if (!unitRunning) {
|
|
29782
29813
|
process.stdout.write("crew reload: no daemon unit is running \u2014 nothing to reload (the next run reads crew.yaml fresh)\n");
|
|
@@ -29790,7 +29821,7 @@ ${where.join("\n")}`);
|
|
|
29790
29821
|
);
|
|
29791
29822
|
if (flag("now") && control?.stopCommand && control.startCommand) {
|
|
29792
29823
|
for (const cmd of [control.stopCommand, control.startCommand]) {
|
|
29793
|
-
const res =
|
|
29824
|
+
const res = spawnSync12(cmd[0], cmd.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
|
|
29794
29825
|
if (cmd === control.startCommand && (res.error || res.status !== 0)) {
|
|
29795
29826
|
process.stderr.write(`crew reload: ${cmd.join(" ")} exited ${res.status ?? "error"}
|
|
29796
29827
|
`);
|
|
@@ -29932,7 +29963,7 @@ ${where.join("\n")}`);
|
|
|
29932
29963
|
writeFileSync38(join56(dir, "README.md"), SAMPLE_README);
|
|
29933
29964
|
writeFileSync38(join56(dir, ".crew.yaml"), SAMPLE_CREW_YAML);
|
|
29934
29965
|
const g = (...a) => {
|
|
29935
|
-
const r =
|
|
29966
|
+
const r = spawnSync12("git", a, { cwd: dir, encoding: "utf8" });
|
|
29936
29967
|
if (r.status !== 0) fail2(`git ${a[0]} failed in ${dir}: ${(r.stderr || r.stdout).trim()}`);
|
|
29937
29968
|
};
|
|
29938
29969
|
g("init", "-b", "main");
|
|
@@ -30364,7 +30395,9 @@ watermark: ${state.watermark()}
|
|
|
30364
30395
|
}
|
|
30365
30396
|
for (const message of roleCapWarnings(cfg.ship)) problems.push({ severity: "note", kind: "role_cap_above_ship_cap", message });
|
|
30366
30397
|
if (!flag("offline")) {
|
|
30367
|
-
|
|
30398
|
+
const shipKind = await doctorShipKind(route2, cfg.ship);
|
|
30399
|
+
for (const message of managedRuntimeWarnings(shipKind, cfg.ship)) problems.push({ severity: "attention", kind: "managed_runtime_default", message });
|
|
30400
|
+
for (const message of managedGitIdentityWarnings(shipKind, readGlobalGitIdentity())) problems.push({ severity: "attention", kind: "managed_git_identity", message });
|
|
30368
30401
|
}
|
|
30369
30402
|
for (const t of rejectedTunnels(cfg.ship.stateDir)) {
|
|
30370
30403
|
problems.push({ severity: "attention", kind: TUNNEL_REJECTED_KEY, message: tunnelRejectedMessage(t.workspaceId, t.quickExits), remedy: "rotate the slug with `crew rotate-passenger-url`" });
|
|
@@ -30615,6 +30648,8 @@ crew manifest: ${seats2.length ? seats2.map((c) => c.name).join(", ") : "non
|
|
|
30615
30648
|
`
|
|
30616
30649
|
);
|
|
30617
30650
|
for (const w of managedRuntimeWarnings(row.kind, cfg.ship)) process.stdout.write(`managed runtime: WARN ${w}
|
|
30651
|
+
`);
|
|
30652
|
+
for (const w of managedGitIdentityWarnings(row.kind, readGlobalGitIdentity())) process.stdout.write(`managed git: WARN ${w}
|
|
30618
30653
|
`);
|
|
30619
30654
|
}
|
|
30620
30655
|
}
|
package/package.json
CHANGED