@mutmutco/installer-launcher 1.4.3 → 1.5.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/launcher.js +92 -10
- package/dist/launcher.sea.cjs +92 -10
- package/package.json +1 -1
package/dist/launcher.js
CHANGED
|
@@ -976,6 +976,15 @@ parentPort.on('message', (next) => {
|
|
|
976
976
|
});
|
|
977
977
|
setInterval(draw, workerData.intervalMs);
|
|
978
978
|
`;
|
|
979
|
+
function awaitWorkerIdle(control, timeoutMs = 250) {
|
|
980
|
+
const deadline = Date.now() + timeoutMs;
|
|
981
|
+
while (Atomics.load(control, 1)) {
|
|
982
|
+
const left = deadline - Date.now();
|
|
983
|
+
if (left <= 0) return false;
|
|
984
|
+
Atomics.wait(control, 1, 1, left);
|
|
985
|
+
}
|
|
986
|
+
return true;
|
|
987
|
+
}
|
|
979
988
|
function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath, env = process.env, platform = process.platform }) {
|
|
980
989
|
animate = animate && !face.nested && !face.emitsProgress;
|
|
981
990
|
const glyphs = spinnerFramesFor(env, platform);
|
|
@@ -1008,7 +1017,7 @@ function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath,
|
|
|
1008
1017
|
const pause = () => {
|
|
1009
1018
|
if (!control) return;
|
|
1010
1019
|
Atomics.store(control, 0, 1);
|
|
1011
|
-
|
|
1020
|
+
awaitWorkerIdle(control);
|
|
1012
1021
|
};
|
|
1013
1022
|
const halt = () => {
|
|
1014
1023
|
if (timer) clearInterval(timer);
|
|
@@ -1699,15 +1708,21 @@ function querySchedule(config, options = {}) {
|
|
|
1699
1708
|
if (result.code !== 0) return { supported: true, enabled: false };
|
|
1700
1709
|
const lastRun = valueOf(result.stdout, "Last Run Time:");
|
|
1701
1710
|
const nextRun = valueOf(result.stdout, "Next Run Time:");
|
|
1711
|
+
const lastResult = valueOf(result.stdout, "Last Result:");
|
|
1702
1712
|
const state2 = { supported: true, enabled: true, cadence: "hourly" };
|
|
1703
1713
|
if (lastRun && !/disabled|never|not run/i.test(lastRun)) state2.lastRun = lastRun;
|
|
1704
1714
|
else if (nextRun && !/disabled|never/i.test(nextRun)) state2.lastRun = `next run ${nextRun}`;
|
|
1715
|
+
if (lastResult) state2.lastResult = lastResult;
|
|
1705
1716
|
return state2;
|
|
1706
1717
|
}
|
|
1707
1718
|
if (platform === "darwin") {
|
|
1708
1719
|
const plist = join5(home, "Library", "LaunchAgents", `${scheduleLabel(config)}.plist`);
|
|
1709
1720
|
if (!existsSync6(plist)) return { supported: true, enabled: false };
|
|
1710
|
-
|
|
1721
|
+
const state2 = { supported: true, enabled: true, cadence: "hourly" };
|
|
1722
|
+
const printed = exec("launchctl", ["print", `gui/${process.getuid?.() ?? 501}/${scheduleLabel(config)}`]);
|
|
1723
|
+
const exitCode = /last exit code = (-?\d+)/.exec(`${printed.stdout ?? ""}${printed.stderr ?? ""}`)?.[1];
|
|
1724
|
+
if (printed.code === 0 && exitCode) state2.lastResult = exitCode;
|
|
1725
|
+
return state2;
|
|
1711
1726
|
}
|
|
1712
1727
|
const timer = join5(home, ".config", "systemd", "user", `${scheduleLabel(config)}.timer`);
|
|
1713
1728
|
if (!existsSync6(timer)) return { supported: true, enabled: false };
|
|
@@ -1715,6 +1730,9 @@ function querySchedule(config, options = {}) {
|
|
|
1715
1730
|
const shown = exec("systemctl", ["--user", "show", `${scheduleLabel(config)}.service`, "-p", "ExecMainStartTimestamp", "--value"]);
|
|
1716
1731
|
const stamp = (shown.stdout ?? "").trim();
|
|
1717
1732
|
if (shown.code === 0 && stamp && stamp !== "n/a") state.lastRun = stamp;
|
|
1733
|
+
const status = exec("systemctl", ["--user", "show", `${scheduleLabel(config)}.service`, "-p", "ExecMainStatus", "--value"]);
|
|
1734
|
+
const code = (status.stdout ?? "").trim();
|
|
1735
|
+
if (status.code === 0 && /^\d+$/.test(code)) state.lastResult = code;
|
|
1718
1736
|
return state;
|
|
1719
1737
|
}
|
|
1720
1738
|
function darwinPlist(label, command2) {
|
|
@@ -1766,6 +1784,36 @@ function valueOf(output, key) {
|
|
|
1766
1784
|
function firstLine(text) {
|
|
1767
1785
|
return String(text).split(/\r?\n/).map((line) => line.trim()).filter(Boolean)[0] ?? "";
|
|
1768
1786
|
}
|
|
1787
|
+
var SCHEDULE_SIGNAL = "MM_LAUNCHER_SCHEDULE";
|
|
1788
|
+
var OPT_OUT_FILE = "auto-update-off";
|
|
1789
|
+
function autoUpdateOptOut(dir) {
|
|
1790
|
+
return existsSync6(join5(dir, OPT_OUT_FILE));
|
|
1791
|
+
}
|
|
1792
|
+
function persistAutoUpdateOptOut(dir, off) {
|
|
1793
|
+
try {
|
|
1794
|
+
if (off) {
|
|
1795
|
+
mkdirSync5(dir, { recursive: true });
|
|
1796
|
+
writeFileSync6(join5(dir, OPT_OUT_FILE), "");
|
|
1797
|
+
} else rmSync5(join5(dir, OPT_OUT_FILE), { force: true });
|
|
1798
|
+
} catch {
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
function armVerifiedSchedule(config, options) {
|
|
1802
|
+
try {
|
|
1803
|
+
enableSchedule(config, options.command, options);
|
|
1804
|
+
const verified = querySchedule(config, options);
|
|
1805
|
+
if (verified.enabled) return { signal: scheduleName(config), note: null };
|
|
1806
|
+
return { signal: null, note: `The launcher's hourly update task (${scheduleName(config)}) could not be verified \u2014 the product's own auto-update task stays.` };
|
|
1807
|
+
} catch (error) {
|
|
1808
|
+
return { signal: null, note: `The launcher could not arm its hourly update task: ${error.message} The product's own auto-update task stays.` };
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
function lastResultFailed(value) {
|
|
1812
|
+
const text = value?.trim() ?? "";
|
|
1813
|
+
if (!text) return false;
|
|
1814
|
+
if (!/^-?(?:0x[0-9a-f]+|\d+)$/i.test(text)) return true;
|
|
1815
|
+
return ![0, 267011, 267009].includes(Number(text));
|
|
1816
|
+
}
|
|
1769
1817
|
|
|
1770
1818
|
// src/login-github.ts
|
|
1771
1819
|
import { spawn, spawnSync as spawnSync3 } from "node:child_process";
|
|
@@ -2265,7 +2313,7 @@ async function refreshLauncher(target, options = {}) {
|
|
|
2265
2313
|
}
|
|
2266
2314
|
|
|
2267
2315
|
// src/index.ts
|
|
2268
|
-
var LAUNCHER_VERSION = true ? "1.
|
|
2316
|
+
var LAUNCHER_VERSION = true ? "1.5.1" : readVersionFromPackage();
|
|
2269
2317
|
function defaultPrint(message) {
|
|
2270
2318
|
process.stdout.write(`${message}
|
|
2271
2319
|
`);
|
|
@@ -2722,6 +2770,8 @@ async function installOrUpdateRun(config, dir, options, print, update, flags2, m
|
|
|
2722
2770
|
installer.finish({ ...pointer ? { version: pointer } : {}, total: 1, updated: pointer && installed !== pointer ? 1 : 0, failed: 0, dryRun: true });
|
|
2723
2771
|
return 0;
|
|
2724
2772
|
}
|
|
2773
|
+
const armNote = armScheduleForInstall(config, dir, options);
|
|
2774
|
+
if (armNote) installer.phase("arm", { state: "note", detail: armNote });
|
|
2725
2775
|
if (pointer && current?.version === pointer && payloadPresent) {
|
|
2726
2776
|
version = pointer;
|
|
2727
2777
|
installer.phase("resolve", { seconds: (Date.now() - started) / 1e3 });
|
|
@@ -2814,6 +2864,18 @@ async function installOrUpdateRun(config, dir, options, print, update, flags2, m
|
|
|
2814
2864
|
installer.stop();
|
|
2815
2865
|
}
|
|
2816
2866
|
}
|
|
2867
|
+
function armScheduleForInstall(config, dir, options) {
|
|
2868
|
+
if (autoUpdateOptOut(dir)) return null;
|
|
2869
|
+
if (!isSea() && !options.autoupdate) return null;
|
|
2870
|
+
const result = armVerifiedSchedule(config, {
|
|
2871
|
+
command: options.autoupdate?.command ?? [process.execPath, "update"],
|
|
2872
|
+
stateDir: dir,
|
|
2873
|
+
...options.autoupdate
|
|
2874
|
+
});
|
|
2875
|
+
if (!result.signal) return result.note;
|
|
2876
|
+
process.env[SCHEDULE_SIGNAL] = result.signal;
|
|
2877
|
+
return null;
|
|
2878
|
+
}
|
|
2817
2879
|
function doInstall(config, dir, options, print, flags2) {
|
|
2818
2880
|
return installOrUpdate(config, dir, options, print, false, flags2);
|
|
2819
2881
|
}
|
|
@@ -3023,8 +3085,13 @@ function doAutoupdate(config, dir, options, args, ui) {
|
|
|
3023
3085
|
const name = identityFor(ui.product).name;
|
|
3024
3086
|
if (mode === "on" || mode === "off") {
|
|
3025
3087
|
try {
|
|
3026
|
-
if (mode === "on")
|
|
3027
|
-
|
|
3088
|
+
if (mode === "on") {
|
|
3089
|
+
enableSchedule(config, command2, scheduleOptions);
|
|
3090
|
+
persistAutoUpdateOptOut(dir, false);
|
|
3091
|
+
} else {
|
|
3092
|
+
disableSchedule(config, scheduleOptions);
|
|
3093
|
+
persistAutoUpdateOptOut(dir, true);
|
|
3094
|
+
}
|
|
3028
3095
|
} catch (error) {
|
|
3029
3096
|
return ui.refuse(sentence(error.message), `${ui.bin} doctor`);
|
|
3030
3097
|
}
|
|
@@ -3035,8 +3102,16 @@ function doAutoupdate(config, dir, options, args, ui) {
|
|
|
3035
3102
|
if (mode !== "status") return ui.refuse(`Unknown autoupdate mode: ${mode}.`, `${ui.bin} autoupdate status`, 2);
|
|
3036
3103
|
const state = querySchedule(config, scheduleOptions);
|
|
3037
3104
|
if (!state.supported) return ui.refuse("Auto-update is not supported on this platform.", `${ui.bin} update`);
|
|
3038
|
-
if (state.enabled)
|
|
3039
|
-
|
|
3105
|
+
if (state.enabled) {
|
|
3106
|
+
const failed = lastResultFailed(state.lastResult);
|
|
3107
|
+
ui.notice(
|
|
3108
|
+
failed ? "note" : "ok",
|
|
3109
|
+
`Auto-update is on and runs every hour.${state.lastRun ? ` Last run: ${state.lastRun}.` : ""}${failed ? ` Last result: ${state.lastResult}.` : ""}`,
|
|
3110
|
+
...failed ? [`${ui.bin} doctor`] : []
|
|
3111
|
+
);
|
|
3112
|
+
return 0;
|
|
3113
|
+
}
|
|
3114
|
+
ui.notice("note", "Auto-update is off.", `${ui.bin} autoupdate on`);
|
|
3040
3115
|
return 0;
|
|
3041
3116
|
}
|
|
3042
3117
|
function localFacts(config, dir, options) {
|
|
@@ -3055,10 +3130,12 @@ function signInRow(local) {
|
|
|
3055
3130
|
if (local.signedIn) return { surface: "sign-in", state: local.expired ? "signed in \xB7 renews on next use" : "signed in", mark: "ok" };
|
|
3056
3131
|
return { surface: "sign-in", state: local.expired ? "expired" : "signed out", mark: "fail" };
|
|
3057
3132
|
}
|
|
3058
|
-
function autoUpdateRow({ supported, enabled, cadence, lastRun }) {
|
|
3133
|
+
function autoUpdateRow({ supported, enabled, cadence, lastRun, lastResult }) {
|
|
3059
3134
|
if (!supported) return { surface: AUTO_UPDATE, state: "unsupported on this platform", mark: "note" };
|
|
3060
3135
|
if (!enabled) return { surface: AUTO_UPDATE, state: "off", mark: "note" };
|
|
3061
|
-
|
|
3136
|
+
const updateFailed = lastResultFailed(lastResult);
|
|
3137
|
+
const note = updateFailed ? lastRun ? `Last run: ${lastRun}. Last run failed (exit ${lastResult})` : `Last run failed (exit ${lastResult})` : lastRun ? `Last run: ${lastRun}` : void 0;
|
|
3138
|
+
return { surface: AUTO_UPDATE, state: `on \xB7 ${cadence ?? "hourly"}`, mark: updateFailed ? "fail" : "ok", ...note ? { note } : {} };
|
|
3062
3139
|
}
|
|
3063
3140
|
function verdictFor(ui, local, updateAvailable, ready) {
|
|
3064
3141
|
if (!local.installed) return { state: "fail", headline: "is not installed.", next: `${ui.bin} install` };
|
|
@@ -3113,7 +3190,12 @@ async function doStatus(config, dir, options, ui, print, json) {
|
|
|
3113
3190
|
installed: local.installed,
|
|
3114
3191
|
release,
|
|
3115
3192
|
signIn: local.signedIn ? local.expired ? "renews" : "signed-in" : local.expired ? "expired" : "signed-out",
|
|
3116
|
-
autoupdate: {
|
|
3193
|
+
autoupdate: {
|
|
3194
|
+
supported: local.schedule.supported,
|
|
3195
|
+
enabled: local.schedule.enabled,
|
|
3196
|
+
lastRun: local.schedule.lastRun ?? null,
|
|
3197
|
+
lastResult: local.schedule.lastResult ?? null
|
|
3198
|
+
},
|
|
3117
3199
|
verdict: verdict.state,
|
|
3118
3200
|
next: verdict.next
|
|
3119
3201
|
}, null, 2));
|
package/dist/launcher.sea.cjs
CHANGED
|
@@ -1009,6 +1009,15 @@ parentPort.on('message', (next) => {
|
|
|
1009
1009
|
});
|
|
1010
1010
|
setInterval(draw, workerData.intervalMs);
|
|
1011
1011
|
`;
|
|
1012
|
+
function awaitWorkerIdle(control, timeoutMs = 250) {
|
|
1013
|
+
const deadline = Date.now() + timeoutMs;
|
|
1014
|
+
while (Atomics.load(control, 1)) {
|
|
1015
|
+
const left = deadline - Date.now();
|
|
1016
|
+
if (left <= 0) return false;
|
|
1017
|
+
Atomics.wait(control, 1, 1, left);
|
|
1018
|
+
}
|
|
1019
|
+
return true;
|
|
1020
|
+
}
|
|
1012
1021
|
function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath, env = process.env, platform = process.platform }) {
|
|
1013
1022
|
animate = animate && !face.nested && !face.emitsProgress;
|
|
1014
1023
|
const glyphs = spinnerFramesFor(env, platform);
|
|
@@ -1041,7 +1050,7 @@ function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath,
|
|
|
1041
1050
|
const pause = () => {
|
|
1042
1051
|
if (!control) return;
|
|
1043
1052
|
Atomics.store(control, 0, 1);
|
|
1044
|
-
|
|
1053
|
+
awaitWorkerIdle(control);
|
|
1045
1054
|
};
|
|
1046
1055
|
const halt = () => {
|
|
1047
1056
|
if (timer) clearInterval(timer);
|
|
@@ -1732,15 +1741,21 @@ function querySchedule(config, options = {}) {
|
|
|
1732
1741
|
if (result.code !== 0) return { supported: true, enabled: false };
|
|
1733
1742
|
const lastRun = valueOf(result.stdout, "Last Run Time:");
|
|
1734
1743
|
const nextRun = valueOf(result.stdout, "Next Run Time:");
|
|
1744
|
+
const lastResult = valueOf(result.stdout, "Last Result:");
|
|
1735
1745
|
const state2 = { supported: true, enabled: true, cadence: "hourly" };
|
|
1736
1746
|
if (lastRun && !/disabled|never|not run/i.test(lastRun)) state2.lastRun = lastRun;
|
|
1737
1747
|
else if (nextRun && !/disabled|never/i.test(nextRun)) state2.lastRun = `next run ${nextRun}`;
|
|
1748
|
+
if (lastResult) state2.lastResult = lastResult;
|
|
1738
1749
|
return state2;
|
|
1739
1750
|
}
|
|
1740
1751
|
if (platform === "darwin") {
|
|
1741
1752
|
const plist = (0, import_node_path5.join)(home, "Library", "LaunchAgents", `${scheduleLabel(config)}.plist`);
|
|
1742
1753
|
if (!(0, import_node_fs10.existsSync)(plist)) return { supported: true, enabled: false };
|
|
1743
|
-
|
|
1754
|
+
const state2 = { supported: true, enabled: true, cadence: "hourly" };
|
|
1755
|
+
const printed = exec("launchctl", ["print", `gui/${process.getuid?.() ?? 501}/${scheduleLabel(config)}`]);
|
|
1756
|
+
const exitCode = /last exit code = (-?\d+)/.exec(`${printed.stdout ?? ""}${printed.stderr ?? ""}`)?.[1];
|
|
1757
|
+
if (printed.code === 0 && exitCode) state2.lastResult = exitCode;
|
|
1758
|
+
return state2;
|
|
1744
1759
|
}
|
|
1745
1760
|
const timer = (0, import_node_path5.join)(home, ".config", "systemd", "user", `${scheduleLabel(config)}.timer`);
|
|
1746
1761
|
if (!(0, import_node_fs10.existsSync)(timer)) return { supported: true, enabled: false };
|
|
@@ -1748,6 +1763,9 @@ function querySchedule(config, options = {}) {
|
|
|
1748
1763
|
const shown = exec("systemctl", ["--user", "show", `${scheduleLabel(config)}.service`, "-p", "ExecMainStartTimestamp", "--value"]);
|
|
1749
1764
|
const stamp = (shown.stdout ?? "").trim();
|
|
1750
1765
|
if (shown.code === 0 && stamp && stamp !== "n/a") state.lastRun = stamp;
|
|
1766
|
+
const status = exec("systemctl", ["--user", "show", `${scheduleLabel(config)}.service`, "-p", "ExecMainStatus", "--value"]);
|
|
1767
|
+
const code = (status.stdout ?? "").trim();
|
|
1768
|
+
if (status.code === 0 && /^\d+$/.test(code)) state.lastResult = code;
|
|
1751
1769
|
return state;
|
|
1752
1770
|
}
|
|
1753
1771
|
function darwinPlist(label, command2) {
|
|
@@ -1799,6 +1817,36 @@ function valueOf(output, key) {
|
|
|
1799
1817
|
function firstLine(text) {
|
|
1800
1818
|
return String(text).split(/\r?\n/).map((line) => line.trim()).filter(Boolean)[0] ?? "";
|
|
1801
1819
|
}
|
|
1820
|
+
var SCHEDULE_SIGNAL = "MM_LAUNCHER_SCHEDULE";
|
|
1821
|
+
var OPT_OUT_FILE = "auto-update-off";
|
|
1822
|
+
function autoUpdateOptOut(dir) {
|
|
1823
|
+
return (0, import_node_fs10.existsSync)((0, import_node_path5.join)(dir, OPT_OUT_FILE));
|
|
1824
|
+
}
|
|
1825
|
+
function persistAutoUpdateOptOut(dir, off) {
|
|
1826
|
+
try {
|
|
1827
|
+
if (off) {
|
|
1828
|
+
(0, import_node_fs10.mkdirSync)(dir, { recursive: true });
|
|
1829
|
+
(0, import_node_fs10.writeFileSync)((0, import_node_path5.join)(dir, OPT_OUT_FILE), "");
|
|
1830
|
+
} else (0, import_node_fs10.rmSync)((0, import_node_path5.join)(dir, OPT_OUT_FILE), { force: true });
|
|
1831
|
+
} catch {
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
function armVerifiedSchedule(config, options) {
|
|
1835
|
+
try {
|
|
1836
|
+
enableSchedule(config, options.command, options);
|
|
1837
|
+
const verified = querySchedule(config, options);
|
|
1838
|
+
if (verified.enabled) return { signal: scheduleName(config), note: null };
|
|
1839
|
+
return { signal: null, note: `The launcher's hourly update task (${scheduleName(config)}) could not be verified \u2014 the product's own auto-update task stays.` };
|
|
1840
|
+
} catch (error) {
|
|
1841
|
+
return { signal: null, note: `The launcher could not arm its hourly update task: ${error.message} The product's own auto-update task stays.` };
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
function lastResultFailed(value) {
|
|
1845
|
+
const text = value?.trim() ?? "";
|
|
1846
|
+
if (!text) return false;
|
|
1847
|
+
if (!/^-?(?:0x[0-9a-f]+|\d+)$/i.test(text)) return true;
|
|
1848
|
+
return ![0, 267011, 267009].includes(Number(text));
|
|
1849
|
+
}
|
|
1802
1850
|
|
|
1803
1851
|
// src/login-github.ts
|
|
1804
1852
|
var import_node_child_process3 = require("node:child_process");
|
|
@@ -2298,7 +2346,7 @@ async function refreshLauncher(target, options = {}) {
|
|
|
2298
2346
|
}
|
|
2299
2347
|
|
|
2300
2348
|
// src/index.ts
|
|
2301
|
-
var LAUNCHER_VERSION = true ? "1.
|
|
2349
|
+
var LAUNCHER_VERSION = true ? "1.5.1" : readVersionFromPackage();
|
|
2302
2350
|
function defaultPrint(message) {
|
|
2303
2351
|
process.stdout.write(`${message}
|
|
2304
2352
|
`);
|
|
@@ -2755,6 +2803,8 @@ async function installOrUpdateRun(config, dir, options, print, update, flags2, m
|
|
|
2755
2803
|
installer.finish({ ...pointer ? { version: pointer } : {}, total: 1, updated: pointer && installed !== pointer ? 1 : 0, failed: 0, dryRun: true });
|
|
2756
2804
|
return 0;
|
|
2757
2805
|
}
|
|
2806
|
+
const armNote = armScheduleForInstall(config, dir, options);
|
|
2807
|
+
if (armNote) installer.phase("arm", { state: "note", detail: armNote });
|
|
2758
2808
|
if (pointer && current?.version === pointer && payloadPresent) {
|
|
2759
2809
|
version = pointer;
|
|
2760
2810
|
installer.phase("resolve", { seconds: (Date.now() - started) / 1e3 });
|
|
@@ -2847,6 +2897,18 @@ async function installOrUpdateRun(config, dir, options, print, update, flags2, m
|
|
|
2847
2897
|
installer.stop();
|
|
2848
2898
|
}
|
|
2849
2899
|
}
|
|
2900
|
+
function armScheduleForInstall(config, dir, options) {
|
|
2901
|
+
if (autoUpdateOptOut(dir)) return null;
|
|
2902
|
+
if (!(0, import_node_sea2.isSea)() && !options.autoupdate) return null;
|
|
2903
|
+
const result = armVerifiedSchedule(config, {
|
|
2904
|
+
command: options.autoupdate?.command ?? [process.execPath, "update"],
|
|
2905
|
+
stateDir: dir,
|
|
2906
|
+
...options.autoupdate
|
|
2907
|
+
});
|
|
2908
|
+
if (!result.signal) return result.note;
|
|
2909
|
+
process.env[SCHEDULE_SIGNAL] = result.signal;
|
|
2910
|
+
return null;
|
|
2911
|
+
}
|
|
2850
2912
|
function doInstall(config, dir, options, print, flags2) {
|
|
2851
2913
|
return installOrUpdate(config, dir, options, print, false, flags2);
|
|
2852
2914
|
}
|
|
@@ -3056,8 +3118,13 @@ function doAutoupdate(config, dir, options, args, ui) {
|
|
|
3056
3118
|
const name = identityFor(ui.product).name;
|
|
3057
3119
|
if (mode === "on" || mode === "off") {
|
|
3058
3120
|
try {
|
|
3059
|
-
if (mode === "on")
|
|
3060
|
-
|
|
3121
|
+
if (mode === "on") {
|
|
3122
|
+
enableSchedule(config, command2, scheduleOptions);
|
|
3123
|
+
persistAutoUpdateOptOut(dir, false);
|
|
3124
|
+
} else {
|
|
3125
|
+
disableSchedule(config, scheduleOptions);
|
|
3126
|
+
persistAutoUpdateOptOut(dir, true);
|
|
3127
|
+
}
|
|
3061
3128
|
} catch (error) {
|
|
3062
3129
|
return ui.refuse(sentence(error.message), `${ui.bin} doctor`);
|
|
3063
3130
|
}
|
|
@@ -3068,8 +3135,16 @@ function doAutoupdate(config, dir, options, args, ui) {
|
|
|
3068
3135
|
if (mode !== "status") return ui.refuse(`Unknown autoupdate mode: ${mode}.`, `${ui.bin} autoupdate status`, 2);
|
|
3069
3136
|
const state = querySchedule(config, scheduleOptions);
|
|
3070
3137
|
if (!state.supported) return ui.refuse("Auto-update is not supported on this platform.", `${ui.bin} update`);
|
|
3071
|
-
if (state.enabled)
|
|
3072
|
-
|
|
3138
|
+
if (state.enabled) {
|
|
3139
|
+
const failed = lastResultFailed(state.lastResult);
|
|
3140
|
+
ui.notice(
|
|
3141
|
+
failed ? "note" : "ok",
|
|
3142
|
+
`Auto-update is on and runs every hour.${state.lastRun ? ` Last run: ${state.lastRun}.` : ""}${failed ? ` Last result: ${state.lastResult}.` : ""}`,
|
|
3143
|
+
...failed ? [`${ui.bin} doctor`] : []
|
|
3144
|
+
);
|
|
3145
|
+
return 0;
|
|
3146
|
+
}
|
|
3147
|
+
ui.notice("note", "Auto-update is off.", `${ui.bin} autoupdate on`);
|
|
3073
3148
|
return 0;
|
|
3074
3149
|
}
|
|
3075
3150
|
function localFacts(config, dir, options) {
|
|
@@ -3088,10 +3163,12 @@ function signInRow(local) {
|
|
|
3088
3163
|
if (local.signedIn) return { surface: "sign-in", state: local.expired ? "signed in \xB7 renews on next use" : "signed in", mark: "ok" };
|
|
3089
3164
|
return { surface: "sign-in", state: local.expired ? "expired" : "signed out", mark: "fail" };
|
|
3090
3165
|
}
|
|
3091
|
-
function autoUpdateRow({ supported, enabled, cadence, lastRun }) {
|
|
3166
|
+
function autoUpdateRow({ supported, enabled, cadence, lastRun, lastResult }) {
|
|
3092
3167
|
if (!supported) return { surface: AUTO_UPDATE, state: "unsupported on this platform", mark: "note" };
|
|
3093
3168
|
if (!enabled) return { surface: AUTO_UPDATE, state: "off", mark: "note" };
|
|
3094
|
-
|
|
3169
|
+
const updateFailed = lastResultFailed(lastResult);
|
|
3170
|
+
const note = updateFailed ? lastRun ? `Last run: ${lastRun}. Last run failed (exit ${lastResult})` : `Last run failed (exit ${lastResult})` : lastRun ? `Last run: ${lastRun}` : void 0;
|
|
3171
|
+
return { surface: AUTO_UPDATE, state: `on \xB7 ${cadence ?? "hourly"}`, mark: updateFailed ? "fail" : "ok", ...note ? { note } : {} };
|
|
3095
3172
|
}
|
|
3096
3173
|
function verdictFor(ui, local, updateAvailable, ready) {
|
|
3097
3174
|
if (!local.installed) return { state: "fail", headline: "is not installed.", next: `${ui.bin} install` };
|
|
@@ -3146,7 +3223,12 @@ async function doStatus(config, dir, options, ui, print, json) {
|
|
|
3146
3223
|
installed: local.installed,
|
|
3147
3224
|
release,
|
|
3148
3225
|
signIn: local.signedIn ? local.expired ? "renews" : "signed-in" : local.expired ? "expired" : "signed-out",
|
|
3149
|
-
autoupdate: {
|
|
3226
|
+
autoupdate: {
|
|
3227
|
+
supported: local.schedule.supported,
|
|
3228
|
+
enabled: local.schedule.enabled,
|
|
3229
|
+
lastRun: local.schedule.lastRun ?? null,
|
|
3230
|
+
lastResult: local.schedule.lastResult ?? null
|
|
3231
|
+
},
|
|
3150
3232
|
verdict: verdict.state,
|
|
3151
3233
|
next: verdict.next
|
|
3152
3234
|
}, null, 2));
|
package/package.json
CHANGED