@tdk-landscape/tdk-cli-core 1.3.153 → 1.3.155
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/cli/dist/commands/completion.js +2 -0
- package/cli/dist/commands/help.js +2 -1
- package/cli/dist/commands/ui.js +7 -5
- package/cli/dist/commands/upgrade.js +188 -12
- package/cli/dist/utils/which.js +29 -0
- package/cli/dist-bundle/chunk-XTSHWDDE.js +322 -0
- package/cli/dist-bundle/cli.js +271 -260
- package/cli/dist-bundle/{cold-preflight-PJM2A7ZF.js → cold-preflight-3RDK76RY.js} +1 -1
- package/cli/package.json +1 -1
- package/engine/topologies/platform/docker/compose/traefik_standalone.star +9 -3
- package/package.json +1 -1
- package/cli/dist-bundle/chunk-WD6JF6WR.js +0 -322
|
@@ -122,6 +122,7 @@ _tdk() {
|
|
|
122
122
|
upgrade)
|
|
123
123
|
_arguments
|
|
124
124
|
'--force[Force upgrade even if on latest]'
|
|
125
|
+
'--all[Upgrade every TDK installation found on PATH]'
|
|
125
126
|
'--dry-run[Show what would be upgraded]'
|
|
126
127
|
;;
|
|
127
128
|
esac
|
|
@@ -242,6 +243,7 @@ complete -c tdk -n '__fish_seen_subcommand_from runtime' -l json -d 'Print the c
|
|
|
242
243
|
|
|
243
244
|
# upgrade command options
|
|
244
245
|
complete -c tdk -n '__fish_seen_subcommand_from upgrade' -l force -d 'Force upgrade even if on latest'
|
|
246
|
+
complete -c tdk -n '__fish_seen_subcommand_from upgrade' -l all -d 'Upgrade every TDK installation found on PATH'
|
|
245
247
|
complete -c tdk -n '__fish_seen_subcommand_from upgrade' -l dry-run -d 'Show what would be upgraded'
|
|
246
248
|
`;
|
|
247
249
|
const POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName tdk -ScriptBlock {
|
|
@@ -83,7 +83,7 @@ const COMMAND_GROUPS = [
|
|
|
83
83
|
alias: "--check-assets",
|
|
84
84
|
},
|
|
85
85
|
{ name: "completion", desc: "Generate shell completions", alias: "--install --shell zsh" },
|
|
86
|
-
{ name: "upgrade, update", desc: "Self-update to latest version", alias: "--force" },
|
|
86
|
+
{ name: "upgrade, update", desc: "Self-update to latest version", alias: "--force --all" },
|
|
87
87
|
{ name: "version, -v", desc: "Display version number", alias: "" },
|
|
88
88
|
{ name: "help", desc: "Show help", alias: "[command]" },
|
|
89
89
|
],
|
|
@@ -136,6 +136,7 @@ export function showHelp() {
|
|
|
136
136
|
${chalk.cyan("$")} tdk networks # Show Traefik-routed URLs
|
|
137
137
|
${chalk.cyan("$")} tdk doctor # Check your environment
|
|
138
138
|
${chalk.cyan("$")} tdk upgrade # Self-update
|
|
139
|
+
${chalk.cyan("$")} tdk upgrade --all # Update all TDK installs on PATH
|
|
139
140
|
`));
|
|
140
141
|
console.log(chalk.gray(` ${"═".repeat(50)}`));
|
|
141
142
|
console.log(chalk.gray(` For more help: ${chalk.cyan("tdk help [command]")}`));
|
package/cli/dist/commands/ui.js
CHANGED
|
@@ -348,11 +348,13 @@ export const TUIApp = ({ animated = true }) => {
|
|
|
348
348
|
// Parse SGR 1006 mouse protocol: ESC[<btn;x;yM or ESC[<btn;x;ym
|
|
349
349
|
// biome-ignore lint/suspicious/noControlCharactersInRegex: \\x1b ESC is intentional (ANSI SGR/CSI sequence parsing)
|
|
350
350
|
const sgrMatch = str.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
const
|
|
351
|
+
const btnText = sgrMatch?.[1];
|
|
352
|
+
const yText = sgrMatch?.[3];
|
|
353
|
+
const action = sgrMatch?.[4];
|
|
354
|
+
if (btnText !== undefined && yText !== undefined && action !== undefined) {
|
|
355
|
+
const btn = parseInt(btnText, 10);
|
|
356
|
+
const y = parseInt(yText, 10);
|
|
357
|
+
const release = action === "m";
|
|
356
358
|
// Check if it's a left click (btn & 0b11 == 0 means left button)
|
|
357
359
|
const isLeftClick = (btn & 0b11) === 0;
|
|
358
360
|
if (isLeftClick && !release) {
|
|
@@ -15,7 +15,7 @@ import { binaryAssetName, executableName, isWindows } from "../utils/platform.js
|
|
|
15
15
|
import { promptConfirm } from "../utils/prompt.js";
|
|
16
16
|
import { startSpinner } from "../utils/spinner.js";
|
|
17
17
|
import { extractTarball } from "../utils/tar.js";
|
|
18
|
-
import { findOnPath } from "../utils/which.js";
|
|
18
|
+
import { findAllOnPath, findOnPath } from "../utils/which.js";
|
|
19
19
|
function isStandaloneBinary(tdkPath) {
|
|
20
20
|
if (isWindows() && tdkPath.toLowerCase().endsWith(".exe"))
|
|
21
21
|
return true;
|
|
@@ -88,6 +88,45 @@ function detectInstallation() {
|
|
|
88
88
|
return { method: "unknown" };
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
function detectInstallationForPath(tdkPath) {
|
|
92
|
+
try {
|
|
93
|
+
const realPath = realpathSync(tdkPath);
|
|
94
|
+
if (realPath.includes("tdk-cli")) {
|
|
95
|
+
const possibleGitRoot = resolve(realPath, "..", "..", "..");
|
|
96
|
+
if (existsSync(join(possibleGitRoot, ".git"))) {
|
|
97
|
+
return { method: "git", path: possibleGitRoot };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (tdkPath.includes("node_modules") || tdkPath.includes(".npm") || tdkPath.includes(".bun")) {
|
|
101
|
+
return { method: tdkPath.includes(".bun") ? "bun" : "npm", path: tdkPath };
|
|
102
|
+
}
|
|
103
|
+
if (isStandaloneBinary(realPath))
|
|
104
|
+
return { method: "binary", path: realPath };
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
logVerbose(`Installation detection failed for ${tdkPath}`, err);
|
|
108
|
+
}
|
|
109
|
+
return { method: "unknown", path: tdkPath };
|
|
110
|
+
}
|
|
111
|
+
function detectAllInstallations() {
|
|
112
|
+
const candidates = findAllOnPath(executableName()).map(detectInstallationForPath);
|
|
113
|
+
const current = detectInstallation();
|
|
114
|
+
if (current.method !== "unknown")
|
|
115
|
+
candidates.unshift(current);
|
|
116
|
+
const unique = new Map();
|
|
117
|
+
for (const install of candidates) {
|
|
118
|
+
if (install.method === "unknown" || !install.path)
|
|
119
|
+
continue;
|
|
120
|
+
let key = install.path;
|
|
121
|
+
try {
|
|
122
|
+
if (install.method === "binary")
|
|
123
|
+
key = realpathSync(install.path);
|
|
124
|
+
}
|
|
125
|
+
catch { }
|
|
126
|
+
unique.set(`${install.method}:${key}`, install);
|
|
127
|
+
}
|
|
128
|
+
return [...unique.values()];
|
|
129
|
+
}
|
|
91
130
|
const BINARY_RELEASE_REPO = "tdk-landscape/tdk-cli-releases";
|
|
92
131
|
const ENGINE_ASSET_NAME = "tdk-cli-engine.tar.gz";
|
|
93
132
|
const CHECKSUMS_ASSET_NAME = "checksums.txt";
|
|
@@ -355,8 +394,75 @@ export async function upgradeViaBun() {
|
|
|
355
394
|
return false;
|
|
356
395
|
}
|
|
357
396
|
}
|
|
397
|
+
async function upgradeAllInstallations(dryRun) {
|
|
398
|
+
const installations = detectAllInstallations();
|
|
399
|
+
if (!installations.length) {
|
|
400
|
+
console.error(chalk.red("Could not find any TDK installations on PATH."));
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
console.log(chalk.blue(`Found ${installations.length} TDK installation${installations.length === 1 ? "" : "s"}:`));
|
|
404
|
+
for (const install of installations) {
|
|
405
|
+
console.log(chalk.gray(` ${install.method}: ${install.path}`));
|
|
406
|
+
}
|
|
407
|
+
if (dryRun) {
|
|
408
|
+
console.log(chalk.yellow("\nDry run: no installations were changed."));
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
const binaryInstallations = installations.filter((install) => install.method === "binary" && install.path);
|
|
412
|
+
const release = binaryInstallations.length ? await getLatestBinaryRelease() : null;
|
|
413
|
+
if (binaryInstallations.length && !release) {
|
|
414
|
+
console.error(chalk.red("Could not find a compatible TDK binary release for this platform."));
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
let success = true;
|
|
418
|
+
const completed = new Set();
|
|
419
|
+
for (const install of installations) {
|
|
420
|
+
const key = install.method === "npm" || install.method === "bun"
|
|
421
|
+
? install.method
|
|
422
|
+
: `${install.method}:${install.path}`;
|
|
423
|
+
if (completed.has(key))
|
|
424
|
+
continue;
|
|
425
|
+
completed.add(key);
|
|
426
|
+
if (install.method === "git" && install.path) {
|
|
427
|
+
console.log(chalk.cyan(`\nUpdating git install at ${install.path}`));
|
|
428
|
+
success = (await upgradeViaGit(install.path)) && success;
|
|
429
|
+
}
|
|
430
|
+
else if (install.method === "binary" && install.path && release) {
|
|
431
|
+
const latest = release.tag.replace(/^v/, "").split("-")[0];
|
|
432
|
+
let current = "";
|
|
433
|
+
try {
|
|
434
|
+
current = execFileSync(install.path, ["version"], {
|
|
435
|
+
encoding: "utf-8",
|
|
436
|
+
timeout: 10_000,
|
|
437
|
+
}).trim();
|
|
438
|
+
}
|
|
439
|
+
catch { }
|
|
440
|
+
if (current === latest) {
|
|
441
|
+
console.log(chalk.green(`\n${install.path} is already current (${current}).`));
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
console.log(chalk.cyan(`\nUpdating ${install.path} (${current || "unknown"} → ${latest})`));
|
|
445
|
+
success = (await upgradeViaBinary(install.path, release)) && success;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else if (install.method === "npm") {
|
|
449
|
+
console.log(chalk.cyan("\nUpdating the npm installation..."));
|
|
450
|
+
success = (await upgradeViaNpm()) && success;
|
|
451
|
+
}
|
|
452
|
+
else if (install.method === "bun") {
|
|
453
|
+
console.log(chalk.cyan("\nUpdating the Bun installation..."));
|
|
454
|
+
success = (await upgradeViaBun()) && success;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (success)
|
|
458
|
+
console.log(chalk.green.bold("\nAll TDK installations on PATH are up to date."));
|
|
459
|
+
else
|
|
460
|
+
console.error(chalk.red("\nAt least one TDK installation could not be updated."));
|
|
461
|
+
return success;
|
|
462
|
+
}
|
|
358
463
|
async function upgradeViaGit(path) {
|
|
359
|
-
const spinner = startSpinner("
|
|
464
|
+
const spinner = startSpinner("Updating the git installation from the default branch...");
|
|
465
|
+
let rebaseInProgress = false;
|
|
360
466
|
try {
|
|
361
467
|
execFileSync("git", ["rev-parse", "--git-dir"], {
|
|
362
468
|
cwd: path,
|
|
@@ -368,16 +474,57 @@ async function upgradeViaGit(path) {
|
|
|
368
474
|
stdio: "pipe",
|
|
369
475
|
timeout: 30000,
|
|
370
476
|
});
|
|
371
|
-
const
|
|
477
|
+
const dirty = execFileSync("git", ["status", "--porcelain"], {
|
|
372
478
|
cwd: path,
|
|
373
479
|
encoding: "utf-8",
|
|
374
480
|
}).trim();
|
|
375
|
-
|
|
376
|
-
|
|
481
|
+
if (dirty) {
|
|
482
|
+
throw new Error("The TDK source checkout has local changes. Commit or stash them, then run `tdk upgrade` again.");
|
|
483
|
+
}
|
|
484
|
+
const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
377
485
|
cwd: path,
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
486
|
+
encoding: "utf-8",
|
|
487
|
+
}).trim();
|
|
488
|
+
let defaultRef = "";
|
|
489
|
+
try {
|
|
490
|
+
defaultRef = execFileSync("git", ["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"], {
|
|
491
|
+
cwd: path,
|
|
492
|
+
encoding: "utf-8",
|
|
493
|
+
stdio: "pipe",
|
|
494
|
+
}).trim();
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
for (const candidate of ["origin/main", "origin/master"]) {
|
|
498
|
+
try {
|
|
499
|
+
execFileSync("git", ["rev-parse", "--verify", candidate], { cwd: path, stdio: "pipe" });
|
|
500
|
+
defaultRef = candidate;
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
catch { }
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
if (!defaultRef?.startsWith("origin/")) {
|
|
507
|
+
throw new Error("Could not find the default branch for origin (expected origin/HEAD, origin/main, or origin/master).");
|
|
508
|
+
}
|
|
509
|
+
const defaultBranch = defaultRef.slice("origin/".length);
|
|
510
|
+
if (branch === defaultBranch) {
|
|
511
|
+
spinner.text = `Fast-forwarding ${branch} from origin/${defaultBranch}...`;
|
|
512
|
+
execFileSync("git", ["pull", "--ff-only", "origin", defaultBranch], {
|
|
513
|
+
cwd: path,
|
|
514
|
+
stdio: "pipe",
|
|
515
|
+
timeout: 30000,
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
spinner.text = `Rebasing ${branch} onto origin/${defaultBranch}...`;
|
|
520
|
+
rebaseInProgress = true;
|
|
521
|
+
execFileSync("git", ["rebase", defaultRef], {
|
|
522
|
+
cwd: path,
|
|
523
|
+
stdio: "pipe",
|
|
524
|
+
timeout: 60000,
|
|
525
|
+
});
|
|
526
|
+
rebaseInProgress = false;
|
|
527
|
+
}
|
|
381
528
|
if (existsSync(join(path, "cli", PACKAGE_JSON))) {
|
|
382
529
|
spinner.text = "Rebuilding CLI...";
|
|
383
530
|
execFileSync(findOnPath("bun") ?? "bun", ["install"], {
|
|
@@ -397,10 +544,16 @@ async function upgradeViaGit(path) {
|
|
|
397
544
|
stdio: "pipe",
|
|
398
545
|
timeout: 30000,
|
|
399
546
|
});
|
|
400
|
-
spinner.succeed(
|
|
547
|
+
spinner.succeed(`Upgraded successfully from origin/${defaultBranch}`);
|
|
401
548
|
return true;
|
|
402
549
|
}
|
|
403
550
|
catch (err) {
|
|
551
|
+
if (rebaseInProgress) {
|
|
552
|
+
try {
|
|
553
|
+
execFileSync("git", ["rebase", "--abort"], { cwd: path, stdio: "pipe" });
|
|
554
|
+
}
|
|
555
|
+
catch { }
|
|
556
|
+
}
|
|
404
557
|
spinner.fail(`Git upgrade failed: ${getErrorMessage(err)}`);
|
|
405
558
|
return false;
|
|
406
559
|
}
|
|
@@ -409,6 +562,7 @@ export const upgradeCommand = new Command("upgrade")
|
|
|
409
562
|
.alias("update")
|
|
410
563
|
.description("Upgrade TDK CLI to the latest version")
|
|
411
564
|
.option("-f, --force", "Force upgrade even if already on latest", false)
|
|
565
|
+
.option("--all", "Upgrade every TDK installation found on PATH", false)
|
|
412
566
|
.option("--dry-run", "Show what would be upgraded without actually doing it", false)
|
|
413
567
|
.option("-y, --yes", "Skip confirmation prompt", false)
|
|
414
568
|
.action(async (options) => {
|
|
@@ -418,6 +572,27 @@ export const upgradeCommand = new Command("upgrade")
|
|
|
418
572
|
const installInfo = detectInstallation();
|
|
419
573
|
console.log(chalk.gray(`Installation method: ${installInfo.method}`));
|
|
420
574
|
console.log();
|
|
575
|
+
if (options.all) {
|
|
576
|
+
const installations = detectAllInstallations();
|
|
577
|
+
if (!installations.length) {
|
|
578
|
+
console.error(chalk.red("Could not find any TDK installations on PATH."));
|
|
579
|
+
process.exit(1);
|
|
580
|
+
}
|
|
581
|
+
if (!options.dryRun && !options.yes) {
|
|
582
|
+
const confirm = await promptConfirm({
|
|
583
|
+
message: `Upgrade all ${installations.length} TDK installations on PATH?`,
|
|
584
|
+
initial: true,
|
|
585
|
+
});
|
|
586
|
+
if (!confirm) {
|
|
587
|
+
showCancelled();
|
|
588
|
+
process.exit(0);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
const success = await upgradeAllInstallations(options.dryRun);
|
|
592
|
+
if (!success)
|
|
593
|
+
process.exit(1);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
421
596
|
const windowsNpmMessage = windowsNpmUpgradeMessage(process.platform, installInfo);
|
|
422
597
|
if (windowsNpmMessage) {
|
|
423
598
|
console.log(windowsNpmMessage);
|
|
@@ -459,7 +634,7 @@ export const upgradeCommand = new Command("upgrade")
|
|
|
459
634
|
}
|
|
460
635
|
}
|
|
461
636
|
else if (installInfo.method === "git" && installInfo.path) {
|
|
462
|
-
console.log(chalk.blue("📦 Git installation detected - will
|
|
637
|
+
console.log(chalk.blue("📦 Git installation detected - will update from origin's default branch"));
|
|
463
638
|
try {
|
|
464
639
|
execFileSync("git", ["fetch", "origin"], { cwd: installInfo.path, stdio: "pipe" });
|
|
465
640
|
const localHash = execFileSync("git", ["rev-parse", "HEAD"], {
|
|
@@ -516,7 +691,7 @@ export const upgradeCommand = new Command("upgrade")
|
|
|
516
691
|
console.log(chalk.gray(` Path: ${installInfo.path}`));
|
|
517
692
|
}
|
|
518
693
|
if (installInfo.method === "git") {
|
|
519
|
-
console.log(chalk.gray(" Action:
|
|
694
|
+
console.log(chalk.gray(" Action: fetch origin, update from origin/HEAD, rebuild, and relink"));
|
|
520
695
|
}
|
|
521
696
|
else if (installInfo.method === "binary" && binaryRelease) {
|
|
522
697
|
console.log(chalk.gray(` Action: Download and replace with ${binaryRelease.downloadUrl}`));
|
|
@@ -565,7 +740,8 @@ export const upgradeCommand = new Command("upgrade")
|
|
|
565
740
|
if (!success) {
|
|
566
741
|
console.error(chalk.red("\nUpgrade failed"));
|
|
567
742
|
if (installInfo.method === "git") {
|
|
568
|
-
console.log(chalk.cyan(`
|
|
743
|
+
console.log(chalk.cyan(` Check local changes with: git -C ${installInfo.path} status --short`));
|
|
744
|
+
console.log(chalk.cyan(" Commit or stash them, then retry: tdk upgrade"));
|
|
569
745
|
}
|
|
570
746
|
else if (installInfo.method === "binary" && binaryRelease && installInfo.path) {
|
|
571
747
|
const engineDir = join(dirname(installInfo.path), "tdk-cli");
|
package/cli/dist/utils/which.js
CHANGED
|
@@ -25,3 +25,32 @@ export function findOnPath(command) {
|
|
|
25
25
|
}
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
|
+
export function findAllOnPath(command) {
|
|
29
|
+
const pathEnv = process.env.PATH ?? process.env.Path ?? "";
|
|
30
|
+
const windows = isWindows();
|
|
31
|
+
const names = pathLookups(command, windows);
|
|
32
|
+
if (windows && !extname(command)) {
|
|
33
|
+
for (const extension of (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";")) {
|
|
34
|
+
const suffix = extension.toLowerCase();
|
|
35
|
+
if (suffix && !names.includes(`${command}${suffix}`))
|
|
36
|
+
names.push(`${command}${suffix}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const found = [];
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
for (const dir of pathEnv.split(delimiter)) {
|
|
42
|
+
if (!dir)
|
|
43
|
+
continue;
|
|
44
|
+
for (const name of names) {
|
|
45
|
+
const candidate = join(dir, name);
|
|
46
|
+
if (!existsSync(candidate))
|
|
47
|
+
continue;
|
|
48
|
+
const key = windows ? candidate.toLowerCase() : candidate;
|
|
49
|
+
if (!seen.has(key)) {
|
|
50
|
+
seen.add(key);
|
|
51
|
+
found.push(candidate);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return found;
|
|
56
|
+
}
|