stim 1.17.2 → 1.18.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/README.md +50 -1
- package/dist/{activity-IRvJY_ru.mjs → activity-BxnkDZDi.mjs} +4 -4
- package/dist/{agent-device-usage-output-BK41vnzN.mjs → agent-device-usage-output-CZ66YA4T.mjs} +8 -8
- package/dist/android-BKA16DTf.mjs +4 -0
- package/dist/{android-B9yaNKwa.mjs → android-BvwuMUJ9.mjs} +192 -98
- package/dist/{android-DE4v59Mb.mjs → android-CBwCNicO.mjs} +2 -2
- package/dist/{android-B_YNZy61.mjs → android-DC3ZLuw0.mjs} +9 -9
- package/dist/{android-cas-ZFpjJBL_.mjs → android-cas-BBFyr9CA.mjs} +5 -5
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/api-D0VtFhqk.mjs +152 -0
- package/dist/api-run.d.mts +1 -0
- package/dist/api-run.mjs +145 -0
- package/dist/api.d.mts +212 -0
- package/dist/api.mjs +2 -0
- package/dist/{app-install-VPkI5WEg.mjs → app-install-D-PUENug.mjs} +3 -3
- package/dist/{attempt-Bk2ouQVL.mjs → attempt-DW-mQqM7.mjs} +14 -4
- package/dist/{budget-DfcgFdQB.mjs → budget-DIhL2BKx.mjs} +1578 -58
- package/dist/build-facts-DcLv2HSd.d.mts +111 -0
- package/dist/{cache-manifest-DnUHBJaU.mjs → cache-manifest-BI7ozfmH.mjs} +3 -3
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-BrcVWQyD.mjs → chrome-DJnmnS5q.mjs} +1 -1
- package/dist/cli-DNJMwADx.mjs +68 -0
- package/dist/cli.mjs +1 -1
- package/dist/{client-SvBdgObD.mjs → client-DzhapoMB.mjs} +139 -32
- package/dist/collector-run.mjs +9 -9
- package/dist/{command-output-CDAIFD-8.mjs → command-output-CBtzyIgF.mjs} +2 -2
- package/dist/{config-D0DbpZtM.mjs → config-CgYMahz7.mjs} +5 -5
- package/dist/{created-devices-CpvzBL25.mjs → created-devices-DKbeWsiK.mjs} +2 -2
- package/dist/{dependency-state-CLcBHH2M.mjs → dependency-state-xKoOypBm.mjs} +2 -2
- package/dist/{detached-entry-CiTEgMR1.mjs → detached-entry-BLfcgc4O.mjs} +1 -1
- package/dist/{dev-client-B-XC4uRH.mjs → dev-client-CLnIH02x.mjs} +2 -2
- package/dist/{device-C8IOoJPv.mjs → device-D7oCHGWi.mjs} +8 -8
- package/dist/{device-capacity-ZC4XSZ4R.mjs → device-capacity-EUOOYr8T.mjs} +13 -13
- package/dist/device-host-worker.mjs +19 -19
- package/dist/{device-ios-C2Um-XUR.mjs → device-ios-6MewKKnc.mjs} +13 -13
- package/dist/{device-lease-DpoS36_u.mjs → device-lease-Co-EwifR.mjs} +9 -9
- package/dist/{device-lease-run-B8YltIH_.mjs → device-lease-run-w1xhCqIW.mjs} +4 -4
- package/dist/{device-pool-3o7s5lo4.mjs → device-pool-F5WvRPtD.mjs} +3 -3
- package/dist/{device-remote-hFSkpfQu.mjs → device-remote-tHbd1fKy.mjs} +15 -15
- package/dist/{doctor-CFv1fCrF.mjs → doctor-B9ckYUoU.mjs} +33 -30
- package/dist/{error-diagnostics-C-NMnhrk.mjs → error-diagnostics-BRXOqDzG.mjs} +11 -11
- package/dist/{exec-CaErVv7t.mjs → exec-DWhCZDGm.mjs} +65 -2
- package/dist/{gc-DEmkg3Xh.mjs → gc-Dh6mXOKC.mjs} +23 -469
- package/dist/{gradle-dJpre3Yn.mjs → gradle-C6GKnunQ.mjs} +6 -6
- package/dist/{guide-status-Du-ZQ3FD.mjs → guide-status-Bhf9SJXc.mjs} +3 -3
- package/dist/{guide-CSmhMTf8.mjs → guide-tm6igAaa.mjs} +290 -53
- package/dist/{hosted-android-E1Heoqnv.mjs → hosted-android-Bv285t_t.mjs} +3 -3
- package/dist/{hosted-client-Bp4knSwu.mjs → hosted-client-C-rMtppF.mjs} +2 -2
- package/dist/{hosted-ios-BnbeYOUD.mjs → hosted-ios-D5mNmtj4.mjs} +1 -1
- package/dist/{hosted-logs-OcgIBvCT.mjs → hosted-logs-DN8Iz4mJ.mjs} +9 -9
- package/dist/{hosted-macos-DcxKjtfH.mjs → hosted-macos-B-wEjlwG.mjs} +5 -5
- package/dist/{hosted-native-1Ebbig4w.mjs → hosted-native-DeeOG8xZ.mjs} +6 -6
- package/dist/{idle-shutdown-IGyNV8Cr.mjs → idle-shutdown-jjtxAn5C.mjs} +7 -8
- package/dist/{ios-DSfnPfse.mjs → ios-B3SbOWdw.mjs} +19 -7
- package/dist/{ios-Cr1h5gnO.mjs → ios-Bvbf0SGY.mjs} +1 -1
- package/dist/{ios-BJ4XUSe1.mjs → ios-CPdkoKaa.mjs} +181 -95
- package/dist/ios-DNpdygiv.mjs +7 -0
- package/dist/{ios-device-Ee7sDXfp.mjs → ios-device-Bn7jWDB1.mjs} +1 -1
- package/dist/{ios-device-pAN4t54-.mjs → ios-device-vOaByMhw.mjs} +3 -3
- package/dist/{ios-state-8L3lgum6.mjs → ios-state-B2pES6Vs.mjs} +1 -1
- package/dist/{launch-verify-lTnWZikR.mjs → launch-verify-hskNcWkZ.mjs} +5 -5
- package/dist/{logs-BAaS7gS2.mjs → logs-1Ylc1Ri6.mjs} +13 -13
- package/dist/macos-Ck7OBMNY.mjs +2 -0
- package/dist/{macos-BIRQS90f.mjs → macos-DF6C7wUU.mjs} +118 -34
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +349 -47
- package/dist/{metro-g8NqiJp-.mjs → metro-Dh8T4Ytd.mjs} +5 -5
- package/dist/{metro-gateway-C-ijGI2F.mjs → metro-gateway-CEUw9RMH.mjs} +4 -4
- package/dist/{metro-store-CDDZHtPl.mjs → metro-store-BAHFcJm6.mjs} +16 -2
- package/dist/{named-ports-C8m8EQs2.mjs → named-ports-BFIz1Shz.mjs} +61 -6
- package/dist/{native-run-D1Q56rAD.mjs → native-run-B06FkmZx.mjs} +4 -4
- package/dist/{native-runtime-BEK171xQ.mjs → native-runtime-D_603JiC.mjs} +6 -6
- package/dist/{ndjson-PclOIwVY.mjs → ndjson-LGZAMsqa.mjs} +8 -4
- package/dist/offload-worker.d.mts +3 -17
- package/dist/offload-worker.mjs +10 -11
- package/dist/{ownership-DyRQru0q.mjs → ownership-D6Se7gg_.mjs} +3 -3
- package/dist/{page-QF_Ke10s.mjs → page-Bv9s2KwY.mjs} +1 -1
- package/dist/placement-log-BcPhRwR4.mjs +84 -0
- package/dist/{build-plan-BDsSi09V.mjs → plan-placement-CtxkCO54.mjs} +122 -48
- package/dist/{ports-4nYqxPWC.mjs → ports-BLTtfBq-.mjs} +3 -3
- package/dist/{prebuild-D7RUMkwN.mjs → prebuild-juCyreaR.mjs} +5 -5
- package/dist/preview-D5V07Nrl.mjs +987 -0
- package/dist/{rolldown-runtime-BsOwBuO_.mjs → process-identity-Biv3arCO.mjs} +11 -1
- package/dist/{project-D47Rh0ly.mjs → project-C3ChRLZy.mjs} +4 -68
- package/dist/projects-DD7dBTCj.mjs +92 -0
- package/dist/{pull-request-pxnDCQzn.mjs → pull-request-u4vp7zmK.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/{recordings-BNgsD1Tr.mjs → recordings-BAWltsVt.mjs} +1 -1
- package/dist/{reload-DcRxj3qG.mjs → reload-DvyWzVjJ.mjs} +15 -15
- package/dist/{remote-cache-Ci4DQYYj.mjs → remote-cache-BGg7aGIZ.mjs} +5 -5
- package/dist/{run-CkE9y0nc.mjs → run-vhtDgpHO.mjs} +5 -5
- package/dist/{server-bare-BkrSxSsZ.mjs → server-bare-B9E7S1aR.mjs} +4 -5
- package/dist/server-expo-Db9HBUoa.mjs +2 -0
- package/dist/{server-expo-CHTyXD0G.mjs → server-expo-DoBHhuzK.mjs} +5 -6
- package/dist/{settings-SR9OmW9h.mjs → settings-Byp2AQ_E.mjs} +6 -5
- package/dist/{settings-Cfd-0r2d.mjs → settings-CQyMElEP.mjs} +24 -763
- package/dist/{settings-BBpMcDbD.mjs → settings-Djl-mpjX.mjs} +1 -1
- package/dist/settings.schema.json +126 -3
- package/dist/{simslim-BWNrc3M3.mjs → simslim-EHBQ2R4G.mjs} +7 -7
- package/dist/{slot-launch-DmjBmpQV.mjs → slot-launch-C1nqh4mu.mjs} +6 -6
- package/dist/{spawn-claims-D0XfSe8u.mjs → spawn-claims-Kqiifsk2.mjs} +1 -1
- package/dist/{spawn-entry-jw19m8Nl.mjs → spawn-entry-Dcb7sDUz.mjs} +1 -0
- package/dist/{stage-CzaiwFsI.mjs → stage-g_WqWeaE.mjs} +14 -3
- package/dist/{start-DUz3mYdb.mjs → start-D-IeOyoK.mjs} +19 -19
- package/dist/{start-AlfCPRVU.mjs → start-NTc1Ifqs.mjs} +1 -1
- package/dist/{state-PeQiJuIu.mjs → state-BG-aAk4k.mjs} +4 -4
- package/dist/{state-B4PQFXMW.d.mts → state-lKh8shBp.d.mts} +2 -3
- package/dist/{state-DyaNTgfR.mjs → state-xnqpx3AD.mjs} +2 -2
- package/dist/{stats-Bq4fJOdB.mjs → stats-DY6ekz8F.mjs} +5 -5
- package/dist/{status-DlKvVJBE.mjs → status-BEeL6IKz.mjs} +6 -4
- package/dist/{status-BA2pehwf.mjs → status-DCjZeE-K.mjs} +33 -34
- package/dist/{status-CzS4bPO9.mjs → status-Dcr0Qexd.mjs} +5 -5
- package/dist/{stim-desktop-Cnz8CPnl.mjs → stim-desktop-Behws_fi.mjs} +1 -1
- package/dist/{stim-installations-QMEI32v1.mjs → stim-installations-aR_WsNOA.mjs} +1 -1
- package/dist/{stop-BIiM49EY.mjs → stop-BGhKMOuH.mjs} +5 -5
- package/dist/{stop-DQIasgKp.mjs → stop-BTjs3xbc.mjs} +17 -18
- package/dist/{stop-zF1y04f2.mjs → stop-DIJtD2GL.mjs} +2 -2
- package/dist/supervisor-run.d.mts +24 -22
- package/dist/supervisor-run.mjs +21 -22
- package/dist/{support-CsJNVfOc.mjs → support-BaayeYCf.mjs} +7 -7
- package/dist/{support-WvD__tSV.mjs → support-Bwvbrq5-.mjs} +5 -5
- package/dist/{toolchain-DNyR3NPq.mjs → toolchain-Bnyd_K3A.mjs} +471 -22
- package/dist/{trigger-Bemu8ytw.mjs → trigger-CJMhwXe8.mjs} +5 -5
- package/dist/trigger-DWAq9hkw.mjs +2 -0
- package/dist/{warm-progress-DF4JRvYI.mjs → warm-progress-CjB-MP6H.mjs} +7 -7
- package/dist/web-B6_bFDn7.mjs +2 -0
- package/dist/{web-Dl0KSRHf.mjs → web-DTU0uiWj.mjs} +22 -22
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-DqcCbpE7.mjs → workspace-state-C59dqG-Z.mjs} +3 -3
- package/dist/{ownership-BMLqyBgJ.mjs → workspaces-xXItD8Dj.mjs} +577 -23
- package/dist/{worktree-j3IcFAI5.mjs → worktree-BJfnU6r5.mjs} +1 -1
- package/dist/{worktree-Be_7NLKy.mjs → worktree-BSYlofkq.mjs} +234 -35
- package/dist/worktree-CsKYexJM.mjs +753 -0
- package/package.json +10 -5
- package/dist/build-progress-D0WkjCPd.mjs +0 -1036
- package/dist/build-slots-41v_d2x9.mjs +0 -142
- package/dist/cli-CYXb29oE.mjs +0 -51
- package/dist/deps-iKw0eD4P.mjs +0 -438
- package/dist/errors-B6W7FkxQ.mjs +0 -15
- package/dist/idle-BXG__1BA.mjs +0 -176
- package/dist/in-use-CvGOUn-x.mjs +0 -130
- package/dist/preview-B-g9d7kV.mjs +0 -318
- package/dist/process-identity-BmRm1qV0.mjs +0 -12
- package/dist/server-expo-CeakhI8P.mjs +0 -2
- package/dist/state-BKa8wNN5.mjs +0 -148
- package/dist/stop-cause-rhmGfwvt.mjs +0 -97
- package/dist/trigger-CXts6qt1.mjs +0 -2
- package/dist/watchman-APYjXSQa.mjs +0 -48
- package/dist/workspace-process-lock-2mNzOlaB.mjs +0 -58
- package/dist/workspaces-Bcib97-6.mjs +0 -306
|
@@ -1,36 +1,30 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { d as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { n as
|
|
19
|
-
import { r as readCollectors } from "./ownership-DyRQru0q.mjs";
|
|
20
|
-
import { f as resolveEasCliBin } from "./remote-cache-Ci4DQYYj.mjs";
|
|
21
|
-
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$1, p as easMachineStateRoot$1, x as inspectSessionForTeardown, y as findOrphanedOwnedSessions } from "./device-remote-hFSkpfQu.mjs";
|
|
22
|
-
import { o as fetchDefaultBranch, s as mergeState } from "./warm-progress-DF4JRvYI.mjs";
|
|
23
|
-
import { _ as deleteSelectedArchives, f as removeWorktreeTarget, g as reclaimProject, h as describeDereferenced, i as matchWorktreeEntry, n as excludePodChurn, o as reclaimKeys, r as excludeWatchmanCookies, v as sweepArchiveStaging } from "./worktree-Be_7NLKy.mjs";
|
|
24
|
-
import { i as getSwiftpmCacheUsage, n as swiftpmCacheLines, r as getAgentDeviceUsage, t as agentDeviceLines } from "./agent-device-usage-output-BK41vnzN.mjs";
|
|
1
|
+
import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-DWhCZDGm.mjs";
|
|
3
|
+
import { h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-CBtzyIgF.mjs";
|
|
4
|
+
import { A as directorySize, D as withConfigLock$1, F as volumeRootFor, H as projectDeviceSlots, M as isOnMountedVolume, N as listMountedVolumes, S as removeProject, _ as loadConfig$1, j as formatBytes, k as acquireAvdClaim } from "./config-CgYMahz7.mjs";
|
|
5
|
+
import { i as detectIsExpo, s as findProjectRoot$1 } from "./project-C3ChRLZy.mjs";
|
|
6
|
+
import { C as workspaceStateFile, s as workspaceLastUsed, v as workspaceDir, w as withDirLock$1 } from "./workspace-state-C59dqG-Z.mjs";
|
|
7
|
+
import { $ as describeUnverifiableDevices, $t as sizeCaches, At as phase, C as idleDeviceLines, Ct as memoryCacheKind, Dt as memoryWorkPending, Et as memorySweepIsScoped, G as DEVICE_LIST_TIMEOUT_MS, J as collectParkedSims, K as collectDeviceLeases, Ot as reclaimMemory, Q as describeParkedSims, T as shutDownIdleDevices, Tt as memoryScope, X as deleteParkedSims, Y as deleteParkedAvds, Z as deleteProjectDevices, Zt as discoverCaches, _t as trimCaches, at as unverifiedDeviceCommand, ct as includesArchives, dt as includesWorkspaceOutputs, et as deviceSweepIsScoped, ft as isWorkspacesScope, gt as selectsBeyondCaches, ht as selectCaches, it as findStaleProjectDevices, kt as scopedMemoryReport, lt as includesParkedDevices, mt as previewScopedEmptying, nt as findOrphanedDevices, ot as withAndroidAvdSizes, pt as planCacheEmptying, q as collectParkedAvds, rt as findStaleDeviceRecords, st as emptyCaches, tt as eraseParkedDevices, ut as includesRecordings, vt as parseArchiveSelector, w as parseIdleDuration, wt as memoryLines, x as collectIdleDevices, xt as collectMemoryReport } from "./budget-DIhL2BKx.mjs";
|
|
8
|
+
import { F as takeGcResults, I as canonicalPath, M as listBuildSlots, P as recordGcResult, a as collectWorkspaceOutputs, c as listWorkspaceDirs, f as withIdleWorkspace, i as collectOrphanedWorkspaces, l as rootPresence, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as workspaceInUse, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as sizeText } from "./workspaces-xXItD8Dj.mjs";
|
|
9
|
+
import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-Co-EwifR.mjs";
|
|
10
|
+
import { n as readCreatedDevices$1, t as forgetCreatedDevice } from "./created-devices-DKbeWsiK.mjs";
|
|
11
|
+
import { A as listAvds, H as parseAvdSystemImage, I as ownedAvdDirectory, M as listOrphanedAvdDirectories, V as parseAvdDeviceProfile, _ as avdStorageRoots, at as isStimOwnedSim, d as androidToolPath, ft as parkedMaxSetting, it as isStimOwnedAvd, j as listInstalledSystemImages, m as avdNameAbsent, o as androidHome, ot as POOL_SETTING_REMEDY, p as avdIniPaths, pt as readParked } from "./android-DC3ZLuw0.mjs";
|
|
12
|
+
import { d as listAllIosSims } from "./ios-B3SbOWdw.mjs";
|
|
13
|
+
import { f as resolveEasCliBin } from "./remote-cache-BGg7aGIZ.mjs";
|
|
14
|
+
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$1, p as easMachineStateRoot$1, x as inspectSessionForTeardown, y as findOrphanedOwnedSessions } from "./device-remote-tHbd1fKy.mjs";
|
|
15
|
+
import { r as readCollectors } from "./ownership-D6Se7gg_.mjs";
|
|
16
|
+
import { c as worktreePullRequestNote, l as worktreeRemovalReason, n as previewMaintenance, o as collectWorktreeSweep, s as removeWorktrees } from "./preview-D5V07Nrl.mjs";
|
|
17
|
+
import { _ as deleteSelectedArchives, g as reclaimProject, h as describeDereferenced, v as sweepArchiveStaging } from "./worktree-BSYlofkq.mjs";
|
|
18
|
+
import { i as getSwiftpmCacheUsage, n as swiftpmCacheLines, r as getAgentDeviceUsage, t as agentDeviceLines } from "./agent-device-usage-output-CZ66YA4T.mjs";
|
|
25
19
|
import { existsSync, lstatSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
26
20
|
import { basename, dirname, join } from "node:path";
|
|
27
|
-
import { closeSync as closeSync$1, existsSync as existsSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readSync as readSync$1, readdirSync as readdirSync$1, renameSync as renameSync$1, rmSync as rmSync$1, statSync as statSync$1, utimesSync as utimesSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
28
21
|
import { basename as basename$1, dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1 } from "path";
|
|
29
|
-
import {
|
|
30
|
-
import { InvalidArgumentError } from "commander";
|
|
31
|
-
import { assertHostedDeviceLedger, deviceHostArea, deviceHostRoot, hostedDeviceId, isJsonObject, listRecordedDevices, listStatusCacheEntries, maintenanceRunClaims, parseHostedPlatformDevice, readArchives, readHostedDevice, readHostedDeviceLedger, readHostedSessions, recordedBytes, settingDefinition } from "@stim-cli/core/state";
|
|
22
|
+
import { assertHostedDeviceLedger, deviceHostArea, deviceHostRoot, hostedDeviceId, isJsonObject, listRecordedDevices, listStatusCacheEntries, maintenanceRunClaims, parseHostedPlatformDevice, readArchives, readHostedDevice, readHostedDeviceLedger, readHostedSessions, recordedBytes } from "@stim-cli/core/state";
|
|
32
23
|
import { fileURLToPath } from "node:url";
|
|
33
24
|
import chalk from "chalk";
|
|
25
|
+
import { closeSync as closeSync$1, existsSync as existsSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readSync as readSync$1, readdirSync as readdirSync$1, renameSync as renameSync$1, rmSync as rmSync$1, statSync as statSync$1, utimesSync as utimesSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
26
|
+
import { InvalidArgumentError } from "commander";
|
|
27
|
+
import { LOG_ROTATE_BYTES, rotatedLogPath } from "@stim-cli/core";
|
|
34
28
|
//#region src/commands/gc/archives.ts
|
|
35
29
|
function stagingOrNone() {
|
|
36
30
|
try {
|
|
@@ -534,446 +528,6 @@ async function deleteEasSessions(easSessionSweep, deps) {
|
|
|
534
528
|
return deleteFailures;
|
|
535
529
|
}
|
|
536
530
|
//#endregion
|
|
537
|
-
//#region src/commands/gc/worktrees.ts
|
|
538
|
-
const DEFAULT_WORKTREE_IDLE_DAYS = 7;
|
|
539
|
-
const DAY_MS$1 = 864e5;
|
|
540
|
-
const MINUTE_MS = 6e4;
|
|
541
|
-
const GRACE_SETTING = "gc.worktreeGraceMinutes";
|
|
542
|
-
const MERGE_DECIDES = /* @__PURE__ */ new Set([
|
|
543
|
-
"unpushed",
|
|
544
|
-
"not-merged",
|
|
545
|
-
"last-use-unknown",
|
|
546
|
-
"recently-used"
|
|
547
|
-
]);
|
|
548
|
-
function skip(code, text) {
|
|
549
|
-
return {
|
|
550
|
-
code,
|
|
551
|
-
text
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
function pullRequestNote(lookup) {
|
|
555
|
-
const pr = lookup && "pullRequest" in lookup ? lookup.pullRequest : null;
|
|
556
|
-
if (!pr) return null;
|
|
557
|
-
return pr.containsHead ? describePullRequest(pr) : `${describePullRequest(pr)}, and HEAD has commits it does not`;
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Why gc keeps a worktree, or null when it removes it. A worktree that would be removed is still kept while its last
|
|
561
|
-
* activity, or its merge into the default branch, is less than `grace.ms` old, and kept when that activity is unknown.
|
|
562
|
-
*/
|
|
563
|
-
function worktreeSkipReason(facts, olderThan, grace = {
|
|
564
|
-
ms: 0,
|
|
565
|
-
now: 0
|
|
566
|
-
}) {
|
|
567
|
-
return removalBlocker(facts, olderThan) ?? graceBlocker(facts, grace);
|
|
568
|
-
}
|
|
569
|
-
function graceBlocker(facts, grace) {
|
|
570
|
-
if (grace.ms <= 0) return null;
|
|
571
|
-
if (!facts.activity) return skip("activity-unknown", "its last activity could not be read");
|
|
572
|
-
const merged = facts.merge?.merged ? facts.merge : null;
|
|
573
|
-
const ended = endedPullRequest(facts.pullRequest);
|
|
574
|
-
const events = [facts.activity];
|
|
575
|
-
if (merged) events.push({
|
|
576
|
-
at: merged.mergedAt,
|
|
577
|
-
basis: `merged into ${merged.into}`
|
|
578
|
-
});
|
|
579
|
-
if (ended?.endedAt) events.push({
|
|
580
|
-
at: ended.endedAt,
|
|
581
|
-
basis: describePullRequest(ended)
|
|
582
|
-
});
|
|
583
|
-
const latest = events.reduce((a, b) => b.at > a.at ? b : a);
|
|
584
|
-
const eligibleAt = latest.at + grace.ms;
|
|
585
|
-
if (grace.now >= eligibleAt) return null;
|
|
586
|
-
const ago = formatLongDuration(Math.max(0, grace.now - latest.at));
|
|
587
|
-
return {
|
|
588
|
-
code: "recent-activity",
|
|
589
|
-
text: `recent activity: ${latest.basis} ${ago} ago; removable after ${new Date(eligibleAt).toISOString()}`,
|
|
590
|
-
eligibleAt
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
function removalBlocker(facts, olderThan) {
|
|
594
|
-
if (facts.bare) return skip("bare-repository", "bare repository");
|
|
595
|
-
if (typeof facts.source === "object") return skip("source-checkout-unknown", `source checkout unknown: ${facts.source.refusal}`);
|
|
596
|
-
if (facts.source === "source") return skip("source-checkout", "source checkout");
|
|
597
|
-
if (facts.locked) return skip("locked", "locked with git worktree lock");
|
|
598
|
-
if (facts.inUse.length) return skip("in-use", `in use: ${facts.inUse.join("; ")}`);
|
|
599
|
-
if (facts.porcelain === null) return skip("status-unreadable", "git status could not be read");
|
|
600
|
-
const dirty = excludePodChurn(excludeWatchmanCookies(facts.porcelain).lines).lines.length;
|
|
601
|
-
if (dirty) return skip("dirty", `dirty: ${plural(dirty, "uncommitted or untracked file")}`);
|
|
602
|
-
if (facts.unpushed === null) return skip("unpushed-unchecked", "unpushed commits could not be checked");
|
|
603
|
-
const merged = facts.merge?.merged ? facts.merge : null;
|
|
604
|
-
const ended = endedPullRequest(facts.pullRequest);
|
|
605
|
-
if (facts.unpushed.length && !merged?.coversUnpushed && ended?.state !== "merged") return skip("unpushed", `unpushed: ${plural(facts.unpushed.length, "commit")} on no remote or other branch`);
|
|
606
|
-
if (facts.submodules) return skip("submodules", "initialized submodules");
|
|
607
|
-
if (merged || ended) return null;
|
|
608
|
-
const notMerged = facts.merge && !facts.merge.merged ? facts.merge : null;
|
|
609
|
-
const details = [notMerged?.detail, pullRequestNote(facts.pullRequest)].filter(Boolean);
|
|
610
|
-
if (olderThan === null) return skip(notMerged?.unknown ? "merge-unknown" : "not-merged", details.join("; ") || "not merged");
|
|
611
|
-
const also = details.map((detail) => `; ${detail}`).join("");
|
|
612
|
-
if (facts.idleDays === null) return skip("last-use-unknown", `recently used: its last use is unknown${also}`);
|
|
613
|
-
if (facts.idleDays < olderThan) return skip("recently-used", `recently used ${facts.idleDays}d ago${also}`);
|
|
614
|
-
return null;
|
|
615
|
-
}
|
|
616
|
-
/** Why gc removes a worktree it did not skip: `merged into origin/main`, `PR #12 closed` or `idle 9d`. */
|
|
617
|
-
function worktreeRemovalReason(candidate) {
|
|
618
|
-
if (candidate.merge?.merged) return `merged into ${candidate.merge.into}`;
|
|
619
|
-
const ended = endedPullRequest(candidate.pullRequest);
|
|
620
|
-
return ended ? describePullRequest(ended) : `idle ${candidate.idleDays ?? 0}d`;
|
|
621
|
-
}
|
|
622
|
-
/** The pull request note a kept worktree's report line carries, such as `PR #12 merged`, or null. */
|
|
623
|
-
function worktreePullRequestNote(candidate) {
|
|
624
|
-
return pullRequestNote(candidate.pullRequest);
|
|
625
|
-
}
|
|
626
|
-
function lastUsedOf(keys) {
|
|
627
|
-
const times = keys.map(workspaceLastUsed).filter(Number.isFinite);
|
|
628
|
-
return times.length ? Math.max(...times) : NaN;
|
|
629
|
-
}
|
|
630
|
-
function idleDaysOf(keys, now) {
|
|
631
|
-
const last = lastUsedOf(keys);
|
|
632
|
-
return Number.isFinite(last) ? Math.max(0, Math.floor((now - last) / DAY_MS$1)) : null;
|
|
633
|
-
}
|
|
634
|
-
function deviceReads() {
|
|
635
|
-
let sims;
|
|
636
|
-
let resolver;
|
|
637
|
-
return {
|
|
638
|
-
sims: () => {
|
|
639
|
-
if (sims === void 0) try {
|
|
640
|
-
sims = listAllIosSims({ timeoutMs: DEVICE_LIST_TIMEOUT_MS });
|
|
641
|
-
} catch {
|
|
642
|
-
sims = null;
|
|
643
|
-
}
|
|
644
|
-
return sims;
|
|
645
|
-
},
|
|
646
|
-
avdSerial: (avdName) => (resolver ??= ownedAvdSerialResolver({ timeoutMs: DEVICE_LIST_TIMEOUT_MS }))(avdName)
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
function inUseOf(keys, checks, devices = deviceReads()) {
|
|
650
|
-
return [.../* @__PURE__ */ new Set([...keys.flatMap((key) => workspaceInUse(key, checks)), ...deviceUseOf(keys, devices)])];
|
|
651
|
-
}
|
|
652
|
-
function deviceUseOf(keys, devices) {
|
|
653
|
-
const reasons = [];
|
|
654
|
-
for (const key of keys) {
|
|
655
|
-
let slots;
|
|
656
|
-
try {
|
|
657
|
-
slots = projectDeviceSlots(getProject(key));
|
|
658
|
-
} catch (error) {
|
|
659
|
-
reasons.push(`its device records cannot be read: ${error.message}`);
|
|
660
|
-
continue;
|
|
661
|
-
}
|
|
662
|
-
for (const { platforms } of slots) {
|
|
663
|
-
const ios = platforms.ios;
|
|
664
|
-
if (ios?.owned && ios.deviceUdid) {
|
|
665
|
-
const sims = devices.sims();
|
|
666
|
-
const sim = sims?.find((entry) => entry.udid === ios.deviceUdid);
|
|
667
|
-
if (sims === null) reasons.push(`the state of its owned simulator ${ios.deviceUdid} cannot be read`);
|
|
668
|
-
else if (sim && sim.state !== "Shutdown") reasons.push(`its owned simulator ${sim.name} is ${sim.state}; \`stim stop\` in ${key} shuts it down`);
|
|
669
|
-
}
|
|
670
|
-
const android = platforms.android;
|
|
671
|
-
if (android?.owned && android.avdName) try {
|
|
672
|
-
if (devices.avdSerial(android.avdName).serial) reasons.push(`its owned emulator ${android.avdName} is running; \`stim stop\` in ${key} shuts it down`);
|
|
673
|
-
} catch {
|
|
674
|
-
reasons.push(`the state of its owned emulator ${android.avdName} cannot be read`);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
const holders = new Set(keys.map(canonicalPath));
|
|
679
|
-
const now = Date.now();
|
|
680
|
-
for (const { lease } of listLeaseFiles()) if (lease && !leaseIsExpired(lease, now) && holders.has(canonicalPath(lease.holder))) reasons.push(`it holds the ${lease.platform} device lease on ${lease.deviceName ?? lease.id}`);
|
|
681
|
-
return reasons;
|
|
682
|
-
}
|
|
683
|
-
function newestMtime(paths) {
|
|
684
|
-
let newest = null;
|
|
685
|
-
for (const { path, basis } of paths) {
|
|
686
|
-
let mtime;
|
|
687
|
-
try {
|
|
688
|
-
mtime = statSync$1(path).mtimeMs;
|
|
689
|
-
} catch (error) {
|
|
690
|
-
if (error.code === "ENOENT") continue;
|
|
691
|
-
return "unreadable";
|
|
692
|
-
}
|
|
693
|
-
if (!newest || mtime > newest.at) newest = {
|
|
694
|
-
at: mtime,
|
|
695
|
-
basis
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
|
-
return newest;
|
|
699
|
-
}
|
|
700
|
-
function logFiles$1(key) {
|
|
701
|
-
const dir = workspaceLogsDir$1(key);
|
|
702
|
-
try {
|
|
703
|
-
return readdirSync$1(dir).map((name) => ({
|
|
704
|
-
path: join$1(dir, name),
|
|
705
|
-
basis: "a Stim log write"
|
|
706
|
-
}));
|
|
707
|
-
} catch (error) {
|
|
708
|
-
return error.code === "ENOENT" ? [] : null;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
function worktreeActivityOf(path, keys) {
|
|
712
|
-
const gitDir = getExecutor().runFileQuiet("git", [
|
|
713
|
-
"--no-optional-locks",
|
|
714
|
-
"-C",
|
|
715
|
-
path,
|
|
716
|
-
"rev-parse",
|
|
717
|
-
"--path-format=absolute",
|
|
718
|
-
"--git-dir"
|
|
719
|
-
])?.trim();
|
|
720
|
-
if (!gitDir) return null;
|
|
721
|
-
const paths = [
|
|
722
|
-
{
|
|
723
|
-
path: join$1(gitDir, "index"),
|
|
724
|
-
basis: "a git index write"
|
|
725
|
-
},
|
|
726
|
-
{
|
|
727
|
-
path: join$1(gitDir, "HEAD"),
|
|
728
|
-
basis: "a git HEAD change"
|
|
729
|
-
},
|
|
730
|
-
{
|
|
731
|
-
path: join$1(gitDir, "logs", "HEAD"),
|
|
732
|
-
basis: "a git reflog entry"
|
|
733
|
-
}
|
|
734
|
-
];
|
|
735
|
-
for (const key of keys) {
|
|
736
|
-
const logs = logFiles$1(key);
|
|
737
|
-
if (logs === null) return null;
|
|
738
|
-
paths.push({
|
|
739
|
-
path: workspaceStateFile(key),
|
|
740
|
-
basis: "a Stim workspace state write"
|
|
741
|
-
}, ...logs);
|
|
742
|
-
}
|
|
743
|
-
const newest = newestMtime(paths);
|
|
744
|
-
return newest === "unreadable" ? null : newest;
|
|
745
|
-
}
|
|
746
|
-
function graceMsSetting() {
|
|
747
|
-
const { value, error } = machineNumber(GRACE_SETTING, loadConfig$1(), process.env);
|
|
748
|
-
if (error) {
|
|
749
|
-
const fallback = Number(settingDefinition(GRACE_SETTING)?.default);
|
|
750
|
-
console.error(chalk.yellow(`${error} gc uses the default of ${fallback} minutes.`));
|
|
751
|
-
return fallback * MINUTE_MS;
|
|
752
|
-
}
|
|
753
|
-
return (value ?? 0) * MINUTE_MS;
|
|
754
|
-
}
|
|
755
|
-
function porcelainOf(path, gitAnswered) {
|
|
756
|
-
if (gitAnswered === null) return null;
|
|
757
|
-
if (!gitAnswered) return [];
|
|
758
|
-
const lines = dirtyPaths(path, { limit: Infinity });
|
|
759
|
-
return lines.length ? lines : null;
|
|
760
|
-
}
|
|
761
|
-
function candidateRoots() {
|
|
762
|
-
const registered = Object.keys(loadConfig$1()?.projects ?? {}).filter(isAbsolute$1);
|
|
763
|
-
const recorded = listWorkspaceDirs().flatMap((entry) => entry.projectRoot ? [entry.projectRoot] : []);
|
|
764
|
-
return [.../* @__PURE__ */ new Set([...registered, ...recorded])].filter((root) => existsSync$1(root)).toSorted();
|
|
765
|
-
}
|
|
766
|
-
function checkMergeStates(pending, idle, grace) {
|
|
767
|
-
const repos = /* @__PURE__ */ new Map();
|
|
768
|
-
for (const entry of pending) repos.set(entry.repo, [...repos.get(entry.repo) ?? [], entry]);
|
|
769
|
-
for (const [repo, entries] of repos) {
|
|
770
|
-
const target = fetchDefaultBranch(repo, grace.now);
|
|
771
|
-
for (const { candidate, facts } of entries) {
|
|
772
|
-
const merge = "error" in target ? {
|
|
773
|
-
merged: false,
|
|
774
|
-
unknown: true,
|
|
775
|
-
detail: `merge state unknown: ${target.error}`
|
|
776
|
-
} : mergeState(candidate.path, target);
|
|
777
|
-
const verdict = worktreeSkipReason({
|
|
778
|
-
...facts,
|
|
779
|
-
merge
|
|
780
|
-
}, idle, grace);
|
|
781
|
-
Object.assign(candidate, {
|
|
782
|
-
merge,
|
|
783
|
-
skipCode: verdict?.code ?? null,
|
|
784
|
-
skipped: verdict?.text ?? null,
|
|
785
|
-
eligibleAt: verdict?.eligibleAt ?? null
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Classifies each Stim-managed linked worktree. A merged one is removable; with `idle`, so is one unused for
|
|
792
|
-
* `olderThan` days. Device use is read last, in one pass against one simulator list and one AVD resolver, so
|
|
793
|
-
* the resolver's time budget covers only device reads. Pull requests are asked once per repository, all
|
|
794
|
-
* repositories at once. Merge state is checked only where it decides the verdict, after one fetch per repository.
|
|
795
|
-
*/
|
|
796
|
-
async function collectWorktreeSweep({ idle, olderThan, now }) {
|
|
797
|
-
const days = idle ? olderThan ?? DEFAULT_WORKTREE_IDLE_DAYS : null;
|
|
798
|
-
const grace = {
|
|
799
|
-
ms: graceMsSetting(),
|
|
800
|
-
now
|
|
801
|
-
};
|
|
802
|
-
const groups = /* @__PURE__ */ new Map();
|
|
803
|
-
const outside = [];
|
|
804
|
-
const candidates = candidateRoots();
|
|
805
|
-
if (candidates.length) phase("worktrees", `checking ${plural(candidates.length, "project")} for merged or idle worktrees`);
|
|
806
|
-
for (const root of candidates) {
|
|
807
|
-
const entry = matchWorktreeEntry(listWorktrees(root), root);
|
|
808
|
-
if (!entry) {
|
|
809
|
-
outside.push({
|
|
810
|
-
path: root,
|
|
811
|
-
keys: [root],
|
|
812
|
-
idleDays: null,
|
|
813
|
-
merge: null,
|
|
814
|
-
head: null,
|
|
815
|
-
pullRequest: null,
|
|
816
|
-
skipCode: "not-a-worktree",
|
|
817
|
-
skipped: "not inside a git worktree",
|
|
818
|
-
eligibleAt: null
|
|
819
|
-
});
|
|
820
|
-
continue;
|
|
821
|
-
}
|
|
822
|
-
groups.set(entry.path, [...groups.get(entry.path) ?? [], root]);
|
|
823
|
-
}
|
|
824
|
-
const inspected = [];
|
|
825
|
-
for (const [path, roots] of groups) {
|
|
826
|
-
const entries = listWorktrees(path);
|
|
827
|
-
const entry = matchWorktreeEntry(entries, path);
|
|
828
|
-
const source = sourceCheckoutOf(entries);
|
|
829
|
-
const keys = [.../* @__PURE__ */ new Set([...roots, ...reclaimKeys(path)])];
|
|
830
|
-
const idleDays = idleDaysOf(keys, now);
|
|
831
|
-
const linked = !("refusal" in source) && entry !== null && source.path !== entry.path;
|
|
832
|
-
const activity = linked && grace.ms > 0 ? worktreeActivityOf(path, keys) : null;
|
|
833
|
-
const gitAnswered = linked ? hasUncommittedWork(path) : null;
|
|
834
|
-
const head = linked ? resolveFullRef(path, "HEAD") : null;
|
|
835
|
-
const facts = {
|
|
836
|
-
source: "refusal" in source ? source : linked ? "linked" : "source",
|
|
837
|
-
bare: Boolean(entry?.bare),
|
|
838
|
-
locked: Boolean(entry?.locked),
|
|
839
|
-
porcelain: porcelainOf(path, gitAnswered),
|
|
840
|
-
unpushed: linked ? unpushedCommits(path) : null,
|
|
841
|
-
submodules: linked && hasPopulatedSubmodules(path),
|
|
842
|
-
inUse: [],
|
|
843
|
-
idleDays,
|
|
844
|
-
merge: null,
|
|
845
|
-
pullRequest: null,
|
|
846
|
-
activity
|
|
847
|
-
};
|
|
848
|
-
inspected.push({
|
|
849
|
-
candidate: {
|
|
850
|
-
path,
|
|
851
|
-
keys,
|
|
852
|
-
idleDays,
|
|
853
|
-
merge: null,
|
|
854
|
-
head,
|
|
855
|
-
pullRequest: null,
|
|
856
|
-
skipCode: null,
|
|
857
|
-
skipped: null,
|
|
858
|
-
eligibleAt: null
|
|
859
|
-
},
|
|
860
|
-
facts,
|
|
861
|
-
repo: "refusal" in source ? null : source.path,
|
|
862
|
-
branch: head && entry?.branch ? entry.branch : null
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
const linked = inspected.filter(({ facts }) => facts.source === "linked");
|
|
866
|
-
for (const { candidate, facts } of linked) facts.inUse = candidate.keys.flatMap((key) => workspaceInUse(key, { managedLocks: true }));
|
|
867
|
-
const devices = deviceReads();
|
|
868
|
-
for (const { candidate, facts } of linked) facts.inUse = [.../* @__PURE__ */ new Set([...facts.inUse, ...deviceUseOf(candidate.keys, devices)])];
|
|
869
|
-
await lookUpPullRequests(inspected);
|
|
870
|
-
const worktrees = [];
|
|
871
|
-
const pending = [];
|
|
872
|
-
for (const { candidate, facts, repo } of inspected) {
|
|
873
|
-
const verdict = worktreeSkipReason(facts, days, grace);
|
|
874
|
-
Object.assign(candidate, {
|
|
875
|
-
pullRequest: facts.pullRequest,
|
|
876
|
-
skipCode: verdict?.code ?? null,
|
|
877
|
-
skipped: verdict?.text ?? null,
|
|
878
|
-
eligibleAt: verdict?.eligibleAt ?? null
|
|
879
|
-
});
|
|
880
|
-
if (verdict && MERGE_DECIDES.has(verdict.code) && repo !== null) pending.push({
|
|
881
|
-
candidate,
|
|
882
|
-
facts,
|
|
883
|
-
repo
|
|
884
|
-
});
|
|
885
|
-
worktrees.push(candidate);
|
|
886
|
-
}
|
|
887
|
-
checkMergeStates(pending, days, grace);
|
|
888
|
-
const listed = [...worktrees, ...outside].filter((w) => idle || w.skipCode !== "not-a-worktree" && w.skipCode !== "source-checkout");
|
|
889
|
-
return {
|
|
890
|
-
idle: days === null ? null : {
|
|
891
|
-
olderThan: days,
|
|
892
|
-
defaulted: olderThan === null
|
|
893
|
-
},
|
|
894
|
-
graceMs: grace.ms,
|
|
895
|
-
worktrees: listed
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
async function lookUpPullRequests(inspected) {
|
|
899
|
-
const repos = /* @__PURE__ */ new Map();
|
|
900
|
-
for (const { candidate, facts, repo, branch } of inspected) {
|
|
901
|
-
if (repo === null || branch === null || candidate.head === null) continue;
|
|
902
|
-
const query = {
|
|
903
|
-
cwd: candidate.path,
|
|
904
|
-
branch,
|
|
905
|
-
head: candidate.head
|
|
906
|
-
};
|
|
907
|
-
repos.set(repo, [...repos.get(repo) ?? [], {
|
|
908
|
-
facts,
|
|
909
|
-
query
|
|
910
|
-
}]);
|
|
911
|
-
}
|
|
912
|
-
const lookup = pullRequestLookups();
|
|
913
|
-
await Promise.all([...repos].map(async ([repo, entries]) => {
|
|
914
|
-
const answers = await lookup(repo, entries.map(({ query }) => query));
|
|
915
|
-
entries.forEach(({ facts }, i) => facts.pullRequest = answers[i] ?? null);
|
|
916
|
-
}));
|
|
917
|
-
}
|
|
918
|
-
async function removeWorktrees(sweep, { now = Date.now() } = {}) {
|
|
919
|
-
let failures = 0;
|
|
920
|
-
for (const candidate of sweep.worktrees) {
|
|
921
|
-
if (candidate.skipped) continue;
|
|
922
|
-
let kept = [];
|
|
923
|
-
const guard = (lockedKeys) => {
|
|
924
|
-
const keys = [.../* @__PURE__ */ new Set([...candidate.keys, ...lockedKeys])];
|
|
925
|
-
const unlocked = keys.filter((key) => !lockedKeys.includes(key));
|
|
926
|
-
const reasons = [...inUseOf(lockedKeys, { managedLocks: false }), ...inUseOf(unlocked, { managedLocks: true })].map((r) => `in use: ${r}`);
|
|
927
|
-
const mergedHead = candidate.merge?.merged ? candidate.merge.head : endedPullRequest(candidate.pullRequest) ? candidate.head : null;
|
|
928
|
-
if (mergedHead) {
|
|
929
|
-
if (resolveFullRef(candidate.path, "HEAD") !== mergedHead) reasons.push("its HEAD moved since gc checked it");
|
|
930
|
-
} else {
|
|
931
|
-
const idleDays = idleDaysOf(keys, now);
|
|
932
|
-
if (idleDays === null || !sweep.idle || idleDays < sweep.idle.olderThan) reasons.push(`used ${idleDays === null ? "at an unknown time" : `${idleDays}d ago`} since gc checked it`);
|
|
933
|
-
}
|
|
934
|
-
if (sweep.graceMs > 0) {
|
|
935
|
-
const recent = graceBlocker({
|
|
936
|
-
merge: candidate.merge,
|
|
937
|
-
pullRequest: candidate.pullRequest,
|
|
938
|
-
activity: worktreeActivityOf(candidate.path, keys)
|
|
939
|
-
}, {
|
|
940
|
-
ms: sweep.graceMs,
|
|
941
|
-
now: Date.now()
|
|
942
|
-
});
|
|
943
|
-
if (recent) reasons.push(recent.text);
|
|
944
|
-
}
|
|
945
|
-
kept = reasons;
|
|
946
|
-
return reasons;
|
|
947
|
-
};
|
|
948
|
-
let removed = false;
|
|
949
|
-
let error = null;
|
|
950
|
-
try {
|
|
951
|
-
const ended = endedPullRequest(candidate.pullRequest);
|
|
952
|
-
const mergedHead = candidate.merge?.merged && candidate.merge.coversUnpushed ? candidate.merge.head : ended?.state === "merged" ? candidate.head ?? void 0 : void 0;
|
|
953
|
-
removed = await removeWorktreeTarget(candidate.path, {
|
|
954
|
-
linkedOnly: true,
|
|
955
|
-
guard,
|
|
956
|
-
mergedHead
|
|
957
|
-
});
|
|
958
|
-
} catch (thrown) {
|
|
959
|
-
error = thrown?.message || String(thrown);
|
|
960
|
-
console.error(chalk.red(`Could not remove ${candidate.path}: ${error}`));
|
|
961
|
-
}
|
|
962
|
-
if (removed) {
|
|
963
|
-
console.log(chalk.green(`Removed the worktree ${candidate.path} (${worktreeRemovalReason(candidate)})`));
|
|
964
|
-
recordGcResult("worktree", "done", candidate.path, { detail: worktreeRemovalReason(candidate) });
|
|
965
|
-
} else if (kept.length) {
|
|
966
|
-
console.log(chalk.yellow(`Kept the worktree ${candidate.path}: ${kept.join("; ")}`));
|
|
967
|
-
recordGcResult("worktree", "kept", candidate.path, { detail: kept.join("; ") });
|
|
968
|
-
} else {
|
|
969
|
-
failures++;
|
|
970
|
-
console.error(chalk.yellow(`Kept the worktree ${candidate.path}; see the lines above for why.`));
|
|
971
|
-
recordGcResult("worktree", "failed", candidate.path, { detail: error ?? "stim worktree remove did not remove it; see the details" });
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
return failures;
|
|
975
|
-
}
|
|
976
|
-
//#endregion
|
|
977
531
|
//#region src/commands/gc/status-caches.ts
|
|
978
532
|
const KINDS = ["disk-usage", "pull-request"];
|
|
979
533
|
const KEPT_REASON = {
|
|
@@ -1245,7 +799,7 @@ function scopeLine(cacheScope) {
|
|
|
1245
799
|
function maintenanceReportLines(maintenance) {
|
|
1246
800
|
const lines = [];
|
|
1247
801
|
if (maintenance) {
|
|
1248
|
-
lines.push(`Automatic maintenance (${maintenance.mode === "report" ? "report only" :
|
|
802
|
+
lines.push(`Automatic maintenance (${maintenance.mode === "report" ? "report only" : maintenance.mode}):`);
|
|
1249
803
|
if (maintenance.note) lines.push(` ${maintenance.note}`);
|
|
1250
804
|
for (const action of maintenance.actions) lines.push(` ${action.kind}: ${action.target} (${formatBytes(action.bytes)}): ${action.reason}`);
|
|
1251
805
|
for (const skip of maintenance.skips) lines.push(` kept ${skip.target}: ${skip.reason}`);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
1
|
+
import { t as getExecutor } from "./exec-DWhCZDGm.mjs";
|
|
2
2
|
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
|
|
3
|
-
import { l as phaseLine } from "./command-output-
|
|
4
|
-
import { a as spawnDeclared } from "./spawn-claims-
|
|
5
|
-
import { o as androidHome } from "./android-
|
|
6
|
-
import {
|
|
7
|
-
import { createHash } from "node:crypto";
|
|
3
|
+
import { l as phaseLine } from "./command-output-CBtzyIgF.mjs";
|
|
4
|
+
import { a as spawnDeclared } from "./spawn-claims-Kqiifsk2.mjs";
|
|
5
|
+
import { o as androidHome } from "./android-DC3ZLuw0.mjs";
|
|
6
|
+
import { P as readCcacheActivity, T as startBuildHeartbeat, g as HEARTBEAT_INTERVAL_MS, j as CCACHE_UNAVAILABLE } from "./toolchain-Bnyd_K3A.mjs";
|
|
8
7
|
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
9
8
|
import { dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
10
9
|
import { fileURLToPath } from "node:url";
|
|
11
10
|
import chalk from "chalk";
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
12
|
/** The ABI name a build for every ABI has to fit; `stim android` narrows a build to the device's. */
|
|
13
13
|
const LONGEST_ANDROID_ABI = "armeabi-v7a";
|
|
14
14
|
function androidPathRoom(root, { abi = null, variant = null, platform = process.platform } = {}) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { E as upsertProject, d as getConfigDir, p as getProject } from "./config-
|
|
2
|
-
import { n as appProjectProblem } from "./project-
|
|
3
|
-
import { t as compareStimVersions } from "./stim-installations-
|
|
1
|
+
import { E as upsertProject, d as getConfigDir, p as getProject } from "./config-CgYMahz7.mjs";
|
|
2
|
+
import { n as appProjectProblem } from "./project-C3ChRLZy.mjs";
|
|
3
|
+
import { t as compareStimVersions } from "./stim-installations-aR_WsNOA.mjs";
|
|
4
4
|
import { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
//#region src/guide-status.ts
|