stim 1.10.0 → 1.11.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/{build-progress-BXx-ZBe4.mjs → activity-BtG4Va9l.mjs} +8 -182
- package/dist/{android-DPov-fv2.mjs → android-BA2i_KAV.mjs} +1 -1
- package/dist/{android-DBkeHwpm.mjs → android-C1q4l523.mjs} +376 -99
- package/dist/{android-787HhP5w.mjs → android-C4zG2Tuc.mjs} +63 -18
- package/dist/{android-cas-CITmIeWY.mjs → android-cas-DfJkwCXW.mjs} +3 -3
- package/dist/{app-install-CrJ6t_bv.mjs → app-install-DHut6JnV.mjs} +1 -1
- package/dist/{budget-BP4jZZL4.mjs → budget-De3P2rq_.mjs} +9 -9
- package/dist/{dev-client-92U593KT.mjs → build-plan-CeAYgKAx.mjs} +415 -24
- package/dist/build-progress-CDwogz6R.mjs +179 -0
- package/dist/cli.mjs +14 -14
- package/dist/collector-run.mjs +1 -1
- package/dist/{deps-DP4eWqea.mjs → deps-OF7CD5Dx.mjs} +2 -2
- package/dist/{device-DhTZe7L4.mjs → device-BwH2iI3O.mjs} +47 -9
- package/dist/{device-lease-CbEaIk7b.mjs → device-lease-D83nqeMX.mjs} +51 -51
- package/dist/{device-pool-Di8Q-9Ro.mjs → device-pool-DHj7cdPy.mjs} +2 -2
- package/dist/{device-remote-Dy1jGj3U.mjs → device-remote-BQZSnnmE.mjs} +7 -7
- package/dist/{doctor-B-inAJmt.mjs → doctor-D8QdMRMf.mjs} +12 -12
- package/dist/{error-diagnostics-xxWKNO3-.mjs → error-diagnostics-UYFSQwRy.mjs} +3 -3
- package/dist/{gc-ChPFZMRC.mjs → gc-COZteyiq.mjs} +27 -253
- package/dist/{guide-DwmaD_Wa.mjs → guide-NDvTmMi-.mjs} +336 -48
- package/dist/{idle-DpRLp5lj.mjs → idle-NETbeNiQ.mjs} +4 -3
- package/dist/{in-use-CjUluqIX.mjs → in-use-DVhlSoyn.mjs} +4 -4
- package/dist/{ios-Dd-hYJBh.mjs → ios-CQLKpNfr.mjs} +294 -81
- package/dist/{ios-B2Fpqvlb.mjs → ios-DArbmwer.mjs} +16 -7
- package/dist/{ios-device-CtRdEVjx.mjs → ios-device-CwDZo0X4.mjs} +1 -1
- package/dist/{launch-verify-CQS_Kg-C.mjs → launch-verify-CuPDGXdr.mjs} +1 -1
- package/dist/logs-B44a1UeU.mjs +485 -0
- package/dist/merge-state-DDxS-XIZ.mjs +232 -0
- package/dist/{named-ports-DiTfSz6p.mjs → named-ports-Dc7neAlc.mjs} +1 -1
- package/dist/native-run-D7yB_AsB.mjs +143 -0
- package/dist/{ownership-DZjdx8Gq.mjs → ownership-BiojdtAp.mjs} +3 -3
- package/dist/{ports-CLSSFOuz.mjs → ports-DwBaRFJs.mjs} +1 -1
- package/dist/{reload-DoETJ3rl.mjs → reload-By9Dwsrt.mjs} +4 -4
- package/dist/{server-bare-DVbb7kXH.mjs → server-bare-D_RK1RCj.mjs} +1 -1
- package/dist/server-expo-B-CCUJZj.mjs +2 -0
- package/dist/{server-expo-BvOCeakp.mjs → server-expo-o6H5gcBc.mjs} +1 -1
- package/dist/{settings-DOugPlPz.mjs → settings-B5oFZEri.mjs} +12 -3
- package/dist/{settings-EWYNwe72.mjs → settings-C0ugALSC.mjs} +1 -1
- package/dist/settings.schema.json +52 -0
- package/dist/{simslim-Ca3487H6.mjs → simslim-CIR3IYJO.mjs} +150 -95
- package/dist/{slot-launch-C5cg0fmk.mjs → slot-launch-rggO1Esw.mjs} +2 -2
- package/dist/{spawn-claims-CUleC2cM.mjs → spawn-claims-BJwXTMPt.mjs} +24 -1
- package/dist/{start-F9gv5dcC.mjs → start-BSsf2tUs.mjs} +4 -4
- package/dist/{start-VoFsPSes.mjs → start-i8zc9VmS.mjs} +1 -1
- package/dist/{status-DLCD-o3s.mjs → status-CitcBRsC.mjs} +227 -22
- package/dist/{status-Dr4fRkym.mjs → status-Q-WDEGCB.mjs} +20 -6
- package/dist/{stop-Dj4pfmyv.mjs → stop-DIhrvu0B.mjs} +188 -27
- package/dist/stop-rst5mL14.mjs +3 -0
- package/dist/supervisor-run.mjs +7 -7
- package/dist/{workspace-process-lock-BXA96myD.mjs → workspace-process-lock-Cx74RSDZ.mjs} +9 -4
- package/dist/{workspaces-BTUyFfkv.mjs → workspaces-COD2xCz-.mjs} +15 -5
- package/dist/{worktree-4aZg2NnI.mjs → worktree-DhxDTK44.mjs} +1 -1
- package/dist/{worktree-BMS7GeqB.mjs → worktree-KOjMX3zA.mjs} +8 -8
- package/dist/{xcode-B2tBkf0m.mjs → xcode-B5SPD--o.mjs} +3 -3
- package/package.json +5 -5
- package/dist/logs-MARIy6m9.mjs +0 -209
- package/dist/server-expo-DBVTdult.mjs +0 -2
- package/dist/stop-ZvOeTmKb.mjs +0 -3
|
@@ -4,18 +4,18 @@ import { N as workspaceStateFile, O as workspaceDir, v as workspaceLastUsed } fr
|
|
|
4
4
|
import { C as sourceCheckoutOf, b as resolveFullRef, d as hasUncommittedWork, l as hasPopulatedSubmodules, m as listWorktrees, o as dirtyPaths, w as unpushedCommits } from "./worktree-BlizKDpZ.mjs";
|
|
5
5
|
import { a as detectIsExpo, o as findProjectRoot } from "./project-BXZzOABt.mjs";
|
|
6
6
|
import { h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-D5z2_bcF.mjs";
|
|
7
|
-
import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-
|
|
8
|
-
import {
|
|
9
|
-
import { h as POOL_SETTING_REMEDY, y as parkedMaxSetting } from "./ownership-
|
|
10
|
-
import { l as listAllIosSims } from "./ios-
|
|
11
|
-
import { a as parseIdleDuration, o as shutDownIdleDevices, r as idleDeviceLines, t as collectIdleDevices } from "./idle-
|
|
12
|
-
import { i as canonicalPath, o as listBuildSlots, r as workspaceInUse } from "./in-use-
|
|
13
|
-
import { C as listOwnedSessionsArgs, D as verifyStoppedSession, E as stopSessionArgs, S as isDefinitiveMissingSessionError, T as parseSessionListPage, b as getSessionArgs, d as withRemoteSessionLock, f as withEasProjectLock, h as removeEasSessionClaim, m as readEasSessionLedger, p as easMachineStateRoot, x as inspectSessionForTeardown, y as findOrphanedOwnedSessions, z as resolveEasCliBin } from "./device-remote-
|
|
14
|
-
import { A as discoverCaches, C as unverifiedDeviceCommand, D as planCacheEmptying, E as includesWorkspaceOutputs, O as selectCaches, S as findStaleProjectDevices, T as emptyCaches, _ as describeParkedSims, a as collectWorkspaceOutputs, b as findOrphanedDevices, c as listWorkspaceDirs, d as collectDeviceLeases, f as collectParkedAvds, g as deleteProjectDevices, h as deleteParkedSims, i as collectOrphanedWorkspaces, j as sizeCaches, k as trimCaches, l as sizeText, m as deleteParkedAvds, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as collectParkedSims, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as DEVICE_LIST_TIMEOUT_MS, v as describeUnverifiableDevices, w as withAndroidAvdSizes, x as findStaleDeviceRecords, y as deviceSweepIsScoped } from "./workspaces-
|
|
15
|
-
import { a as reclaimKeys, d as removeWorktreeTarget, m as reclaimProject, n as excludePodChurn, p as describeDereferenced, r as matchWorktreeEntry } from "./worktree-
|
|
16
|
-
import {
|
|
7
|
+
import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-D83nqeMX.mjs";
|
|
8
|
+
import { D as listAvds, N as ownedAvdDirectory, Y as isStimOwnedSim, k as listOrphanedAvdDirectories, w as isStimOwnedAvdName } from "./android-C4zG2Tuc.mjs";
|
|
9
|
+
import { h as POOL_SETTING_REMEDY, y as parkedMaxSetting } from "./ownership-BiojdtAp.mjs";
|
|
10
|
+
import { l as listAllIosSims } from "./ios-DArbmwer.mjs";
|
|
11
|
+
import { a as parseIdleDuration, o as shutDownIdleDevices, r as idleDeviceLines, t as collectIdleDevices } from "./idle-NETbeNiQ.mjs";
|
|
12
|
+
import { i as canonicalPath, o as listBuildSlots, r as workspaceInUse } from "./in-use-DVhlSoyn.mjs";
|
|
13
|
+
import { C as listOwnedSessionsArgs, D as verifyStoppedSession, E as stopSessionArgs, S as isDefinitiveMissingSessionError, T as parseSessionListPage, b as getSessionArgs, d as withRemoteSessionLock, f as withEasProjectLock, h as removeEasSessionClaim, m as readEasSessionLedger, p as easMachineStateRoot, x as inspectSessionForTeardown, y as findOrphanedOwnedSessions, z as resolveEasCliBin } from "./device-remote-BQZSnnmE.mjs";
|
|
14
|
+
import { A as discoverCaches, C as unverifiedDeviceCommand, D as planCacheEmptying, E as includesWorkspaceOutputs, O as selectCaches, S as findStaleProjectDevices, T as emptyCaches, _ as describeParkedSims, a as collectWorkspaceOutputs, b as findOrphanedDevices, c as listWorkspaceDirs, d as collectDeviceLeases, f as collectParkedAvds, g as deleteProjectDevices, h as deleteParkedSims, i as collectOrphanedWorkspaces, j as sizeCaches, k as trimCaches, l as sizeText, m as deleteParkedAvds, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as collectParkedSims, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as DEVICE_LIST_TIMEOUT_MS, v as describeUnverifiableDevices, w as withAndroidAvdSizes, x as findStaleDeviceRecords, y as deviceSweepIsScoped } from "./workspaces-COD2xCz-.mjs";
|
|
15
|
+
import { a as reclaimKeys, d as removeWorktreeTarget, m as reclaimProject, n as excludePodChurn, p as describeDereferenced, r as matchWorktreeEntry } from "./worktree-KOjMX3zA.mjs";
|
|
16
|
+
import { n as mergeState, t as fetchDefaultBranch } from "./merge-state-DDxS-XIZ.mjs";
|
|
17
17
|
import { InvalidArgumentError } from "commander";
|
|
18
|
-
import { existsSync
|
|
18
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
19
19
|
import { basename, dirname, isAbsolute, join } from "path";
|
|
20
20
|
import chalk from "chalk";
|
|
21
21
|
//#region src/commands/gc/eas-sessions.ts
|
|
@@ -37,18 +37,18 @@ function readRecordedRemoteSessionIds(roots) {
|
|
|
37
37
|
let safe = true;
|
|
38
38
|
for (const root of new Set(roots)) {
|
|
39
39
|
try {
|
|
40
|
-
if (!statSync
|
|
41
|
-
readdirSync
|
|
40
|
+
if (!statSync(root).isDirectory()) throw new Error("path is not a directory");
|
|
41
|
+
readdirSync(root);
|
|
42
42
|
} catch (error) {
|
|
43
43
|
safe = false;
|
|
44
44
|
notices.push(`${root} is not available as a readable workspace directory: ${describeError(error)}`);
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
47
|
const path = workspaceStateFile(root);
|
|
48
|
-
if (!existsSync
|
|
48
|
+
if (!existsSync(path)) continue;
|
|
49
49
|
let state;
|
|
50
50
|
try {
|
|
51
|
-
state = JSON.parse(readFileSync
|
|
51
|
+
state = JSON.parse(readFileSync(path, "utf-8"));
|
|
52
52
|
} catch (error) {
|
|
53
53
|
safe = false;
|
|
54
54
|
notices.push(`${path} could not be read as valid JSON: ${describeError(error)}`);
|
|
@@ -84,8 +84,8 @@ function claimStateAbsence(claim) {
|
|
|
84
84
|
const stateDir = dirname(claim.stateFile);
|
|
85
85
|
let entries;
|
|
86
86
|
try {
|
|
87
|
-
if (!statSync
|
|
88
|
-
entries = readdirSync
|
|
87
|
+
if (!statSync(stateDir).isDirectory()) throw new Error("path is not a directory");
|
|
88
|
+
entries = readdirSync(stateDir);
|
|
89
89
|
} catch (error) {
|
|
90
90
|
return {
|
|
91
91
|
absent: false,
|
|
@@ -98,7 +98,7 @@ function claimStateAbsence(claim) {
|
|
|
98
98
|
};
|
|
99
99
|
let state;
|
|
100
100
|
try {
|
|
101
|
-
state = JSON.parse(readFileSync
|
|
101
|
+
state = JSON.parse(readFileSync(claim.stateFile, "utf-8"));
|
|
102
102
|
} catch (error) {
|
|
103
103
|
return {
|
|
104
104
|
absent: false,
|
|
@@ -215,8 +215,8 @@ function easLockRoots(projectRoot, config) {
|
|
|
215
215
|
}
|
|
216
216
|
function unavailableLockRootNotice(roots) {
|
|
217
217
|
for (const root of roots) try {
|
|
218
|
-
if (!statSync
|
|
219
|
-
readdirSync
|
|
218
|
+
if (!statSync(root).isDirectory()) throw new Error("path is not a directory");
|
|
219
|
+
readdirSync(root);
|
|
220
220
|
} catch (error) {
|
|
221
221
|
return `EAS session sweep skipped: ${root} is not available for remote-session lock inspection: ${describeError(error)}`;
|
|
222
222
|
}
|
|
@@ -225,7 +225,7 @@ function unavailableLockRootNotice(roots) {
|
|
|
225
225
|
function malformedRemoteSessionLockNotice(roots) {
|
|
226
226
|
for (const root of roots) {
|
|
227
227
|
const lockPath = join(workspaceDir(root), "remote-session.lock");
|
|
228
|
-
if (!existsSync
|
|
228
|
+
if (!existsSync(lockPath)) continue;
|
|
229
229
|
if ((0, ownership_claim_exports.readClaimSet)(lockPath).unresolved.length === 0) continue;
|
|
230
230
|
return `EAS session sweep skipped: the remote-session lock at ${lockPath} has a malformed owner record.`;
|
|
231
231
|
}
|
|
@@ -399,233 +399,6 @@ async function deleteEasSessions(easSessionSweep, deps) {
|
|
|
399
399
|
return deleteFailures;
|
|
400
400
|
}
|
|
401
401
|
//#endregion
|
|
402
|
-
//#region src/workspace/merge-state.ts
|
|
403
|
-
const FETCH_TIMEOUT_MS = 3e4;
|
|
404
|
-
const FETCH_FRESH_MS = 6e5;
|
|
405
|
-
const GIT_TIMEOUT_MS = 6e4;
|
|
406
|
-
const REMOTE_PREFIX = "refs/remotes/origin/";
|
|
407
|
-
function failure(error) {
|
|
408
|
-
const { stderr, message } = error;
|
|
409
|
-
const text = String(stderr ?? "").trim() || String(message ?? error);
|
|
410
|
-
return text.split("\n")[0] ?? text;
|
|
411
|
-
}
|
|
412
|
-
function fetchedRecently(repo, now) {
|
|
413
|
-
const path = getExecutor().runFileQuiet("git", [
|
|
414
|
-
"-C",
|
|
415
|
-
repo,
|
|
416
|
-
"rev-parse",
|
|
417
|
-
"--path-format=absolute",
|
|
418
|
-
"--git-path",
|
|
419
|
-
"FETCH_HEAD"
|
|
420
|
-
])?.trim();
|
|
421
|
-
try {
|
|
422
|
-
return Boolean(path) && now - statSync(path).mtimeMs < FETCH_FRESH_MS;
|
|
423
|
-
} catch {
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Fetches the default branch that `origin/HEAD` names into its remote-tracking ref, bounded by a timeout and never
|
|
429
|
-
* prompting for credentials. It skips the fetch when the checkout fetched anything in the last 10 minutes.
|
|
430
|
-
*/
|
|
431
|
-
function fetchDefaultBranch(repo, now = Date.now()) {
|
|
432
|
-
const exec = getExecutor();
|
|
433
|
-
const ref = exec.runFileQuiet("git", [
|
|
434
|
-
"-C",
|
|
435
|
-
repo,
|
|
436
|
-
"symbolic-ref",
|
|
437
|
-
"--quiet",
|
|
438
|
-
"refs/remotes/origin/HEAD"
|
|
439
|
-
])?.trim();
|
|
440
|
-
if (!ref?.startsWith(REMOTE_PREFIX)) return { error: `origin/HEAD is not set; run \`git -C ${repo} remote set-head origin --auto\`` };
|
|
441
|
-
const branch = ref.slice(20);
|
|
442
|
-
if (fetchedRecently(repo, now)) return {
|
|
443
|
-
ref,
|
|
444
|
-
name: `origin/${branch}`
|
|
445
|
-
};
|
|
446
|
-
try {
|
|
447
|
-
exec.runFile("git", [
|
|
448
|
-
"-C",
|
|
449
|
-
repo,
|
|
450
|
-
"fetch",
|
|
451
|
-
"--quiet",
|
|
452
|
-
"--no-tags",
|
|
453
|
-
"--no-recurse-submodules",
|
|
454
|
-
"origin",
|
|
455
|
-
`+refs/heads/${branch}:${ref}`
|
|
456
|
-
], {
|
|
457
|
-
timeoutMs: FETCH_TIMEOUT_MS,
|
|
458
|
-
env: { GIT_TERMINAL_PROMPT: "0" }
|
|
459
|
-
});
|
|
460
|
-
} catch (error) {
|
|
461
|
-
return { error: `git fetch origin ${branch} failed: ${failure(error)}` };
|
|
462
|
-
}
|
|
463
|
-
return {
|
|
464
|
-
ref,
|
|
465
|
-
name: `origin/${branch}`
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
function notMerged(detail) {
|
|
469
|
-
return {
|
|
470
|
-
merged: false,
|
|
471
|
-
unknown: false,
|
|
472
|
-
detail
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
function currentBranch(path) {
|
|
476
|
-
const ref = getExecutor().runFileQuiet("git", [
|
|
477
|
-
"-C",
|
|
478
|
-
path,
|
|
479
|
-
"symbolic-ref",
|
|
480
|
-
"--quiet",
|
|
481
|
-
"HEAD"
|
|
482
|
-
])?.trim();
|
|
483
|
-
return ref?.startsWith("refs/heads/") ? ref : null;
|
|
484
|
-
}
|
|
485
|
-
function upstreamGone(path, branch) {
|
|
486
|
-
if (!branch) return false;
|
|
487
|
-
const [upstream, state] = (getExecutor().runFileQuiet("git", [
|
|
488
|
-
"-C",
|
|
489
|
-
path,
|
|
490
|
-
"for-each-ref",
|
|
491
|
-
"--format=%(upstream)%00%(upstream:track)",
|
|
492
|
-
branch
|
|
493
|
-
]) ?? "").trim().split("\0");
|
|
494
|
-
return Boolean(upstream) && state === "[gone]";
|
|
495
|
-
}
|
|
496
|
-
function committedOn(path, branch, head) {
|
|
497
|
-
if (!branch) return false;
|
|
498
|
-
const exec = getExecutor();
|
|
499
|
-
return (exec.runFileQuiet("git", [
|
|
500
|
-
"-C",
|
|
501
|
-
path,
|
|
502
|
-
"reflog",
|
|
503
|
-
"show",
|
|
504
|
-
"--format=%H %gs",
|
|
505
|
-
branch
|
|
506
|
-
]) ?? "").split("\n").some((entry) => {
|
|
507
|
-
const [sha = "", ...subject] = entry.split(" ");
|
|
508
|
-
return /^(commit|cherry-pick|rebase|revert)\b/.test(subject.join(" ")) && exec.runFileQuiet("git", [
|
|
509
|
-
"-C",
|
|
510
|
-
path,
|
|
511
|
-
"merge-base",
|
|
512
|
-
"--is-ancestor",
|
|
513
|
-
sha,
|
|
514
|
-
head
|
|
515
|
-
]) !== null;
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
/**
|
|
519
|
-
* Whether the worktree's HEAD is merged into `target`. The signals, all local git:
|
|
520
|
-
* - HEAD is an ancestor of the default branch, off its first-parent line, and the branch's reflog shows a commit made
|
|
521
|
-
* on it that HEAD contains, so a merge commit brought the branch's own work in. A branch with no commit of its own
|
|
522
|
-
* is not merged.
|
|
523
|
-
* - The branch changes the tree, has no merge commits, and every commit since the merge base has the same
|
|
524
|
-
* `git patch-id --verbatim` as a commit on the default branch (a rebase merge).
|
|
525
|
-
* - The branch changes the tree and its whole diff since the merge base has the same verbatim patch id as a commit on
|
|
526
|
-
* the default branch, limited to the files the branch changes (a squash merge).
|
|
527
|
-
* Anything git cannot answer is unknown, never merged. `coversUnpushed` is true for a patch-equivalent HEAD whose
|
|
528
|
-
* upstream branch was deleted: its commits exist only locally, but their change is on the default branch.
|
|
529
|
-
*/
|
|
530
|
-
function mergeState(path, { ref, name }) {
|
|
531
|
-
const git = (args, input) => getExecutor().runFile("git", [
|
|
532
|
-
"--literal-pathspecs",
|
|
533
|
-
"-C",
|
|
534
|
-
path,
|
|
535
|
-
...args
|
|
536
|
-
], {
|
|
537
|
-
timeoutMs: GIT_TIMEOUT_MS,
|
|
538
|
-
input
|
|
539
|
-
});
|
|
540
|
-
const patch = (args) => getExecutor().runFile("git", [
|
|
541
|
-
"--literal-pathspecs",
|
|
542
|
-
"-C",
|
|
543
|
-
path,
|
|
544
|
-
...args
|
|
545
|
-
], {
|
|
546
|
-
timeoutMs: GIT_TIMEOUT_MS,
|
|
547
|
-
untrimmed: true
|
|
548
|
-
});
|
|
549
|
-
const patchIds = (text) => text ? git(["patch-id", "--verbatim"], text).split("\n").flatMap((line) => line.split(" ")[0] || []) : [];
|
|
550
|
-
const diffOptions = ["--no-color", "--no-ext-diff"];
|
|
551
|
-
const noOwnCommits = notMerged(`no commits of its own beyond ${name}`);
|
|
552
|
-
try {
|
|
553
|
-
const head = git([
|
|
554
|
-
"rev-parse",
|
|
555
|
-
"--verify",
|
|
556
|
-
"HEAD^{commit}"
|
|
557
|
-
]);
|
|
558
|
-
const base = git([
|
|
559
|
-
"merge-base",
|
|
560
|
-
head,
|
|
561
|
-
ref
|
|
562
|
-
]);
|
|
563
|
-
const branch = currentBranch(path);
|
|
564
|
-
if (base === head) {
|
|
565
|
-
if (git(["rev-parse", ref]) === head || git([
|
|
566
|
-
"rev-list",
|
|
567
|
-
"--first-parent",
|
|
568
|
-
"--parents",
|
|
569
|
-
`${head}..${ref}`
|
|
570
|
-
]).split("\n").some((line) => line.split(" ")[1] === head) || !committedOn(path, branch, head)) return noOwnCommits;
|
|
571
|
-
return {
|
|
572
|
-
merged: true,
|
|
573
|
-
into: name,
|
|
574
|
-
head,
|
|
575
|
-
coversUnpushed: false
|
|
576
|
-
};
|
|
577
|
-
}
|
|
578
|
-
const files = git([
|
|
579
|
-
"diff",
|
|
580
|
-
"--name-only",
|
|
581
|
-
"--no-renames",
|
|
582
|
-
"-z",
|
|
583
|
-
base,
|
|
584
|
-
head
|
|
585
|
-
]).split("\0").filter(Boolean);
|
|
586
|
-
if (!files.length) return notMerged(`no net change beyond ${name}`);
|
|
587
|
-
const log = (range, pathspec = []) => patch([
|
|
588
|
-
"log",
|
|
589
|
-
"-p",
|
|
590
|
-
"--no-merges",
|
|
591
|
-
...diffOptions,
|
|
592
|
-
"--format=commit %H",
|
|
593
|
-
range,
|
|
594
|
-
"--",
|
|
595
|
-
...pathspec
|
|
596
|
-
]);
|
|
597
|
-
const upstream = new Set(patchIds(log(`${base}..${ref}`, files)));
|
|
598
|
-
const patchEquivalent = () => ({
|
|
599
|
-
merged: true,
|
|
600
|
-
into: name,
|
|
601
|
-
head,
|
|
602
|
-
coversUnpushed: upstreamGone(path, branch)
|
|
603
|
-
});
|
|
604
|
-
const squash = patchIds(patch([
|
|
605
|
-
"diff",
|
|
606
|
-
...diffOptions,
|
|
607
|
-
base,
|
|
608
|
-
head
|
|
609
|
-
]));
|
|
610
|
-
if (squash.length === 1 && upstream.has(squash[0])) return patchEquivalent();
|
|
611
|
-
if (!git([
|
|
612
|
-
"rev-list",
|
|
613
|
-
"--merges",
|
|
614
|
-
`${base}..${head}`
|
|
615
|
-
])) {
|
|
616
|
-
const own = patchIds(log(`${base}..${head}`));
|
|
617
|
-
if (own.length && own.every((id) => upstream.has(id))) return patchEquivalent();
|
|
618
|
-
}
|
|
619
|
-
return notMerged(`not merged into ${name}`);
|
|
620
|
-
} catch (error) {
|
|
621
|
-
return {
|
|
622
|
-
merged: false,
|
|
623
|
-
unknown: true,
|
|
624
|
-
detail: `merge state unknown: ${failure(error)}`
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
//#endregion
|
|
629
402
|
//#region src/commands/gc/worktrees.ts
|
|
630
403
|
const DEFAULT_WORKTREE_IDLE_DAYS = 7;
|
|
631
404
|
const DAY_MS = 864e5;
|
|
@@ -685,7 +458,7 @@ function porcelainOf(path, gitAnswered) {
|
|
|
685
458
|
function candidateRoots() {
|
|
686
459
|
const registered = Object.keys(loadConfig()?.projects ?? {}).filter(isAbsolute);
|
|
687
460
|
const recorded = listWorkspaceDirs().flatMap((entry) => entry.projectRoot ? [entry.projectRoot] : []);
|
|
688
|
-
return [.../* @__PURE__ */ new Set([...registered, ...recorded])].filter((root) => existsSync
|
|
461
|
+
return [.../* @__PURE__ */ new Set([...registered, ...recorded])].filter((root) => existsSync(root)).toSorted();
|
|
689
462
|
}
|
|
690
463
|
function checkMergeStates(pending, idle, now) {
|
|
691
464
|
const repos = /* @__PURE__ */ new Map();
|
|
@@ -851,7 +624,7 @@ function formatParkedAvdReport(parkedAvds, now) {
|
|
|
851
624
|
lines.push(`Parked emulators (${parkedAvds.length}):`);
|
|
852
625
|
for (const avd of parkedAvds) {
|
|
853
626
|
const listed = avd.listed === false ? " - not on this machine" : avd.listed === null ? " - listing unavailable; kept" : "";
|
|
854
|
-
lines.push(` android ${avd.name} ${avd.systemImage} ${parkedAge(avd.parkedAt, now)}${avd.bytes === null ? "" : ` ${formatBytes(avd.bytes)}`}${listed}`);
|
|
627
|
+
lines.push(` android ${avd.name} ${avd.systemImage}${avd.deviceProfile ? ` ${avd.deviceProfile}` : ""} ${parkedAge(avd.parkedAt, now)}${avd.bytes === null ? "" : ` ${formatBytes(avd.bytes)}`}${listed}`);
|
|
855
628
|
}
|
|
856
629
|
lines.push(" --delete attempts verified deletions and keeps failures.");
|
|
857
630
|
return lines;
|
|
@@ -1147,9 +920,10 @@ function gcReportSections({ skipped = [], deadProjects = [], orphanedPorts = [],
|
|
|
1147
920
|
bytes,
|
|
1148
921
|
listed
|
|
1149
922
|
})),
|
|
1150
|
-
parkedEmulators: parkedAvds.map(({ name, systemImage, parkedAt, bytes, listed }) => ({
|
|
923
|
+
parkedEmulators: parkedAvds.map(({ name, systemImage, deviceProfile, parkedAt, bytes, listed }) => ({
|
|
1151
924
|
name,
|
|
1152
925
|
systemImage,
|
|
926
|
+
deviceProfile,
|
|
1153
927
|
parkedAt,
|
|
1154
928
|
bytes,
|
|
1155
929
|
listed
|
|
@@ -1344,7 +1118,7 @@ async function collectGcReport({ olderThan = null, cache = null, worktrees = fal
|
|
|
1344
1118
|
else invalidProjects.push(path);
|
|
1345
1119
|
continue;
|
|
1346
1120
|
}
|
|
1347
|
-
if (existsSync
|
|
1121
|
+
if (existsSync(path)) continue;
|
|
1348
1122
|
if (!isOnMountedVolume(path, mountedVolumes)) {
|
|
1349
1123
|
const volume = volumeRootFor(path);
|
|
1350
1124
|
skipped.push({
|
|
@@ -1634,7 +1408,7 @@ async function runGcCore(opts, deps) {
|
|
|
1634
1408
|
deleteFailures += deleteParkedSims(report.parkedSims, deps) + deleteParkedAvds(report.parkedAvds);
|
|
1635
1409
|
removeInvalidProjectEntries(invalidProjects);
|
|
1636
1410
|
for (const path of deadProjects) {
|
|
1637
|
-
if (existsSync
|
|
1411
|
+
if (existsSync(path) || !isOnMountedVolume(path)) {
|
|
1638
1412
|
console.log(chalk.yellow(`Kept ${path}: its absence can no longer be confirmed.`));
|
|
1639
1413
|
continue;
|
|
1640
1414
|
}
|