@flowscripter/dynamic-cli-framework 5.3.5 → 5.4.0
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/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginAddSubCommand.js +4 -2
- package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginRemoveSubCommand.js +2 -1
- package/dist/src/service/upgrade/DefaultUpgradeService.d.ts +3 -2
- package/dist/src/service/upgrade/DefaultUpgradeService.d.ts.map +1 -1
- package/dist/src/service/upgrade/DefaultUpgradeService.js +70 -18
- package/dist/src/service/upgrade/UpgradeServiceProvider.d.ts.map +1 -1
- package/dist/src/service/upgrade/UpgradeServiceProvider.js +2 -1
- package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts.map +1 -1
- package/dist/src/service/upgrade/command/UpgradeSubCommand.js +4 -1
- package/package.json +1 -1
- package/src/service/plugin/command/PluginAddSubCommand.ts +4 -2
- package/src/service/plugin/command/PluginRemoveSubCommand.ts +2 -1
- package/src/service/upgrade/DefaultUpgradeService.ts +87 -42
- package/src/service/upgrade/UpgradeServiceProvider.ts +2 -1
- package/src/service/upgrade/command/UpgradeSubCommand.ts +7 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginAddSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginAddSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AASxE,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,WAAW,6BAA6B;IACjD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"PluginAddSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginAddSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AASxE,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,WAAW,6BAA6B;IACjD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFrE;CACF"}
|
|
@@ -20,7 +20,7 @@ export class PluginAddSubCommand {
|
|
|
20
20
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID);
|
|
21
21
|
const { pluginId, version } = parsePluginSpecifier(argumentValues["pluginId"]);
|
|
22
22
|
const searchLabel = version ? `${pluginId}@${version}` : pluginId;
|
|
23
|
-
await printerService.
|
|
23
|
+
await printerService.showSpinner(`Searching for plugin: ${searchLabel}`);
|
|
24
24
|
let descriptor;
|
|
25
25
|
for await (const d of pluginService.search({ text: pluginId })) {
|
|
26
26
|
if (getPluginId(d) === pluginId || d.pluginId === pluginId) {
|
|
@@ -28,6 +28,7 @@ export class PluginAddSubCommand {
|
|
|
28
28
|
break;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
await printerService.hideSpinner();
|
|
31
32
|
if (descriptor && version) {
|
|
32
33
|
// search only ever returns the latest version - substitute the explicitly requested
|
|
33
34
|
// version so install() is asked for the correct one.
|
|
@@ -62,7 +63,7 @@ export class PluginAddSubCommand {
|
|
|
62
63
|
? `Version ${versionToCheck} of plugin ${descriptor.pluginId} was not found in the configured plugin registry`
|
|
63
64
|
: `Plugin ${descriptor.pluginId} was not found in the configured plugin registry`);
|
|
64
65
|
}
|
|
65
|
-
await printerService.
|
|
66
|
+
await printerService.showSpinner(`Installing ${installLabel}...`);
|
|
66
67
|
await pluginService.install(descriptor);
|
|
67
68
|
// Look up the actually-installed version rather than trusting `descriptor.version`: when no
|
|
68
69
|
// version was requested and the plugin wasn't found via search (direct-install fallback),
|
|
@@ -74,6 +75,7 @@ export class PluginAddSubCommand {
|
|
|
74
75
|
break;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
78
|
+
await printerService.hideSpinner();
|
|
77
79
|
await printerService.print(`Plugin ${descriptor.pluginId}@${installedVersion} installed.\n`, Icon.SUCCESS);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginRemoveSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginRemoveSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAMxE,qBAAa,sBAAuB,YAAW,UAAU;IACvD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,uCAAuC;IAC3D,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"PluginRemoveSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginRemoveSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAMxE,qBAAa,sBAAuB,YAAW,UAAU;IACvD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,uCAAuC;IAC3D,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASrE;CACF"}
|
|
@@ -17,8 +17,9 @@ export class PluginRemoveSubCommand {
|
|
|
17
17
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID);
|
|
18
18
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID);
|
|
19
19
|
const pluginId = argumentValues["pluginId"];
|
|
20
|
-
await printerService.
|
|
20
|
+
await printerService.showSpinner(`Removing plugin: ${pluginId}...`);
|
|
21
21
|
await pluginService.uninstall(pluginId);
|
|
22
|
+
await printerService.hideSpinner();
|
|
22
23
|
await printerService.print(`Plugin ${pluginId} removed.\n`, Icon.SUCCESS);
|
|
23
24
|
}
|
|
24
25
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { CLIConfig, FetchService, SpawnService, UpgradeCheckResult, UpgradeResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
|
+
import type { CLIConfig, FetchService, PrinterService, SpawnService, UpgradeCheckResult, UpgradeResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { InstallMethod, SupportedArch, SupportedOs, type UpgradeService } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import type { UpgradeLocationsConfig } from "./UpgradeLocationsConfig.ts";
|
|
4
4
|
export declare const VERSION_CHECK_TIMEOUT_MS = 250;
|
|
5
|
+
export declare function describeUpgradeCheckResult(result: UpgradeCheckResult): string;
|
|
5
6
|
export default class DefaultUpgradeService implements UpgradeService {
|
|
6
7
|
#private;
|
|
7
8
|
constructor(config: UpgradeLocationsConfig, cliConfig: CLIConfig);
|
|
8
|
-
setDependencies(spawnService: SpawnService | undefined, fetchService: FetchService | undefined): void;
|
|
9
|
+
setDependencies(spawnService: SpawnService | undefined, fetchService: FetchService | undefined, printerService: PrinterService | undefined): void;
|
|
9
10
|
getUpgradeCheckResult(waitForResult?: boolean): Promise<UpgradeCheckResult>;
|
|
10
11
|
detectOs(): SupportedOs | undefined;
|
|
11
12
|
detectArch(): SupportedArch | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultUpgradeService.d.ts","sourceRoot":"","sources":["../../../../src/service/upgrade/DefaultUpgradeService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,
|
|
1
|
+
{"version":3,"file":"DefaultUpgradeService.d.ts","sourceRoot":"","sources":["../../../../src/service/upgrade/DefaultUpgradeService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,aAAa,EACb,aAAa,EACb,WAAW,EACX,KAAK,cAAc,EACpB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAS1E,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAY5C,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAI7E;AAQD,MAAM,CAAC,OAAO,OAAO,qBAAsB,YAAW,cAAc;;IAQlE,YAAmB,MAAM,EAAE,sBAAsB,EAAE,SAAS,EAAE,SAAS,EAGtE;IAEM,eAAe,CACpB,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,cAAc,EAAE,cAAc,GAAG,SAAS,GACzC,IAAI,CAIN;IAoCM,qBAAqB,CAAC,aAAa,UAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0B/E;IAEM,QAAQ,IAAI,WAAW,GAAG,SAAS,CAWzC;IAEM,UAAU,IAAI,aAAa,GAAG,SAAS,CAS7C;IAEY,mBAAmB,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAcpF;IAEY,eAAe,CAC1B,UAAU,CAAC,EAAE,WAAW,EACxB,YAAY,CAAC,EAAE,aAAa,EAC5B,qBAAqB,CAAC,EAAE,aAAa,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAsC7B;IAEY,OAAO,CAClB,UAAU,CAAC,EAAE,WAAW,EACxB,YAAY,CAAC,EAAE,aAAa,EAC5B,qBAAqB,CAAC,EAAE,aAAa,GACpC,OAAO,CAAC,aAAa,CAAC,CAsDxB;CAiRF"}
|
|
@@ -16,6 +16,11 @@ function describeSpawnFailure(result) {
|
|
|
16
16
|
? "timed out"
|
|
17
17
|
: (result.error?.message ?? `exit code ${result.exitCode}`);
|
|
18
18
|
}
|
|
19
|
+
export function describeUpgradeCheckResult(result) {
|
|
20
|
+
return result.status === "failed"
|
|
21
|
+
? `Upgrade check result: failed - ${result.error.message}`
|
|
22
|
+
: `Upgrade check result: ${JSON.stringify(result)}`;
|
|
23
|
+
}
|
|
19
24
|
const OS_LABELS = {
|
|
20
25
|
[SupportedOs.LINUX]: "Linux",
|
|
21
26
|
[SupportedOs.MACOS]: "MacOS",
|
|
@@ -24,6 +29,7 @@ const OS_LABELS = {
|
|
|
24
29
|
export default class DefaultUpgradeService {
|
|
25
30
|
#spawnService;
|
|
26
31
|
#fetchService;
|
|
32
|
+
#printerService;
|
|
27
33
|
#upgradeCheckPromise;
|
|
28
34
|
#config;
|
|
29
35
|
#cliConfig;
|
|
@@ -31,9 +37,40 @@ export default class DefaultUpgradeService {
|
|
|
31
37
|
this.#config = config;
|
|
32
38
|
this.#cliConfig = cliConfig;
|
|
33
39
|
}
|
|
34
|
-
setDependencies(spawnService, fetchService) {
|
|
40
|
+
setDependencies(spawnService, fetchService, printerService) {
|
|
35
41
|
this.#spawnService = spawnService;
|
|
36
42
|
this.#fetchService = fetchService;
|
|
43
|
+
this.#printerService = printerService;
|
|
44
|
+
}
|
|
45
|
+
// Mirrors SpawnInterfaceAdapter's plugin:add/plugin:remove pattern: wrap a spawned command's
|
|
46
|
+
// output in a quoted, marked block that's cleared on success (so a clean install stays quiet)
|
|
47
|
+
// but left on screen on failure (so the diagnostic output remains visible).
|
|
48
|
+
async #spawnQuoted(command) {
|
|
49
|
+
const spawnService = this.#spawnService;
|
|
50
|
+
const printerService = this.#printerService;
|
|
51
|
+
if (!printerService) {
|
|
52
|
+
return spawnService.spawn(command, { mode: "ignore" });
|
|
53
|
+
}
|
|
54
|
+
printerService.startQuote();
|
|
55
|
+
printerService.startMark();
|
|
56
|
+
// onOutput is synchronous and may be called concurrently for stdout/stderr lines, but
|
|
57
|
+
// printerService.info() is async and must not be invoked concurrently with itself - queue
|
|
58
|
+
// writes so they're applied one at a time, in call order.
|
|
59
|
+
let writeQueue = Promise.resolve();
|
|
60
|
+
const onOutput = (line) => {
|
|
61
|
+
writeQueue = writeQueue.then(() => printerService.info(`${line}\n`));
|
|
62
|
+
};
|
|
63
|
+
const result = await spawnService.spawn(command, { mode: "wrapped", onOutput });
|
|
64
|
+
await writeQueue;
|
|
65
|
+
printerService.endQuote();
|
|
66
|
+
printerService.endMark();
|
|
67
|
+
if (result.ok) {
|
|
68
|
+
await printerService.clearMarked();
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
printerService.discardMark();
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
37
74
|
}
|
|
38
75
|
getUpgradeCheckResult(waitForResult = false) {
|
|
39
76
|
if (!this.#upgradeCheckPromise) {
|
|
@@ -45,7 +82,7 @@ export default class DefaultUpgradeService {
|
|
|
45
82
|
// waiting via waitForResult=true) any chance of a fresh attempt for the rest of this
|
|
46
83
|
// process's lifetime.
|
|
47
84
|
this.#upgradeCheckPromise = this.checkForUpgrade().then((result) => {
|
|
48
|
-
logger.debug(() =>
|
|
85
|
+
logger.debug(() => describeUpgradeCheckResult(result));
|
|
49
86
|
if (result.status === "failed") {
|
|
50
87
|
this.#upgradeCheckPromise = undefined;
|
|
51
88
|
}
|
|
@@ -156,7 +193,13 @@ export default class DefaultUpgradeService {
|
|
|
156
193
|
if (checkResult.installMethod === InstallMethod.GITHUB_RELEASE && !this.#fetchService) {
|
|
157
194
|
return { ok: false, oldVersion, error: new Error("FetchService is not available") };
|
|
158
195
|
}
|
|
196
|
+
if (this.#printerService) {
|
|
197
|
+
await this.#printerService.showSpinner(`Installing version ${checkResult.latestVersion}...`);
|
|
198
|
+
}
|
|
159
199
|
try {
|
|
200
|
+
if (this.#printerService) {
|
|
201
|
+
await this.#printerService.hideSpinner();
|
|
202
|
+
}
|
|
160
203
|
switch (checkResult.installMethod) {
|
|
161
204
|
case InstallMethod.LINUX_SCRIPT:
|
|
162
205
|
await this.#upgradeViaLinuxScript();
|
|
@@ -301,25 +344,21 @@ export default class DefaultUpgradeService {
|
|
|
301
344
|
}
|
|
302
345
|
async #upgradeViaLinuxScript() {
|
|
303
346
|
const { scriptUrl } = this.#config.linuxScript;
|
|
304
|
-
const result = await this.#
|
|
305
|
-
mode: "ignore",
|
|
306
|
-
});
|
|
347
|
+
const result = await this.#spawnQuoted(["sh", "-c", `curl -fsSL ${scriptUrl} | sh`]);
|
|
307
348
|
if (!result.ok) {
|
|
308
349
|
throw new Error(`Install script failed: ${describeSpawnFailure(result)}`);
|
|
309
350
|
}
|
|
310
351
|
}
|
|
311
352
|
async #upgradeViaHomebrew() {
|
|
312
353
|
const { tap, formula } = this.#config.homebrew;
|
|
313
|
-
const result = await this.#
|
|
314
|
-
mode: "ignore",
|
|
315
|
-
});
|
|
354
|
+
const result = await this.#spawnQuoted(["brew", "upgrade", `${tap}/${formula}`]);
|
|
316
355
|
if (!result.ok) {
|
|
317
356
|
throw new Error(`brew upgrade failed: ${describeSpawnFailure(result)}`);
|
|
318
357
|
}
|
|
319
358
|
}
|
|
320
359
|
async #upgradeViaWinget() {
|
|
321
360
|
const { packageId } = this.#config.winget;
|
|
322
|
-
const result = await this.#
|
|
361
|
+
const result = await this.#spawnQuoted([
|
|
323
362
|
"winget",
|
|
324
363
|
"upgrade",
|
|
325
364
|
"--id",
|
|
@@ -327,7 +366,7 @@ export default class DefaultUpgradeService {
|
|
|
327
366
|
"--silent",
|
|
328
367
|
"--accept-package-agreements",
|
|
329
368
|
"--accept-source-agreements",
|
|
330
|
-
]
|
|
369
|
+
]);
|
|
331
370
|
if (!result.ok) {
|
|
332
371
|
throw new Error(`winget upgrade failed: ${describeSpawnFailure(result)}`);
|
|
333
372
|
}
|
|
@@ -351,11 +390,11 @@ export default class DefaultUpgradeService {
|
|
|
351
390
|
await Bun.write(archivePath, archiveData);
|
|
352
391
|
const currentExecutable = process.execPath;
|
|
353
392
|
if (os === SupportedOs.WINDOWS) {
|
|
354
|
-
const extractResult = await this.#
|
|
393
|
+
const extractResult = await this.#spawnQuoted([
|
|
355
394
|
"powershell",
|
|
356
395
|
"-Command",
|
|
357
396
|
`Expand-Archive -Path '${archivePath}' -DestinationPath '${tmpDir}' -Force`,
|
|
358
|
-
]
|
|
397
|
+
]);
|
|
359
398
|
if (!extractResult.ok) {
|
|
360
399
|
throw new Error("Failed to extract release archive");
|
|
361
400
|
}
|
|
@@ -365,23 +404,36 @@ export default class DefaultUpgradeService {
|
|
|
365
404
|
// Windows won't let us delete the just-renamed-aside exe while this process still has it
|
|
366
405
|
// open/mapped - that can only happen once we're no longer holding it, i.e. at the start of
|
|
367
406
|
// the NEXT invocation, before we move today's running exe aside. Ignore failures: the file
|
|
368
|
-
// may not exist, or may still be locked (e.g. another instance still running).
|
|
407
|
+
// may not exist, or may still be locked (e.g. another instance still running). Not quoted -
|
|
408
|
+
// this is expected to fail silently, there's nothing worth showing the user.
|
|
369
409
|
await this.#spawnService.spawn(["cmd", "/c", "del", "/f", "/q", oldPath], {
|
|
370
410
|
mode: "ignore",
|
|
371
411
|
});
|
|
372
|
-
const moveResult = await this.#
|
|
412
|
+
const moveResult = await this.#spawnQuoted([
|
|
413
|
+
"cmd",
|
|
414
|
+
"/c",
|
|
415
|
+
"move",
|
|
416
|
+
"/y",
|
|
417
|
+
currentExecutable,
|
|
418
|
+
oldPath,
|
|
419
|
+
]);
|
|
373
420
|
if (!moveResult.ok) {
|
|
374
421
|
throw new Error("Failed to move current executable aside");
|
|
375
422
|
}
|
|
376
|
-
const copyResult = await this.#
|
|
423
|
+
const copyResult = await this.#spawnQuoted([
|
|
424
|
+
"cmd",
|
|
425
|
+
"/c",
|
|
426
|
+
"copy",
|
|
427
|
+
"/y",
|
|
428
|
+
extractedBinary,
|
|
429
|
+
currentExecutable,
|
|
430
|
+
]);
|
|
377
431
|
if (!copyResult.ok) {
|
|
378
432
|
throw new Error("Failed to copy new executable into place");
|
|
379
433
|
}
|
|
380
434
|
}
|
|
381
435
|
else {
|
|
382
|
-
const extractResult = await this.#
|
|
383
|
-
mode: "ignore",
|
|
384
|
-
});
|
|
436
|
+
const extractResult = await this.#spawnQuoted(["unzip", "-o", archivePath, "-d", tmpDir]);
|
|
385
437
|
if (!extractResult.ok) {
|
|
386
438
|
throw new Error("Failed to extract release archive");
|
|
387
439
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpgradeServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/upgrade/UpgradeServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAczE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAK1E,MAAM,CAAC,OAAO,OAAO,sBAAuB,YAAW,eAAe;;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAsB;IAChD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAKjC,YAAmB,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,EAGzE;IAEM,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAOhE;IAEY,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"UpgradeServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/upgrade/UpgradeServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAczE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAK1E,MAAM,CAAC,OAAO,OAAO,sBAAuB,YAAW,eAAe;;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAsB;IAChD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAKjC,YAAmB,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,EAGzE;IAEM,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAOhE;IAEY,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFxD;CAoCF"}
|
|
@@ -41,7 +41,8 @@ export default class UpgradeServiceProvider {
|
|
|
41
41
|
if (fetchService === undefined) {
|
|
42
42
|
logger.debug(() => "FetchService not available, upgrade version checks will be unavailable");
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
const printerService = context.getServiceById(PRINTER_SERVICE_ID);
|
|
45
|
+
upgradeService.setDependencies(spawnService, fetchService, printerService);
|
|
45
46
|
void upgradeService.getUpgradeCheckResult();
|
|
46
47
|
if (!context.doesServiceExist(PROMPTER_SERVICE_ID)) {
|
|
47
48
|
logger.debug(() => "PrompterService not available, skipping auto-upgrade");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpgradeSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/upgrade/command/UpgradeSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,yCAAyC,CAAC;AASrF,OAAO,KAAK,qBAAqB,MAAM,6BAA6B,CAAC;AAErE,qBAAa,iBAAkB,YAAW,UAAU;;IAClD,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,6CAA6C;IACjE,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,WAAW,UAAM;IAE1B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAerC;IAIF,YAAmB,cAAc,EAAE,qBAAqB,EAEvD;IAEY,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"UpgradeSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/upgrade/command/UpgradeSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,yCAAyC,CAAC;AASrF,OAAO,KAAK,qBAAqB,MAAM,6BAA6B,CAAC;AAErE,qBAAa,iBAAkB,YAAW,UAAU;;IAClD,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,6CAA6C;IACjE,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,WAAW,UAAM;IAE1B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAerC;IAIF,YAAmB,cAAc,EAAE,qBAAqB,EAEvD;IAEY,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4D5E;CACF"}
|
|
@@ -28,12 +28,15 @@ export class UpgradeSubCommand {
|
|
|
28
28
|
async execute(context, argumentValues) {
|
|
29
29
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID);
|
|
30
30
|
const cliName = context.cliConfig.name;
|
|
31
|
+
const currentVersion = context.cliConfig.version;
|
|
31
32
|
const os = argumentValues.os;
|
|
32
33
|
const arch = undefined;
|
|
33
34
|
const installMethod = argumentValues["install-method"];
|
|
35
|
+
await printerService.showSpinner(`Looking for version newer than ${currentVersion}`);
|
|
34
36
|
const checkResult = os === undefined && installMethod === undefined
|
|
35
37
|
? await this.#upgradeService.getUpgradeCheckResult(true)
|
|
36
38
|
: await this.#upgradeService.checkForUpgrade(os, arch, installMethod);
|
|
39
|
+
await printerService.hideSpinner();
|
|
37
40
|
if (checkResult.status === "unsupported") {
|
|
38
41
|
await printerService.error(`No upgrade location is configured for the detected or requested platform.\n`, Icon.FAILURE);
|
|
39
42
|
return;
|
|
@@ -48,7 +51,7 @@ export class UpgradeSubCommand {
|
|
|
48
51
|
return;
|
|
49
52
|
}
|
|
50
53
|
if (!checkResult.updateAvailable) {
|
|
51
|
-
await printerService.print(`${cliName} is already up to date
|
|
54
|
+
await printerService.print(`${cliName} is already up to date: ${checkResult.currentVersion}\n`, Icon.INFORMATION);
|
|
52
55
|
return;
|
|
53
56
|
}
|
|
54
57
|
const upgradeResult = await this.#upgradeService.upgrade(os, arch, installMethod);
|
package/package.json
CHANGED
|
@@ -29,7 +29,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
29
29
|
|
|
30
30
|
const { pluginId, version } = parsePluginSpecifier(argumentValues["pluginId"] as string);
|
|
31
31
|
const searchLabel = version ? `${pluginId}@${version}` : pluginId;
|
|
32
|
-
await printerService.
|
|
32
|
+
await printerService.showSpinner(`Searching for plugin: ${searchLabel}`);
|
|
33
33
|
|
|
34
34
|
let descriptor: VersionedPluginDescriptor | undefined;
|
|
35
35
|
for await (const d of pluginService.search({ text: pluginId })) {
|
|
@@ -38,6 +38,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
38
38
|
break;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
await printerService.hideSpinner();
|
|
41
42
|
|
|
42
43
|
if (descriptor && version) {
|
|
43
44
|
// search only ever returns the latest version - substitute the explicitly requested
|
|
@@ -83,7 +84,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
83
84
|
);
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
await printerService.
|
|
87
|
+
await printerService.showSpinner(`Installing ${installLabel}...`);
|
|
87
88
|
await pluginService.install(descriptor);
|
|
88
89
|
|
|
89
90
|
// Look up the actually-installed version rather than trusting `descriptor.version`: when no
|
|
@@ -96,6 +97,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
96
97
|
break;
|
|
97
98
|
}
|
|
98
99
|
}
|
|
100
|
+
await printerService.hideSpinner();
|
|
99
101
|
|
|
100
102
|
await printerService.print(
|
|
101
103
|
`Plugin ${descriptor.pluginId}@${installedVersion} installed.\n`,
|
|
@@ -25,8 +25,9 @@ export class PluginRemoveSubCommand implements SubCommand {
|
|
|
25
25
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID) as PluginService;
|
|
26
26
|
|
|
27
27
|
const pluginId = argumentValues["pluginId"] as string;
|
|
28
|
-
await printerService.
|
|
28
|
+
await printerService.showSpinner(`Removing plugin: ${pluginId}...`);
|
|
29
29
|
await pluginService.uninstall(pluginId);
|
|
30
|
+
await printerService.hideSpinner();
|
|
30
31
|
await printerService.print(`Plugin ${pluginId} removed.\n`, Icon.SUCCESS);
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -5,6 +5,7 @@ import { dirname, join } from "node:path";
|
|
|
5
5
|
import type {
|
|
6
6
|
CLIConfig,
|
|
7
7
|
FetchService,
|
|
8
|
+
PrinterService,
|
|
8
9
|
SpawnResult,
|
|
9
10
|
SpawnService,
|
|
10
11
|
UpgradeCheckResult,
|
|
@@ -38,6 +39,12 @@ function describeSpawnFailure(result: Extract<SpawnResult, { ok: false }>): stri
|
|
|
38
39
|
: (result.error?.message ?? `exit code ${result.exitCode}`);
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
export function describeUpgradeCheckResult(result: UpgradeCheckResult): string {
|
|
43
|
+
return result.status === "failed"
|
|
44
|
+
? `Upgrade check result: failed - ${result.error.message}`
|
|
45
|
+
: `Upgrade check result: ${JSON.stringify(result)}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
41
48
|
const OS_LABELS: Record<SupportedOs, string> = {
|
|
42
49
|
[SupportedOs.LINUX]: "Linux",
|
|
43
50
|
[SupportedOs.MACOS]: "MacOS",
|
|
@@ -47,6 +54,7 @@ const OS_LABELS: Record<SupportedOs, string> = {
|
|
|
47
54
|
export default class DefaultUpgradeService implements UpgradeService {
|
|
48
55
|
#spawnService: SpawnService | undefined;
|
|
49
56
|
#fetchService: FetchService | undefined;
|
|
57
|
+
#printerService: PrinterService | undefined;
|
|
50
58
|
#upgradeCheckPromise: Promise<UpgradeCheckResult> | undefined;
|
|
51
59
|
readonly #config: UpgradeLocationsConfig;
|
|
52
60
|
readonly #cliConfig: CLIConfig;
|
|
@@ -59,9 +67,45 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
59
67
|
public setDependencies(
|
|
60
68
|
spawnService: SpawnService | undefined,
|
|
61
69
|
fetchService: FetchService | undefined,
|
|
70
|
+
printerService: PrinterService | undefined,
|
|
62
71
|
): void {
|
|
63
72
|
this.#spawnService = spawnService;
|
|
64
73
|
this.#fetchService = fetchService;
|
|
74
|
+
this.#printerService = printerService;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Mirrors SpawnInterfaceAdapter's plugin:add/plugin:remove pattern: wrap a spawned command's
|
|
78
|
+
// output in a quoted, marked block that's cleared on success (so a clean install stays quiet)
|
|
79
|
+
// but left on screen on failure (so the diagnostic output remains visible).
|
|
80
|
+
async #spawnQuoted(command: ReadonlyArray<string>): Promise<SpawnResult> {
|
|
81
|
+
const spawnService = this.#spawnService!;
|
|
82
|
+
const printerService = this.#printerService;
|
|
83
|
+
if (!printerService) {
|
|
84
|
+
return spawnService.spawn(command, { mode: "ignore" });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
printerService.startQuote();
|
|
88
|
+
printerService.startMark();
|
|
89
|
+
|
|
90
|
+
// onOutput is synchronous and may be called concurrently for stdout/stderr lines, but
|
|
91
|
+
// printerService.info() is async and must not be invoked concurrently with itself - queue
|
|
92
|
+
// writes so they're applied one at a time, in call order.
|
|
93
|
+
let writeQueue: Promise<void> = Promise.resolve();
|
|
94
|
+
const onOutput = (line: string): void => {
|
|
95
|
+
writeQueue = writeQueue.then(() => printerService.info(`${line}\n`));
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const result = await spawnService.spawn(command, { mode: "wrapped", onOutput });
|
|
99
|
+
await writeQueue;
|
|
100
|
+
|
|
101
|
+
printerService.endQuote();
|
|
102
|
+
printerService.endMark();
|
|
103
|
+
if (result.ok) {
|
|
104
|
+
await printerService.clearMarked();
|
|
105
|
+
} else {
|
|
106
|
+
printerService.discardMark();
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
65
109
|
}
|
|
66
110
|
|
|
67
111
|
public getUpgradeCheckResult(waitForResult = false): Promise<UpgradeCheckResult> {
|
|
@@ -74,7 +118,7 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
74
118
|
// waiting via waitForResult=true) any chance of a fresh attempt for the rest of this
|
|
75
119
|
// process's lifetime.
|
|
76
120
|
this.#upgradeCheckPromise = this.checkForUpgrade().then((result) => {
|
|
77
|
-
logger.debug(() =>
|
|
121
|
+
logger.debug(() => describeUpgradeCheckResult(result));
|
|
78
122
|
if (result.status === "failed") {
|
|
79
123
|
this.#upgradeCheckPromise = undefined;
|
|
80
124
|
}
|
|
@@ -208,7 +252,14 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
208
252
|
return { ok: false, oldVersion, error: new Error("FetchService is not available") };
|
|
209
253
|
}
|
|
210
254
|
|
|
255
|
+
if (this.#printerService) {
|
|
256
|
+
await this.#printerService.showSpinner(`Installing version ${checkResult.latestVersion}...`);
|
|
257
|
+
}
|
|
258
|
+
|
|
211
259
|
try {
|
|
260
|
+
if (this.#printerService) {
|
|
261
|
+
await this.#printerService.hideSpinner();
|
|
262
|
+
}
|
|
212
263
|
switch (checkResult.installMethod) {
|
|
213
264
|
case InstallMethod.LINUX_SCRIPT:
|
|
214
265
|
await this.#upgradeViaLinuxScript();
|
|
@@ -379,9 +430,7 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
379
430
|
|
|
380
431
|
async #upgradeViaLinuxScript(): Promise<void> {
|
|
381
432
|
const { scriptUrl } = this.#config.linuxScript!;
|
|
382
|
-
const result = await this.#
|
|
383
|
-
mode: "ignore",
|
|
384
|
-
});
|
|
433
|
+
const result = await this.#spawnQuoted(["sh", "-c", `curl -fsSL ${scriptUrl} | sh`]);
|
|
385
434
|
if (!result.ok) {
|
|
386
435
|
throw new Error(`Install script failed: ${describeSpawnFailure(result)}`);
|
|
387
436
|
}
|
|
@@ -389,9 +438,7 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
389
438
|
|
|
390
439
|
async #upgradeViaHomebrew(): Promise<void> {
|
|
391
440
|
const { tap, formula } = this.#config.homebrew!;
|
|
392
|
-
const result = await this.#
|
|
393
|
-
mode: "ignore",
|
|
394
|
-
});
|
|
441
|
+
const result = await this.#spawnQuoted(["brew", "upgrade", `${tap}/${formula}`]);
|
|
395
442
|
if (!result.ok) {
|
|
396
443
|
throw new Error(`brew upgrade failed: ${describeSpawnFailure(result)}`);
|
|
397
444
|
}
|
|
@@ -399,18 +446,15 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
399
446
|
|
|
400
447
|
async #upgradeViaWinget(): Promise<void> {
|
|
401
448
|
const { packageId } = this.#config.winget!;
|
|
402
|
-
const result = await this.#
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
],
|
|
412
|
-
{ mode: "ignore" },
|
|
413
|
-
);
|
|
449
|
+
const result = await this.#spawnQuoted([
|
|
450
|
+
"winget",
|
|
451
|
+
"upgrade",
|
|
452
|
+
"--id",
|
|
453
|
+
packageId,
|
|
454
|
+
"--silent",
|
|
455
|
+
"--accept-package-agreements",
|
|
456
|
+
"--accept-source-agreements",
|
|
457
|
+
]);
|
|
414
458
|
if (!result.ok) {
|
|
415
459
|
throw new Error(`winget upgrade failed: ${describeSpawnFailure(result)}`);
|
|
416
460
|
}
|
|
@@ -440,14 +484,11 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
440
484
|
const currentExecutable = process.execPath;
|
|
441
485
|
|
|
442
486
|
if (os === SupportedOs.WINDOWS) {
|
|
443
|
-
const extractResult = await this.#
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
],
|
|
449
|
-
{ mode: "ignore" },
|
|
450
|
-
);
|
|
487
|
+
const extractResult = await this.#spawnQuoted([
|
|
488
|
+
"powershell",
|
|
489
|
+
"-Command",
|
|
490
|
+
`Expand-Archive -Path '${archivePath}' -DestinationPath '${tmpDir}' -Force`,
|
|
491
|
+
]);
|
|
451
492
|
if (!extractResult.ok) {
|
|
452
493
|
throw new Error("Failed to extract release archive");
|
|
453
494
|
}
|
|
@@ -458,32 +499,36 @@ export default class DefaultUpgradeService implements UpgradeService {
|
|
|
458
499
|
// Windows won't let us delete the just-renamed-aside exe while this process still has it
|
|
459
500
|
// open/mapped - that can only happen once we're no longer holding it, i.e. at the start of
|
|
460
501
|
// the NEXT invocation, before we move today's running exe aside. Ignore failures: the file
|
|
461
|
-
// may not exist, or may still be locked (e.g. another instance still running).
|
|
502
|
+
// may not exist, or may still be locked (e.g. another instance still running). Not quoted -
|
|
503
|
+
// this is expected to fail silently, there's nothing worth showing the user.
|
|
462
504
|
await this.#spawnService!.spawn(["cmd", "/c", "del", "/f", "/q", oldPath], {
|
|
463
505
|
mode: "ignore",
|
|
464
506
|
});
|
|
465
507
|
|
|
466
|
-
const moveResult = await this.#
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
508
|
+
const moveResult = await this.#spawnQuoted([
|
|
509
|
+
"cmd",
|
|
510
|
+
"/c",
|
|
511
|
+
"move",
|
|
512
|
+
"/y",
|
|
513
|
+
currentExecutable,
|
|
514
|
+
oldPath,
|
|
515
|
+
]);
|
|
470
516
|
if (!moveResult.ok) {
|
|
471
517
|
throw new Error("Failed to move current executable aside");
|
|
472
518
|
}
|
|
473
|
-
const copyResult = await this.#
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
519
|
+
const copyResult = await this.#spawnQuoted([
|
|
520
|
+
"cmd",
|
|
521
|
+
"/c",
|
|
522
|
+
"copy",
|
|
523
|
+
"/y",
|
|
524
|
+
extractedBinary,
|
|
525
|
+
currentExecutable,
|
|
526
|
+
]);
|
|
477
527
|
if (!copyResult.ok) {
|
|
478
528
|
throw new Error("Failed to copy new executable into place");
|
|
479
529
|
}
|
|
480
530
|
} else {
|
|
481
|
-
const extractResult = await this.#
|
|
482
|
-
["unzip", "-o", archivePath, "-d", tmpDir],
|
|
483
|
-
{
|
|
484
|
-
mode: "ignore",
|
|
485
|
-
},
|
|
486
|
-
);
|
|
531
|
+
const extractResult = await this.#spawnQuoted(["unzip", "-o", archivePath, "-d", tmpDir]);
|
|
487
532
|
if (!extractResult.ok) {
|
|
488
533
|
throw new Error("Failed to extract release archive");
|
|
489
534
|
}
|
|
@@ -56,7 +56,8 @@ export default class UpgradeServiceProvider implements ServiceProvider {
|
|
|
56
56
|
if (fetchService === undefined) {
|
|
57
57
|
logger.debug(() => "FetchService not available, upgrade version checks will be unavailable");
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
60
|
+
upgradeService.setDependencies(spawnService, fetchService, printerService);
|
|
60
61
|
|
|
61
62
|
void upgradeService.getUpgradeCheckResult();
|
|
62
63
|
|
|
@@ -44,15 +44,20 @@ export class UpgradeSubCommand implements SubCommand {
|
|
|
44
44
|
public async execute(context: Context, argumentValues: Values): Promise<void> {
|
|
45
45
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
46
46
|
const cliName = context.cliConfig.name;
|
|
47
|
+
const currentVersion = context.cliConfig.version;
|
|
47
48
|
|
|
48
49
|
const os = argumentValues.os as SupportedOs | undefined;
|
|
49
50
|
const arch = undefined as SupportedArch | undefined;
|
|
50
51
|
const installMethod = argumentValues["install-method"] as InstallMethod | undefined;
|
|
51
52
|
|
|
53
|
+
await printerService.showSpinner(`Looking for version newer than ${currentVersion}`);
|
|
54
|
+
|
|
52
55
|
const checkResult =
|
|
53
56
|
os === undefined && installMethod === undefined
|
|
54
57
|
? await this.#upgradeService.getUpgradeCheckResult(true)
|
|
55
58
|
: await this.#upgradeService.checkForUpgrade(os, arch, installMethod);
|
|
59
|
+
|
|
60
|
+
await printerService.hideSpinner();
|
|
56
61
|
if (checkResult.status === "unsupported") {
|
|
57
62
|
await printerService.error(
|
|
58
63
|
`No upgrade location is configured for the detected or requested platform.\n`,
|
|
@@ -77,7 +82,8 @@ export class UpgradeSubCommand implements SubCommand {
|
|
|
77
82
|
|
|
78
83
|
if (!checkResult.updateAvailable) {
|
|
79
84
|
await printerService.print(
|
|
80
|
-
`${cliName} is already up to date
|
|
85
|
+
`${cliName} is already up to date: ${checkResult.currentVersion}\n`,
|
|
86
|
+
Icon.INFORMATION,
|
|
81
87
|
);
|
|
82
88
|
return;
|
|
83
89
|
}
|