@uniqbit/mate-core 0.15.0-canary.3 → 0.15.0-canary.6
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/package.json +1 -1
- package/src/cli/main.ts +9 -1
- package/src/distribution.ts +11 -4
- package/src/lib/update-checker.ts +26 -3
package/package.json
CHANGED
package/src/cli/main.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getActiveDistribution } from "../distribution";
|
|
2
2
|
import {
|
|
3
|
+
enforceUpdateIfRequired,
|
|
3
4
|
scheduleBackgroundCheck,
|
|
4
5
|
showUpdateBannerIfAvailable,
|
|
5
6
|
UpdateStateStore,
|
|
@@ -56,8 +57,15 @@ export async function main(argv = process.argv, deps: MainDeps = mainDeps): Prom
|
|
|
56
57
|
command === "cap" && findPluginCliCommand(subcommand, rest[0]) !== undefined;
|
|
57
58
|
if (!isPluginCommand) {
|
|
58
59
|
const updateStore = new UpdateStateStore();
|
|
59
|
-
await showUpdateBannerIfAvailable(updateStore);
|
|
60
60
|
scheduleBackgroundCheck(updateStore);
|
|
61
|
+
if (
|
|
62
|
+
!isInstallRecoveryCommand(command, subcommand) &&
|
|
63
|
+
(await enforceUpdateIfRequired(updateStore))
|
|
64
|
+
) {
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
await showUpdateBannerIfAvailable(updateStore);
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
package/src/distribution.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { PluginRegistry } from "./tools/setup/registry";
|
|
2
2
|
|
|
3
3
|
export interface DistributionUpdateConfig {
|
|
4
|
-
/** npm package whose versions are checked and installed by `mate update`. */
|
|
5
|
-
packageName
|
|
6
|
-
/** npm registry used for update checks and downloads. */
|
|
7
|
-
registry
|
|
4
|
+
/** npm package whose versions are checked and installed by `mate update`. Defaults to `@uniqbit/<name>`. */
|
|
5
|
+
packageName?: string;
|
|
6
|
+
/** npm registry used for update checks and downloads. Defaults to public npm. */
|
|
7
|
+
registry?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Refuse to run commands while a newer version is available, instead of
|
|
10
|
+
* only printing a banner. Install-recovery commands (`install`, `update`,
|
|
11
|
+
* `doctor`, `help`, `companion setup|link`) stay available so the user can
|
|
12
|
+
* actually upgrade.
|
|
13
|
+
*/
|
|
14
|
+
enforce?: boolean;
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
/** Identity and version of the distribution assembled through `createMate`. */
|
|
@@ -13,7 +13,7 @@ interface UpdateState {
|
|
|
13
13
|
latestVersion: string | null;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const SIX_HOURS_MS = 6 * 60 * 60 * 1000;
|
|
17
17
|
|
|
18
18
|
export const updateCheckerDeps = {
|
|
19
19
|
now: () => Date.now(),
|
|
@@ -34,11 +34,12 @@ export function getCurrentVersion(): string {
|
|
|
34
34
|
return getActiveDistribution().config.version;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export function getUpdateConfig(): DistributionUpdateConfig {
|
|
37
|
+
export function getUpdateConfig(): Required<DistributionUpdateConfig> {
|
|
38
38
|
const { name, update } = getActiveDistribution().config;
|
|
39
39
|
return {
|
|
40
40
|
packageName: update?.packageName ?? `@uniqbit/${name}`,
|
|
41
41
|
registry: update?.registry ?? PUBLIC_NPM_REGISTRY,
|
|
42
|
+
enforce: update?.enforce ?? false,
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -69,6 +70,28 @@ export async function showUpdateBannerIfAvailable(store: UpdateStateStore): Prom
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Distributions that set `update.enforce` refuse to run further commands while
|
|
75
|
+
* a cached newer version is available. Returns true when the current command
|
|
76
|
+
* must stop; state-load failures never block.
|
|
77
|
+
*/
|
|
78
|
+
export async function enforceUpdateIfRequired(store: UpdateStateStore): Promise<boolean> {
|
|
79
|
+
if (!getUpdateConfig().enforce) return false;
|
|
80
|
+
try {
|
|
81
|
+
const state = await store.load();
|
|
82
|
+
if (!state.latestVersion) return false;
|
|
83
|
+
const current = getCurrentVersion();
|
|
84
|
+
if (!isNewer(state.latestVersion, current)) return false;
|
|
85
|
+
process.stderr.write(
|
|
86
|
+
`\n${frameworkConfig.name}: update required (${current} → ${state.latestVersion})\n`,
|
|
87
|
+
);
|
|
88
|
+
process.stderr.write(` Run \`${frameworkConfig.name} update\` before continuing.\n\n`);
|
|
89
|
+
return true;
|
|
90
|
+
} catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
72
95
|
export async function fetchLatestVersion(): Promise<string> {
|
|
73
96
|
const { packageName, registry } = getUpdateConfig();
|
|
74
97
|
return fetchPublicPackageVersion(packageName, registry);
|
|
@@ -79,7 +102,7 @@ export function scheduleBackgroundCheck(store: UpdateStateStore): void {
|
|
|
79
102
|
try {
|
|
80
103
|
const state = await store.load();
|
|
81
104
|
const lastChecked = state.lastChecked ? new Date(state.lastChecked).getTime() : 0;
|
|
82
|
-
if (updateCheckerDeps.now() - lastChecked <
|
|
105
|
+
if (updateCheckerDeps.now() - lastChecked < SIX_HOURS_MS) return;
|
|
83
106
|
const latestVersion = await fetchLatestVersion();
|
|
84
107
|
await store.save({ lastChecked: updateCheckerDeps.toIsoString(), latestVersion });
|
|
85
108
|
} catch {
|