@mutmutco/hub 4.2.2 → 4.2.4
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.cjs +63 -10
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -66,8 +66,10 @@ __export(index_exports, {
|
|
|
66
66
|
retryHint: () => retryHint,
|
|
67
67
|
schedulePendingWatcher: () => schedulePendingWatcher,
|
|
68
68
|
schedulerStatus: () => schedulerStatus,
|
|
69
|
+
selfDist: () => selfDist,
|
|
69
70
|
sharedDocLockPath: () => sharedDocLockPath,
|
|
70
71
|
sharedDocLockTimeoutReceipt: () => sharedDocLockTimeoutReceipt,
|
|
72
|
+
shouldHandOff: () => shouldHandOff,
|
|
71
73
|
startSpinner: () => startSpinner,
|
|
72
74
|
systemdServiceUnit: () => systemdServiceUnit,
|
|
73
75
|
systemdTimerUnit: () => systemdTimerUnit,
|
|
@@ -81,6 +83,7 @@ __export(index_exports, {
|
|
|
81
83
|
writePending: () => writePending
|
|
82
84
|
});
|
|
83
85
|
module.exports = __toCommonJS(index_exports);
|
|
86
|
+
var import_node_child_process12 = require("node:child_process");
|
|
84
87
|
var import_node_fs19 = require("node:fs");
|
|
85
88
|
var import_node_path15 = require("node:path");
|
|
86
89
|
|
|
@@ -1208,11 +1211,16 @@ function cliArm(options) {
|
|
|
1208
1211
|
}
|
|
1209
1212
|
|
|
1210
1213
|
// src/arm-self.ts
|
|
1214
|
+
var SELF_PACKAGE = "@mutmutco/hub";
|
|
1215
|
+
var SELF_DIST_REL = "dist/index.cjs";
|
|
1216
|
+
function selfDist(env) {
|
|
1217
|
+
return globalDist(env, SELF_PACKAGE, SELF_DIST_REL);
|
|
1218
|
+
}
|
|
1211
1219
|
function selfArm(options) {
|
|
1212
1220
|
return npmGlobalArm({
|
|
1213
1221
|
surface: "updater",
|
|
1214
|
-
packageName:
|
|
1215
|
-
distRel:
|
|
1222
|
+
packageName: SELF_PACKAGE,
|
|
1223
|
+
distRel: SELF_DIST_REL,
|
|
1216
1224
|
...options
|
|
1217
1225
|
});
|
|
1218
1226
|
}
|
|
@@ -2671,6 +2679,11 @@ function reap(options) {
|
|
|
2671
2679
|
|
|
2672
2680
|
// src/reconcile.ts
|
|
2673
2681
|
var CANDIDATE_BOUND_DEFAULT = 12;
|
|
2682
|
+
function shouldHandOff(self, options) {
|
|
2683
|
+
if (options.dryRun || options.guard) return false;
|
|
2684
|
+
if (!options.dist) return false;
|
|
2685
|
+
return self.verdict === "ok" && Boolean(self.from) && self.from !== self.to;
|
|
2686
|
+
}
|
|
2674
2687
|
function reconcile(options) {
|
|
2675
2688
|
const env = options.env ?? process.env;
|
|
2676
2689
|
const say = (line) => {
|
|
@@ -2685,7 +2698,7 @@ function reconcile(options) {
|
|
|
2685
2698
|
const stamped = options.dryRun ? { ...event, dryRun: true } : event;
|
|
2686
2699
|
if (!appendJournal(paths.journalPath, { ts: (/* @__PURE__ */ new Date()).toISOString(), run, ...stamped })) summary.journalOk = false;
|
|
2687
2700
|
};
|
|
2688
|
-
const summary = { run, target: null, gate: null, atomicity: null, cli: null, updater: null, plugins: [], reap: [], surfaces: [], journalOk: true, exit: 0 };
|
|
2701
|
+
const summary = { run, target: null, gate: null, atomicity: null, cli: null, updater: null, plugins: [], reap: [], surfaces: [], journalOk: true, reexec: null, exit: 0 };
|
|
2689
2702
|
const recordArm = (arm) => {
|
|
2690
2703
|
if (arm.verdict === "fail") arm.repeatFailure = journalSurfaceRepeatedFail(paths.journalPath, arm.surface, run);
|
|
2691
2704
|
journal({ kind: "arm", surface: arm.surface, from: arm.from, to: arm.to, verdict: arm.verdict, detail: arm.detail, compat: arm.compat });
|
|
@@ -2750,6 +2763,18 @@ function reconcile(options) {
|
|
|
2750
2763
|
}
|
|
2751
2764
|
say(`target v${summary.target} (${summary.gate})`);
|
|
2752
2765
|
options.onTargetResolved?.(summary.target, summary.gate);
|
|
2766
|
+
say("updater: self-bootstrap");
|
|
2767
|
+
const self = selfArm({ target: summary.target, dryRun: options.dryRun, paths, env });
|
|
2768
|
+
summary.updater = self;
|
|
2769
|
+
recordArm(self);
|
|
2770
|
+
say(`updater: ${self.verdict}${self.detail ? " \u2014 " + self.detail : ""}`);
|
|
2771
|
+
const handoffDist = selfDist(env);
|
|
2772
|
+
if (shouldHandOff(self, { dryRun: options.dryRun, dist: handoffDist, guard: env.MMI_UPDATER_REEXEC })) {
|
|
2773
|
+
summary.reexec = { dist: handoffDist, target: summary.target, from: self.from };
|
|
2774
|
+
journal({ kind: "reexec", surface: "updater", from: self.from, to: summary.target, verdict: "ok", detail: `handing off to ${handoffDist} \u2014 the remaining surfaces converge under ${summary.target}` });
|
|
2775
|
+
say(`updater: handing off to ${summary.target}`);
|
|
2776
|
+
return summary;
|
|
2777
|
+
}
|
|
2753
2778
|
say(`cli: converging to v${summary.target}`);
|
|
2754
2779
|
const cli = cliArm({ target: summary.target, dryRun: options.dryRun, paths, env });
|
|
2755
2780
|
summary.cli = cli;
|
|
@@ -2773,11 +2798,6 @@ function reconcile(options) {
|
|
|
2773
2798
|
journal({ kind: "surface", surface: probe.id, present: true, verdict: "skip", detail: `present, its converge arm has not landed yet (target ${summary.target})` });
|
|
2774
2799
|
}
|
|
2775
2800
|
}
|
|
2776
|
-
say("updater: self-bootstrap");
|
|
2777
|
-
const self = selfArm({ target: summary.target, dryRun: options.dryRun, paths, env });
|
|
2778
|
-
summary.updater = self;
|
|
2779
|
-
recordArm(self);
|
|
2780
|
-
say(`updater: ${self.verdict}${self.detail ? " \u2014 " + self.detail : ""}`);
|
|
2781
2801
|
return summary;
|
|
2782
2802
|
});
|
|
2783
2803
|
} catch (error) {
|
|
@@ -3487,6 +3507,7 @@ function stripAnsi(text) {
|
|
|
3487
3507
|
}
|
|
3488
3508
|
function collectRows(summary) {
|
|
3489
3509
|
const rows = [];
|
|
3510
|
+
if (summary.updater) rows.push(classify(summary.updater));
|
|
3490
3511
|
if (summary.cli) rows.push(classify(summary.cli));
|
|
3491
3512
|
for (const arm of summary.plugins) rows.push(classify(arm));
|
|
3492
3513
|
for (const surface of summary.surfaces) {
|
|
@@ -3494,7 +3515,6 @@ function collectRows(summary) {
|
|
|
3494
3515
|
rows.push({ name: surface.id, from: null, to: summary.target ?? "?", kind: "pending", note: "arm not landed", detail: "", repeatFailure: false });
|
|
3495
3516
|
}
|
|
3496
3517
|
}
|
|
3497
|
-
if (summary.updater) rows.push(classify(summary.updater));
|
|
3498
3518
|
return rows;
|
|
3499
3519
|
}
|
|
3500
3520
|
function headline(detail, width) {
|
|
@@ -3543,7 +3563,7 @@ function reportFooterLines(summary, options = {}) {
|
|
|
3543
3563
|
out.push("");
|
|
3544
3564
|
out.push(...noteLines(
|
|
3545
3565
|
" note: ",
|
|
3546
|
-
`hub moved ${self.from} \u2192 ${self.to}
|
|
3566
|
+
`hub moved ${self.from} \u2192 ${self.to} while the surfaces above were converging, so they used ${self.from} logic \u2014 rerun \`mmi-hub update\` to bring them to ${self.to}`,
|
|
3547
3567
|
width
|
|
3548
3568
|
));
|
|
3549
3569
|
}
|
|
@@ -3688,6 +3708,24 @@ function printReconcile(summary, json, dryRun = false) {
|
|
|
3688
3708
|
journalPath: statePaths(process.env).journalPath
|
|
3689
3709
|
}));
|
|
3690
3710
|
}
|
|
3711
|
+
function handOff(reexec, args, json) {
|
|
3712
|
+
if (!json) {
|
|
3713
|
+
process.stdout.write(` updater ${reexec.from ?? "absent"} \u2192 ${reexec.target} updated \u2014 rerunning under ${reexec.target}
|
|
3714
|
+
|
|
3715
|
+
`);
|
|
3716
|
+
}
|
|
3717
|
+
const child = (0, import_node_child_process12.spawnSync)(process.execPath, [reexec.dist, ...args], {
|
|
3718
|
+
stdio: "inherit",
|
|
3719
|
+
windowsHide: true,
|
|
3720
|
+
env: { ...process.env, MMI_UPDATER_REEXEC: "1" }
|
|
3721
|
+
});
|
|
3722
|
+
if (child.error || typeof child.status !== "number") {
|
|
3723
|
+
process.stderr.write(`mmi-hub: could not run the updated updater at ${reexec.dist} \u2014 ${child.error?.message ?? "no exit status"}; rerun \`mmi-hub update\`
|
|
3724
|
+
`);
|
|
3725
|
+
return 1;
|
|
3726
|
+
}
|
|
3727
|
+
return child.status;
|
|
3728
|
+
}
|
|
3691
3729
|
function runUpdate(args, json) {
|
|
3692
3730
|
const dryRun = args.includes("--dry-run");
|
|
3693
3731
|
const verbose = args.includes("--verbose");
|
|
@@ -3745,11 +3783,24 @@ function main(args = process.argv.slice(2)) {
|
|
|
3745
3783
|
}
|
|
3746
3784
|
if (command === "update") {
|
|
3747
3785
|
const { summary, rendered } = runUpdate(args, json);
|
|
3786
|
+
if (summary.reexec) return handOff(summary.reexec, args, json);
|
|
3748
3787
|
if (!rendered) printReconcile(summary, json, args.includes("--dry-run"));
|
|
3749
3788
|
return summary.exit;
|
|
3750
3789
|
}
|
|
3751
3790
|
if (command === "install") {
|
|
3752
3791
|
const { summary, rendered } = runUpdate(args, json);
|
|
3792
|
+
if (summary.reexec) {
|
|
3793
|
+
const handedOff = handOff(summary.reexec, ["update", ...args.filter((arg) => arg !== "install")], json);
|
|
3794
|
+
const scheduled = installTask();
|
|
3795
|
+
if (!json) {
|
|
3796
|
+
process.stdout.write(scheduled.ok ? ` Auto-update on \u2014 hourly task "MMI Fleet Updater".
|
|
3797
|
+
` : ` Auto-update NOT enabled \u2014 ${scheduled.detail}
|
|
3798
|
+
`);
|
|
3799
|
+
} else {
|
|
3800
|
+
process.stdout.write(JSON.stringify({ convergence: summary, autoupdate: scheduled }, null, 2) + "\n");
|
|
3801
|
+
}
|
|
3802
|
+
return Math.max(handedOff, scheduled.ok ? 0 : 1);
|
|
3803
|
+
}
|
|
3753
3804
|
const schedule = installTask();
|
|
3754
3805
|
if (json) {
|
|
3755
3806
|
process.stdout.write(JSON.stringify({ convergence: summary, autoupdate: schedule }, null, 2) + "\n");
|
|
@@ -3826,8 +3877,10 @@ if (typeof require !== "undefined" && require.main === module) {
|
|
|
3826
3877
|
retryHint,
|
|
3827
3878
|
schedulePendingWatcher,
|
|
3828
3879
|
schedulerStatus,
|
|
3880
|
+
selfDist,
|
|
3829
3881
|
sharedDocLockPath,
|
|
3830
3882
|
sharedDocLockTimeoutReceipt,
|
|
3883
|
+
shouldHandOff,
|
|
3831
3884
|
startSpinner,
|
|
3832
3885
|
systemdServiceUnit,
|
|
3833
3886
|
systemdTimerUnit,
|
package/package.json
CHANGED