@rudderhq/cli 0.1.0-canary.18 → 0.1.0-canary.19
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.js +230 -50
- package/dist/index.js.map +4 -4
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -10033,12 +10033,119 @@ import { constants as fsConstants, createWriteStream, mkdirSync as mkdirSync2, r
|
|
|
10033
10033
|
import { access, chmod, copyFile, cp, mkdtemp, mkdir, readFile as readFile3, readdir as readdir2, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
10034
10034
|
import { homedir, tmpdir } from "node:os";
|
|
10035
10035
|
import path10 from "node:path";
|
|
10036
|
-
import { Readable } from "node:stream";
|
|
10036
|
+
import { Readable, Transform } from "node:stream";
|
|
10037
10037
|
import { pipeline } from "node:stream/promises";
|
|
10038
10038
|
import { setTimeout as delay } from "node:timers/promises";
|
|
10039
10039
|
import * as p13 from "@clack/prompts";
|
|
10040
10040
|
import pc8 from "picocolors";
|
|
10041
10041
|
|
|
10042
|
+
// src/utils/progress.ts
|
|
10043
|
+
var BYTE_UNITS = ["B", "KB", "MB", "GB", "TB"];
|
|
10044
|
+
function formatBytes(bytes) {
|
|
10045
|
+
let value = Math.max(0, bytes);
|
|
10046
|
+
let unitIndex = 0;
|
|
10047
|
+
while (value >= 1024 && unitIndex < BYTE_UNITS.length - 1) {
|
|
10048
|
+
value /= 1024;
|
|
10049
|
+
unitIndex += 1;
|
|
10050
|
+
}
|
|
10051
|
+
if (unitIndex === 0) return `${Math.round(value)} ${BYTE_UNITS[unitIndex]}`;
|
|
10052
|
+
return `${value.toFixed(1)} ${BYTE_UNITS[unitIndex]}`;
|
|
10053
|
+
}
|
|
10054
|
+
function normalizeTotalBytes(totalBytes) {
|
|
10055
|
+
if (typeof totalBytes !== "number" || !Number.isFinite(totalBytes) || totalBytes <= 0) {
|
|
10056
|
+
return null;
|
|
10057
|
+
}
|
|
10058
|
+
return totalBytes;
|
|
10059
|
+
}
|
|
10060
|
+
function formatByteProgress(state) {
|
|
10061
|
+
const width = Math.max(4, state.width ?? 20);
|
|
10062
|
+
const receivedBytes = Math.max(0, state.receivedBytes);
|
|
10063
|
+
const totalBytes = normalizeTotalBytes(state.totalBytes);
|
|
10064
|
+
if (totalBytes === null) {
|
|
10065
|
+
return `[downloaded ${formatBytes(receivedBytes)}]`;
|
|
10066
|
+
}
|
|
10067
|
+
const ratio = Math.max(0, Math.min(1, receivedBytes / totalBytes));
|
|
10068
|
+
const filled = Math.round(ratio * width);
|
|
10069
|
+
const percent = Math.floor(ratio * 100);
|
|
10070
|
+
return `[${"#".repeat(filled)}${"-".repeat(width - filled)}] ${percent}% ${formatBytes(receivedBytes)}/${formatBytes(totalBytes)}`;
|
|
10071
|
+
}
|
|
10072
|
+
function progressSummary(receivedBytes, totalBytes) {
|
|
10073
|
+
const total = normalizeTotalBytes(totalBytes);
|
|
10074
|
+
if (total === null) return formatBytes(receivedBytes);
|
|
10075
|
+
return `${formatBytes(receivedBytes)}/${formatBytes(total)}`;
|
|
10076
|
+
}
|
|
10077
|
+
function createByteProgress(label, options = {}) {
|
|
10078
|
+
const stream = options.stream ?? process.stdout;
|
|
10079
|
+
const isTty = options.isTty ?? Boolean(stream.isTTY);
|
|
10080
|
+
const width = options.width ?? 20;
|
|
10081
|
+
const minIntervalMs = options.minIntervalMs ?? 80;
|
|
10082
|
+
const now = options.now ?? (() => Date.now());
|
|
10083
|
+
let started = false;
|
|
10084
|
+
let finished = false;
|
|
10085
|
+
let lastRenderAt = 0;
|
|
10086
|
+
let lastLineLength = 0;
|
|
10087
|
+
let latestReceivedBytes = 0;
|
|
10088
|
+
let latestTotalBytes = null;
|
|
10089
|
+
function render(receivedBytes, totalBytes, force = false) {
|
|
10090
|
+
if (finished) return;
|
|
10091
|
+
latestReceivedBytes = receivedBytes;
|
|
10092
|
+
latestTotalBytes = totalBytes;
|
|
10093
|
+
if (!isTty) return;
|
|
10094
|
+
const currentTime = now();
|
|
10095
|
+
const total = normalizeTotalBytes(totalBytes);
|
|
10096
|
+
const complete = total !== null && receivedBytes >= total;
|
|
10097
|
+
if (!force && currentTime - lastRenderAt < minIntervalMs && !complete) return;
|
|
10098
|
+
const line = `${label} ${formatByteProgress({ receivedBytes, totalBytes, width })}`;
|
|
10099
|
+
const padding = lastLineLength > line.length ? " ".repeat(lastLineLength - line.length) : "";
|
|
10100
|
+
stream.write(`\r${line}${padding}`);
|
|
10101
|
+
lastLineLength = line.length;
|
|
10102
|
+
lastRenderAt = currentTime;
|
|
10103
|
+
}
|
|
10104
|
+
function start(totalBytes) {
|
|
10105
|
+
if (started || finished) return;
|
|
10106
|
+
started = true;
|
|
10107
|
+
latestTotalBytes = totalBytes;
|
|
10108
|
+
if (isTty) {
|
|
10109
|
+
render(0, totalBytes, true);
|
|
10110
|
+
} else {
|
|
10111
|
+
stream.write(`${label}...
|
|
10112
|
+
`);
|
|
10113
|
+
}
|
|
10114
|
+
}
|
|
10115
|
+
function update(receivedBytes, totalBytes) {
|
|
10116
|
+
if (!started) start(totalBytes);
|
|
10117
|
+
render(receivedBytes, totalBytes, false);
|
|
10118
|
+
}
|
|
10119
|
+
function finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes) {
|
|
10120
|
+
if (finished) return;
|
|
10121
|
+
if (!started) start(totalBytes);
|
|
10122
|
+
if (isTty) {
|
|
10123
|
+
render(receivedBytes, totalBytes, true);
|
|
10124
|
+
stream.write("\n");
|
|
10125
|
+
} else {
|
|
10126
|
+
stream.write(`${label} complete (${progressSummary(receivedBytes, totalBytes)}).
|
|
10127
|
+
`);
|
|
10128
|
+
}
|
|
10129
|
+
finished = true;
|
|
10130
|
+
}
|
|
10131
|
+
function fail() {
|
|
10132
|
+
if (finished) return;
|
|
10133
|
+
if (isTty && started) {
|
|
10134
|
+
stream.write("\n");
|
|
10135
|
+
} else if (!isTty && started) {
|
|
10136
|
+
stream.write(`${label} failed.
|
|
10137
|
+
`);
|
|
10138
|
+
}
|
|
10139
|
+
finished = true;
|
|
10140
|
+
}
|
|
10141
|
+
return {
|
|
10142
|
+
start,
|
|
10143
|
+
update,
|
|
10144
|
+
finish,
|
|
10145
|
+
fail
|
|
10146
|
+
};
|
|
10147
|
+
}
|
|
10148
|
+
|
|
10042
10149
|
// src/version.ts
|
|
10043
10150
|
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
10044
10151
|
import path9 from "node:path";
|
|
@@ -10263,7 +10370,13 @@ function buildGithubReleaseAsset(repo, tag, assetName) {
|
|
|
10263
10370
|
browser_download_url: buildGithubReleaseAssetDownloadUrl(repo, tag, assetName)
|
|
10264
10371
|
};
|
|
10265
10372
|
}
|
|
10266
|
-
|
|
10373
|
+
function contentLengthFromHeaders(headers) {
|
|
10374
|
+
const raw = headers.get("content-length");
|
|
10375
|
+
if (!raw) return null;
|
|
10376
|
+
const value = Number(raw);
|
|
10377
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
10378
|
+
}
|
|
10379
|
+
async function downloadAsset(asset, outputDir, progressFactory = createByteProgress) {
|
|
10267
10380
|
mkdirSync2(outputDir, { recursive: true });
|
|
10268
10381
|
const outputPath = path10.join(outputDir, path10.basename(asset.name));
|
|
10269
10382
|
const response = await fetch(asset.browser_download_url, {
|
|
@@ -10272,7 +10385,24 @@ async function downloadAsset(asset, outputDir) {
|
|
|
10272
10385
|
if (!response.ok || !response.body) {
|
|
10273
10386
|
throw new Error(`Failed to download ${asset.name} from ${asset.browser_download_url} (${response.status}).`);
|
|
10274
10387
|
}
|
|
10275
|
-
|
|
10388
|
+
const totalBytes = contentLengthFromHeaders(response.headers);
|
|
10389
|
+
const progress = progressFactory(`Downloading ${asset.name}`);
|
|
10390
|
+
let receivedBytes = 0;
|
|
10391
|
+
const monitor = new Transform({
|
|
10392
|
+
transform(chunk, _encoding, callback) {
|
|
10393
|
+
receivedBytes += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
|
|
10394
|
+
progress.update(receivedBytes, totalBytes);
|
|
10395
|
+
callback(null, chunk);
|
|
10396
|
+
}
|
|
10397
|
+
});
|
|
10398
|
+
progress.start(totalBytes);
|
|
10399
|
+
try {
|
|
10400
|
+
await pipeline(Readable.fromWeb(response.body), monitor, createWriteStream(outputPath));
|
|
10401
|
+
progress.finish(receivedBytes, totalBytes);
|
|
10402
|
+
} catch (error) {
|
|
10403
|
+
progress.fail();
|
|
10404
|
+
throw error;
|
|
10405
|
+
}
|
|
10276
10406
|
return outputPath;
|
|
10277
10407
|
}
|
|
10278
10408
|
function checksumForFile(filePath) {
|
|
@@ -10303,11 +10433,11 @@ function assertChecksumMatch(filePath, expected) {
|
|
|
10303
10433
|
}
|
|
10304
10434
|
return actual;
|
|
10305
10435
|
}
|
|
10306
|
-
async function downloadChecksums(checksumAsset, outputDir) {
|
|
10436
|
+
async function downloadChecksums(checksumAsset, outputDir, progressFactory = createByteProgress) {
|
|
10307
10437
|
if (!checksumAsset) {
|
|
10308
10438
|
throw new Error("Desktop release is missing SHASUMS256.txt.");
|
|
10309
10439
|
}
|
|
10310
|
-
const checksumPath = await downloadAsset(checksumAsset, outputDir);
|
|
10440
|
+
const checksumPath = await downloadAsset(checksumAsset, outputDir, progressFactory);
|
|
10311
10441
|
return parseChecksumFile(readFileSync2(checksumPath, "utf8"));
|
|
10312
10442
|
}
|
|
10313
10443
|
async function pathExists(targetPath) {
|
|
@@ -10571,6 +10701,18 @@ async function writeInstallMetadata(paths, releaseTag, assetName, assetChecksum)
|
|
|
10571
10701
|
await writeFile2(paths.metadataPath, `${JSON.stringify(metadata, null, 2)}
|
|
10572
10702
|
`, "utf8");
|
|
10573
10703
|
}
|
|
10704
|
+
async function runStartPhase(message, successMessage, task) {
|
|
10705
|
+
const spinner5 = p13.spinner();
|
|
10706
|
+
spinner5.start(message);
|
|
10707
|
+
try {
|
|
10708
|
+
const result = await task();
|
|
10709
|
+
spinner5.stop(successMessage);
|
|
10710
|
+
return result;
|
|
10711
|
+
} catch (error) {
|
|
10712
|
+
spinner5.stop(pc8.red(`${message} failed.`));
|
|
10713
|
+
throw error;
|
|
10714
|
+
}
|
|
10715
|
+
}
|
|
10574
10716
|
async function startCommand(opts) {
|
|
10575
10717
|
const installCli = opts.cli !== false;
|
|
10576
10718
|
const installDesktop = opts.desktop !== false;
|
|
@@ -10596,12 +10738,21 @@ async function startCommand(opts) {
|
|
|
10596
10738
|
p13.log.message(`[dry-run] ${command}`);
|
|
10597
10739
|
} else {
|
|
10598
10740
|
p13.log.message(pc8.dim(`Running: ${command}`));
|
|
10599
|
-
const
|
|
10741
|
+
const spinner5 = p13.spinner();
|
|
10742
|
+
spinner5.start("Installing persistent CLI...");
|
|
10743
|
+
let result;
|
|
10744
|
+
try {
|
|
10745
|
+
result = installPersistentCli({ installSpec });
|
|
10746
|
+
} catch (error) {
|
|
10747
|
+
spinner5.stop(pc8.red("Persistent CLI installation failed."));
|
|
10748
|
+
throw error;
|
|
10749
|
+
}
|
|
10600
10750
|
if (!result.ok) {
|
|
10751
|
+
spinner5.stop(pc8.red("Persistent CLI installation failed."));
|
|
10601
10752
|
if (result.output) p13.log.message(pc8.dim(result.output));
|
|
10602
10753
|
throw new Error(`Persistent CLI installation failed. Re-run manually: ${result.command}`);
|
|
10603
10754
|
}
|
|
10604
|
-
|
|
10755
|
+
spinner5.stop(`${pc8.cyan("rudder")} CLI installed.`);
|
|
10605
10756
|
}
|
|
10606
10757
|
}
|
|
10607
10758
|
if (installDesktop) {
|
|
@@ -10620,7 +10771,12 @@ async function startCommand(opts) {
|
|
|
10620
10771
|
return;
|
|
10621
10772
|
}
|
|
10622
10773
|
const directReleaseVersion = resolveDesktopReleaseVersion(tag);
|
|
10623
|
-
const
|
|
10774
|
+
const progressFactory = createByteProgress;
|
|
10775
|
+
const release = directReleaseVersion ? null : await runStartPhase(
|
|
10776
|
+
"Resolving Desktop release...",
|
|
10777
|
+
"Desktop release resolved.",
|
|
10778
|
+
() => fetchGithubRelease(repo, tag)
|
|
10779
|
+
);
|
|
10624
10780
|
const releaseTag = directReleaseVersion ? tag : release?.tag_name;
|
|
10625
10781
|
if (!releaseTag) {
|
|
10626
10782
|
throw new Error(`Unable to resolve Rudder Desktop release tag for ${repo}@${tag}.`);
|
|
@@ -10630,28 +10786,52 @@ async function startCommand(opts) {
|
|
|
10630
10786
|
throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
|
|
10631
10787
|
}
|
|
10632
10788
|
const checksumAsset = directReleaseVersion ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME) : selectChecksumAsset(release?.assets ?? []);
|
|
10633
|
-
const checksums = await downloadChecksums(checksumAsset, outputDir);
|
|
10789
|
+
const checksums = await downloadChecksums(checksumAsset, outputDir, progressFactory);
|
|
10634
10790
|
const expectedChecksum = resolveAssetChecksum(checksums, asset.name);
|
|
10635
10791
|
const metadata = await readInstallMetadata(installPaths.metadataPath);
|
|
10636
10792
|
if (isInstalledDesktopCurrent(metadata, releaseTag, asset.name, expectedChecksum) && await pathExists(installPaths.executablePath)) {
|
|
10637
10793
|
p13.log.success(`Rudder Desktop is already installed at ${pc8.cyan(installPaths.appPath)}.`);
|
|
10638
|
-
await
|
|
10639
|
-
|
|
10794
|
+
await runStartPhase(
|
|
10795
|
+
"Refreshing Desktop launchers...",
|
|
10796
|
+
"Desktop launchers ready.",
|
|
10797
|
+
async () => {
|
|
10798
|
+
await removeMacQuarantine(installPaths, target);
|
|
10799
|
+
await createPlatformLaunchers(installPaths, target);
|
|
10800
|
+
}
|
|
10801
|
+
);
|
|
10640
10802
|
} else {
|
|
10641
|
-
const installerPath = await downloadAsset(asset, outputDir);
|
|
10642
|
-
const checksum =
|
|
10643
|
-
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
await
|
|
10648
|
-
|
|
10803
|
+
const installerPath = await downloadAsset(asset, outputDir, progressFactory);
|
|
10804
|
+
const checksum = await runStartPhase(
|
|
10805
|
+
"Verifying Desktop checksum...",
|
|
10806
|
+
`Verified ${pc8.cyan(path10.basename(installerPath))}.`,
|
|
10807
|
+
() => assertChecksumMatch(installerPath, expectedChecksum)
|
|
10808
|
+
);
|
|
10809
|
+
await runStartPhase(
|
|
10810
|
+
"Replacing existing Rudder Desktop if needed...",
|
|
10811
|
+
"Existing Desktop install is ready for replacement.",
|
|
10812
|
+
() => prepareForDesktopReplace(installPaths, target)
|
|
10813
|
+
);
|
|
10814
|
+
await runStartPhase(
|
|
10815
|
+
"Installing portable Desktop app...",
|
|
10816
|
+
`Installed Rudder Desktop to ${pc8.cyan(installPaths.appPath)}.`,
|
|
10817
|
+
() => installPortableDesktop(installerPath, installPaths, target)
|
|
10818
|
+
);
|
|
10819
|
+
await runStartPhase(
|
|
10820
|
+
"Preparing Desktop launchers...",
|
|
10821
|
+
"Desktop launchers ready.",
|
|
10822
|
+
async () => {
|
|
10823
|
+
await removeMacQuarantine(installPaths, target);
|
|
10824
|
+
await createPlatformLaunchers(installPaths, target);
|
|
10825
|
+
}
|
|
10826
|
+
);
|
|
10649
10827
|
await writeInstallMetadata(installPaths, releaseTag, asset.name, checksum);
|
|
10650
|
-
p13.log.success(`Installed Rudder Desktop to ${pc8.cyan(installPaths.appPath)}.`);
|
|
10651
10828
|
}
|
|
10652
10829
|
if (opts.open !== false) {
|
|
10653
|
-
|
|
10654
|
-
|
|
10830
|
+
await runStartPhase(
|
|
10831
|
+
"Launching Rudder Desktop...",
|
|
10832
|
+
"Rudder Desktop launched.",
|
|
10833
|
+
() => launchDesktop(installPaths, target)
|
|
10834
|
+
);
|
|
10655
10835
|
}
|
|
10656
10836
|
}
|
|
10657
10837
|
p13.outro(pc8.green("Rudder start complete."));
|
|
@@ -12657,8 +12837,8 @@ async function dbBackupCommand(opts) {
|
|
|
12657
12837
|
p15.log.message(pc20.dim(`Connection source: ${connection.source}`));
|
|
12658
12838
|
p15.log.message(pc20.dim(`Backup dir: ${backupDir}`));
|
|
12659
12839
|
p15.log.message(pc20.dim(`Retention: ${retentionDays} day(s)`));
|
|
12660
|
-
const
|
|
12661
|
-
|
|
12840
|
+
const spinner5 = p15.spinner();
|
|
12841
|
+
spinner5.start("Creating database backup...");
|
|
12662
12842
|
try {
|
|
12663
12843
|
const result = await runDatabaseBackup({
|
|
12664
12844
|
connectionString: connection.value,
|
|
@@ -12666,7 +12846,7 @@ async function dbBackupCommand(opts) {
|
|
|
12666
12846
|
retentionDays,
|
|
12667
12847
|
filenamePrefix
|
|
12668
12848
|
});
|
|
12669
|
-
|
|
12849
|
+
spinner5.stop(`Backup saved: ${formatDatabaseBackupResult(result)}`);
|
|
12670
12850
|
if (opts.json) {
|
|
12671
12851
|
console.log(
|
|
12672
12852
|
JSON.stringify(
|
|
@@ -12685,7 +12865,7 @@ async function dbBackupCommand(opts) {
|
|
|
12685
12865
|
}
|
|
12686
12866
|
p15.outro(pc20.green("Backup completed."));
|
|
12687
12867
|
} catch (err) {
|
|
12688
|
-
|
|
12868
|
+
spinner5.stop(pc20.red("Backup failed."));
|
|
12689
12869
|
throw err;
|
|
12690
12870
|
}
|
|
12691
12871
|
}
|
|
@@ -16925,8 +17105,8 @@ async function runWorktreeInit(opts) {
|
|
|
16925
17105
|
`Cannot seed worktree database because source config was not found at ${sourceConfigPath}. Use --no-seed or provide --from-config.`
|
|
16926
17106
|
);
|
|
16927
17107
|
}
|
|
16928
|
-
const
|
|
16929
|
-
|
|
17108
|
+
const spinner5 = p17.spinner();
|
|
17109
|
+
spinner5.start(`Seeding isolated worktree database from source instance (${seedMode})...`);
|
|
16930
17110
|
try {
|
|
16931
17111
|
const seeded = await seedWorktreeDatabase({
|
|
16932
17112
|
sourceConfigPath,
|
|
@@ -16938,9 +17118,9 @@ async function runWorktreeInit(opts) {
|
|
|
16938
17118
|
});
|
|
16939
17119
|
seedSummary = seeded.backupSummary;
|
|
16940
17120
|
reboundWorkspaceSummary = seeded.reboundWorkspaces;
|
|
16941
|
-
|
|
17121
|
+
spinner5.stop(`Seeded isolated worktree database (${seedMode}).`);
|
|
16942
17122
|
} catch (error) {
|
|
16943
|
-
|
|
17123
|
+
spinner5.stop(pc23.red("Failed to seed worktree database."));
|
|
16944
17124
|
throw error;
|
|
16945
17125
|
}
|
|
16946
17126
|
}
|
|
@@ -17006,16 +17186,16 @@ async function worktreeMakeCommand(nameArg, opts) {
|
|
|
17006
17186
|
branchExists: !startPoint && localBranchExists(sourceCwd, name),
|
|
17007
17187
|
startPoint
|
|
17008
17188
|
});
|
|
17009
|
-
const
|
|
17010
|
-
|
|
17189
|
+
const spinner5 = p17.spinner();
|
|
17190
|
+
spinner5.start(`Creating git worktree at ${targetPath}...`);
|
|
17011
17191
|
try {
|
|
17012
17192
|
execFileSync2("git", worktreeArgs, {
|
|
17013
17193
|
cwd: sourceCwd,
|
|
17014
17194
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17015
17195
|
});
|
|
17016
|
-
|
|
17196
|
+
spinner5.stop(`Created git worktree at ${targetPath}.`);
|
|
17017
17197
|
} catch (error) {
|
|
17018
|
-
|
|
17198
|
+
spinner5.stop(pc23.red("Failed to create git worktree."));
|
|
17019
17199
|
throw new Error(extractExecSyncErrorMessage(error) ?? String(error));
|
|
17020
17200
|
}
|
|
17021
17201
|
const installSpinner = p17.spinner();
|
|
@@ -17183,9 +17363,9 @@ async function worktreeCleanupCommand(nameArg, opts) {
|
|
|
17183
17363
|
}
|
|
17184
17364
|
if (linkedWorktree) {
|
|
17185
17365
|
const worktreeDirExists = existsSync3(linkedWorktree.worktree);
|
|
17186
|
-
const
|
|
17366
|
+
const spinner5 = p17.spinner();
|
|
17187
17367
|
if (worktreeDirExists) {
|
|
17188
|
-
|
|
17368
|
+
spinner5.start(`Removing git worktree at ${linkedWorktree.worktree}...`);
|
|
17189
17369
|
try {
|
|
17190
17370
|
const removeArgs = ["worktree", "remove", linkedWorktree.worktree];
|
|
17191
17371
|
if (opts.force) removeArgs.push("--force");
|
|
@@ -17193,18 +17373,18 @@ async function worktreeCleanupCommand(nameArg, opts) {
|
|
|
17193
17373
|
cwd: sourceCwd,
|
|
17194
17374
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17195
17375
|
});
|
|
17196
|
-
|
|
17376
|
+
spinner5.stop(`Removed git worktree at ${linkedWorktree.worktree}.`);
|
|
17197
17377
|
} catch (error) {
|
|
17198
|
-
|
|
17378
|
+
spinner5.stop(pc23.yellow(`Could not remove worktree cleanly, will prune instead.`));
|
|
17199
17379
|
p17.log.warning(extractExecSyncErrorMessage(error) ?? String(error));
|
|
17200
17380
|
}
|
|
17201
17381
|
} else {
|
|
17202
|
-
|
|
17382
|
+
spinner5.start("Pruning stale worktree entry...");
|
|
17203
17383
|
execFileSync2("git", ["worktree", "prune"], {
|
|
17204
17384
|
cwd: sourceCwd,
|
|
17205
17385
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17206
17386
|
});
|
|
17207
|
-
|
|
17387
|
+
spinner5.stop("Pruned stale worktree entry.");
|
|
17208
17388
|
}
|
|
17209
17389
|
} else {
|
|
17210
17390
|
execFileSync2("git", ["worktree", "prune"], {
|
|
@@ -17213,31 +17393,31 @@ async function worktreeCleanupCommand(nameArg, opts) {
|
|
|
17213
17393
|
});
|
|
17214
17394
|
}
|
|
17215
17395
|
if (existsSync3(targetPath)) {
|
|
17216
|
-
const
|
|
17217
|
-
|
|
17396
|
+
const spinner5 = p17.spinner();
|
|
17397
|
+
spinner5.start(`Removing worktree directory ${targetPath}...`);
|
|
17218
17398
|
rmSync(targetPath, { recursive: true, force: true });
|
|
17219
|
-
|
|
17399
|
+
spinner5.stop(`Removed worktree directory ${targetPath}.`);
|
|
17220
17400
|
}
|
|
17221
17401
|
if (localBranchExists(sourceCwd, name)) {
|
|
17222
|
-
const
|
|
17223
|
-
|
|
17402
|
+
const spinner5 = p17.spinner();
|
|
17403
|
+
spinner5.start(`Deleting local branch "${name}"...`);
|
|
17224
17404
|
try {
|
|
17225
17405
|
const deleteFlag = opts.force ? "-D" : "-d";
|
|
17226
17406
|
execFileSync2("git", ["branch", deleteFlag, name], {
|
|
17227
17407
|
cwd: sourceCwd,
|
|
17228
17408
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17229
17409
|
});
|
|
17230
|
-
|
|
17410
|
+
spinner5.stop(`Deleted local branch "${name}".`);
|
|
17231
17411
|
} catch (error) {
|
|
17232
|
-
|
|
17412
|
+
spinner5.stop(pc23.yellow(`Could not delete branch "${name}".`));
|
|
17233
17413
|
p17.log.warning(extractExecSyncErrorMessage(error) ?? String(error));
|
|
17234
17414
|
}
|
|
17235
17415
|
}
|
|
17236
17416
|
if (existsSync3(instanceRoot)) {
|
|
17237
|
-
const
|
|
17238
|
-
|
|
17417
|
+
const spinner5 = p17.spinner();
|
|
17418
|
+
spinner5.start(`Removing instance data at ${instanceRoot}...`);
|
|
17239
17419
|
rmSync(instanceRoot, { recursive: true, force: true });
|
|
17240
|
-
|
|
17420
|
+
spinner5.stop(`Removed instance data at ${instanceRoot}.`);
|
|
17241
17421
|
}
|
|
17242
17422
|
p17.outro(pc23.green("Cleanup complete."));
|
|
17243
17423
|
}
|