stim 1.26.0 → 1.28.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/{acquire-artifact-DVsvSwf7.mjs → acquire-artifact-CKByBnTD.mjs} +2 -2
- package/dist/{act-C-BqJEpu.mjs → act-8iswyfRa.mjs} +319 -126
- package/dist/{activity-Lnb_EoRY.mjs → activity-DRMg4_mD.mjs} +6 -6
- package/dist/{agent-device-usage-output-DbXy5tg8.mjs → agent-device-usage-output-tE90fDdo.mjs} +5 -5
- package/dist/{android-CiNQw3kq.mjs → android-CHmSU4B4.mjs} +101 -45
- package/dist/{android-DTAcRwBC.mjs → android-CsPs-7Mg.mjs} +23 -18
- package/dist/{android-B5P81yI-.mjs → android-D577ApKG.mjs} +37 -15
- package/dist/{android-CSbLRD53.mjs → android-YWCbmkVK.mjs} +5 -5
- package/dist/{android-cas-BTVhZ0Qs.mjs → android-cas-_aDifWW0.mjs} +4 -4
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/api.d.mts +14 -4
- package/dist/api.mjs +39 -29
- package/dist/{apk-signed-tail-B46U9hXc.mjs → apk-signed-tail-CQbwM0qO.mjs} +2 -2
- package/dist/{artifact-CsAP6AGK.mjs → artifact-DYtHjxsn.mjs} +19 -24
- package/dist/{artifact-BxREhAaV.mjs → artifact-bFkfD3vf.mjs} +18 -23
- package/dist/{artifact-platform-CMRc0M_r.mjs → artifact-platform-BO2Uvk_A.mjs} +1 -1
- package/dist/auto-placement-BVqs8AJi.mjs +350 -0
- package/dist/{browser-web-rYPyqhTf.mjs → browser-web-BUaLcafY.mjs} +16 -16
- package/dist/{build-DPhApsjV.mjs → build-cQURy_KW.mjs} +35 -31
- package/dist/{build-cache-DrXNCy3T.mjs → build-cache-CZULpXVl.mjs} +43 -21
- package/dist/{build-plan-DrMMdayj.mjs → build-plan-CxoYfxsc.mjs} +7 -6
- package/dist/{cache-manifest-BEZ9Bpl1.mjs → cache-manifest-DEjqGGat.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{budget-k2mZGvvk.mjs → ccache-Bm_A1xX9.mjs} +562 -1604
- package/dist/{cdp-BG3FJCCx.mjs → cdp-C3svvXiE.mjs} +1 -1
- package/dist/{chrome-BvV8ssI3.mjs → chrome-DyDWurWG.mjs} +1 -1
- package/dist/{cli-BBKFGOFl.mjs → cli-CpbaLDa7.mjs} +24 -23
- package/dist/cli.mjs +1 -1
- package/dist/{client-D9CaRks-.mjs → client-YxCer6ab.mjs} +84 -65
- package/dist/collector-run.d.mts +10 -9
- package/dist/collector-run.mjs +42 -27
- package/dist/{command-output-BF5AR2dL.mjs → command-output-C8R1KIvi.mjs} +1 -1
- package/dist/{config-BktkY_zC.mjs → config-Cn94Jc0g.mjs} +23 -4
- package/dist/{dependencies-Dw6wfQdv.mjs → dependencies-DKeMzwXY.mjs} +108 -60
- package/dist/{dependency-state-DFB41vfr.mjs → dependency-state-CojA2o0t.mjs} +14 -7
- package/dist/{detached-entry-KmieOKgN.mjs → detached-entry-BPlSaCwC.mjs} +1 -1
- package/dist/{dev-client-DXR_tPVY.mjs → dev-client-D-BW5uiq.mjs} +2 -2
- package/dist/{device-BK-zwyd_.mjs → device-CgXfbcz5.mjs} +25 -24
- package/dist/{device-capacity-DCSvUF0l.mjs → device-capacity-Cd8lMSn3.mjs} +175 -22
- package/dist/{device-BcYeHSFu.mjs → device-eeK95Lir.mjs} +16 -16
- package/dist/device-host-worker.mjs +22 -20
- package/dist/{device-ios-BLGfXQeK.mjs → device-ios-Cc9ulihb.mjs} +251 -23
- package/dist/{device-lease-run-BmvIl7bI.mjs → device-lease-run-Mtzp4THX.mjs} +5 -5
- package/dist/{device-pool-Dluix4H3.mjs → device-pool-eRz6DtCg.mjs} +3 -3
- package/dist/{doctor-Bhg1ii70.mjs → doctor-Bz_ouYAW.mjs} +28 -16
- package/dist/{doctor-Cp-BhzTS.mjs → doctor-C2QyhejJ.mjs} +1 -1
- package/dist/{doctor-fingerprint-D3a04Mhu.mjs → doctor-fingerprint-o7ZI9YLn.mjs} +1 -1
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-watchman-BStK05nt.mjs → doctor-watchman-BTW82PDC.mjs} +5 -5
- package/dist/{doctor-OnwP94ne.mjs → doctor-xf7ht-5n.mjs} +76 -32
- package/dist/{eas-build-Dsj93iM9.mjs → eas-build-Dm6q68QY.mjs} +4 -4
- package/dist/eas-fallback-DajNpxf-.mjs +87 -0
- package/dist/{eas-session-ledger-B5vygTiD.mjs → eas-session-ledger-CBFo_Uo1.mjs} +37 -8
- package/dist/{error-diagnostics-BOOm9Db7.mjs → error-diagnostics-D1QfyJzQ.mjs} +51 -25
- package/dist/{exec-VFRpu1iA.mjs → exec-aULwtNly.mjs} +57 -6
- package/dist/{gc-ldgr-hXU.mjs → gc-DM5oMm-J.mjs} +161 -45
- package/dist/{gc-C_79zvz4.mjs → gc-PLFwb0k4.mjs} +2 -2
- package/dist/{guide-D7K0X6KG.mjs → guide-C4I46XAk.mjs} +674 -213
- package/dist/{hosted-android-Bk54ej6n.mjs → hosted-android-DlaKLbW0.mjs} +6 -7
- package/dist/{hosted-client-fHO8yqzc.mjs → hosted-client-DDRm9hPJ.mjs} +51 -20
- package/dist/{hosted-logs-BfbmDM4M.mjs → hosted-logs-bSebOKbz.mjs} +8 -8
- package/dist/{hosted-logs-sync-B0pvmOk-.mjs → hosted-logs-sync-B0c53W_c.mjs} +5 -5
- package/dist/{hosted-macos-CPl0OZ9h.mjs → hosted-macos-B7-8Pv4H.mjs} +6 -6
- package/dist/{hosted-native-CpDB3-PO.mjs → hosted-native-CDe33CSr.mjs} +22 -18
- package/dist/{idle-shutdown-FfxL1KdG.mjs → idle-shutdown-CQ0QwU9J.mjs} +7 -8
- package/dist/{ios-WxpDJ5T1.mjs → ios-B1DYuOjh.mjs} +27 -11
- package/dist/{ios-B7-lToDu.mjs → ios-B1HvafEG.mjs} +8 -8
- package/dist/{ios-ENC4sRPA.mjs → ios-CsRVik64.mjs} +7 -1
- package/dist/{ios-device-CsyryvpT.mjs → ios-device-B4elVFKi.mjs} +3 -3
- package/dist/{ios-device-B6HK951C.mjs → ios-device-CiBA-er9.mjs} +1 -1
- package/dist/{ios-project-Ty5pHl9O.mjs → ios-project-CR4mZ7CH.mjs} +22 -9
- package/dist/{ios-signing-4c_qXvQm.mjs → ios-signing-BJzvDPfU.mjs} +2 -2
- package/dist/{ios-state-Cw7-WQf2.mjs → ios-state-BPHqMDdZ.mjs} +1 -1
- package/dist/{ios-ftxdQbJS.mjs → ios-tg4tp3q1.mjs} +94 -37
- package/dist/{js-swap-BMhXYVDS.mjs → js-swap-CVpSW1fn.mjs} +8 -7
- package/dist/{launch-DOp8RjDz.mjs → launch-DoySmhjz.mjs} +42 -38
- package/dist/lightened-DFAJgfIk.mjs +171 -0
- package/dist/{logs-s1dRIG1E.mjs → logs-BGsW7iPe.mjs} +46 -21
- package/dist/{logs-dQDki6Tt.mjs → logs-DI5ILkYB.mjs} +7 -7
- package/dist/{macos-DBBPNnIA.mjs → macos-Bo9st9Di.mjs} +73 -38
- package/dist/{macos-B0VEV3Gf.mjs → macos-C12RMJQF.mjs} +1 -1
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +7 -7
- package/dist/{metro-CjC10t6E.mjs → metro-BnhXV2Mj.mjs} +4 -4
- package/dist/{metro-gateway-B6_PgD0L.mjs → metro-request-DXyKjVDF.mjs} +26 -47
- package/dist/{named-ports-BG0j1X4g.mjs → named-ports-Phoi2POD.mjs} +3 -3
- package/dist/{native-android-CL2NGiik.mjs → native-android-vxgtLD7w.mjs} +17 -18
- package/dist/{native-gradle-artifact-inputs-btSUulme.mjs → native-gradle-artifact-inputs-BN96IVw8.mjs} +5 -5
- package/dist/{native-runtime-Dq3RBcON.mjs → native-runtime-DG4Rodzj.mjs} +9 -8
- package/dist/{native-source-D-4Dh4JU.mjs → native-source-D1AzWiuP.mjs} +1 -1
- package/dist/{native-xcode-inputs-BW7H8JGu.mjs → native-xcode-inputs-BKarCoKg.mjs} +3 -3
- package/dist/{native-xcode-ios-CBXJAxfC.mjs → native-xcode-ios-8A-efGa5.mjs} +17 -17
- package/dist/{ndjson-CgE_o3Dl.mjs → ndjson-Dy2W4vRa.mjs} +2 -2
- package/dist/offload-worker.mjs +23 -24
- package/dist/{operation-exec-CUZifp6Z.mjs → operation-exec-Dp4FuIGR.mjs} +1 -1
- package/dist/{ownership-BjYvMNX_.mjs → ownership-DJCq48IJ.mjs} +3 -3
- package/dist/{page-CzEA_-5_.mjs → page-CQJlcj3x.mjs} +2 -2
- package/dist/{phone-reverses-lmj6kcPm.mjs → phone-reverses-BzTa8g1F.mjs} +18 -4
- package/dist/{placement-log-DIFPQAXp.mjs → placement-log-Cvhta5ib.mjs} +3 -3
- package/dist/{plan-placement-IiiSQhtz.mjs → plan-placement-WkZdccuN.mjs} +36 -10
- package/dist/{ports-C2_w1Z0Z.mjs → ports-UV4mJgyC.mjs} +3 -3
- package/dist/{prebuild-gmouvmJZ.mjs → prebuild-k8d_tqOq.mjs} +16 -17
- package/dist/{project-BUu6Is4k.mjs → project-Sui52ywT.mjs} +17 -17
- package/dist/{pull-request-CbNlkFok.mjs → pull-request-BzLmzAIQ.mjs} +2 -2
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-Cgg99REN.mjs → react-native-android-DANlGGQf.mjs} +32 -26
- package/dist/{react-native-build-oNwqF5Wb.mjs → react-native-build-jUHnIfZ9.mjs} +9 -9
- package/dist/{react-native-doctor-BhA3KUte.mjs → react-native-doctor-DCWRjS7K.mjs} +6 -6
- package/dist/{react-native-ios-B-nf4rjN.mjs → react-native-ios-BwMsFMXi.mjs} +23 -17
- package/dist/{recordings-BldzVKq0.mjs → recordings-iy0mkm7b.mjs} +1 -1
- package/dist/{registration-CN6nlhcD.mjs → registration-BwCe64PH.mjs} +1 -1
- package/dist/{reload-C9OduiNc.mjs → reload-Bj7QyuDy.mjs} +1 -1
- package/dist/{reload-CCR7KC_l.mjs → reload-c_uEyc_X.mjs} +16 -16
- package/dist/{remote-C8S7FlPF.mjs → remote-DFlpAqdV.mjs} +23 -10
- package/dist/{result-7F5hEwQJ.mjs → result-BIcXREyC.mjs} +32 -21
- package/dist/{run-BqB0v3pt.mjs → run-y2HwyNvg.mjs} +3 -3
- package/dist/{selection-BNPBZ6T5.mjs → selection-CXgM_VK_.mjs} +37 -29
- package/dist/{server-bare-A75rDIdD.mjs → server-bare-2N4vSRZG.mjs} +2 -2
- package/dist/{server-command-CssKFOD7.mjs → server-command-qneHPcRI.mjs} +6 -6
- package/dist/{server-expo-eQfOdydb.mjs → server-expo-Ccm9zB0o.mjs} +4 -4
- package/dist/server-expo-WulkyAwT.mjs +2 -0
- package/dist/{settings-CosW5X-S.mjs → settings-CY5JZlNN.mjs} +375 -62
- package/dist/{settings-OaGQF-ri.mjs → settings-Cfd_Q6ys.mjs} +24 -3
- package/dist/settings-payload-DwQiEMCn.mjs +257 -0
- package/dist/settings-write-CJpjkeAd.mjs +185 -0
- package/dist/settings.schema.json +51 -33
- package/dist/{simslim-Bax1qcxu.mjs → simslim-DCQwzoPy.mjs} +2 -2
- package/dist/{slot-launch-CYCEhfBY.mjs → slot-launch-BpmanOnk.mjs} +6 -6
- package/dist/{stage-jKQ7CP_B.mjs → stage-CmugrSG5.mjs} +2 -2
- package/dist/{start-C_wefNKB.mjs → start-CHH3zgIU.mjs} +1 -1
- package/dist/{start-_BdJ32cZ.mjs → start-DYLk6GXn.mjs} +27 -22
- package/dist/{state-C1i2nMOP.mjs → state-B2QJbDwz.mjs} +4 -4
- package/dist/{state-C4OdpOTF.mjs → state-BXC1Lfxw.mjs} +2 -2
- package/dist/{stats-tEpEEH-u.mjs → stats-DxKqhcGp.mjs} +5 -5
- package/dist/{stats-report-n2U5plhk.mjs → stats-report-B86Cv7Uc.mjs} +1 -1
- package/dist/{status-CRXz-Gtj.mjs → status-7ULDEJ1e.mjs} +1 -1
- package/dist/{status-DQrqodLj.mjs → status-BHCkOZga.mjs} +51 -28
- package/dist/{status-B9M7x4CZ.mjs → status-D_Ljc89p.mjs} +1 -1
- package/dist/{status-watch-B5wDIH_o.mjs → status-watch-BmsPqYSU.mjs} +18 -7
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-6Dqp-gjX.mjs → stim-desktop-CbWo21kb.mjs} +2 -2
- package/dist/{stop-DRqQVqDJ.mjs → stop-D-dGE9gh.mjs} +21 -20
- package/dist/{stop-ySNQHXMG.mjs → stop-DQvE-P76.mjs} +10 -6
- package/dist/{stop-CmdNhGlC.mjs → stop-b2pouxAO.mjs} +2 -2
- package/dist/supervisor-run.mjs +237 -63
- package/dist/{support-BGSCBoib.mjs → support-04IhBUTT.mjs} +6 -6
- package/dist/{support-CVOCp0Ft.mjs → support-BtlJKjyQ.mjs} +12 -11
- package/dist/{swiftpm-artifact-inputs-CfUzt_0Z.mjs → swiftpm-artifact-inputs-Cj2UpmPN.mjs} +4 -4
- package/dist/{swiftpm-macos-x6HPpl_2.mjs → swiftpm-macos-BhF2stxY.mjs} +11 -12
- package/dist/{toolchain-J4J8MrAr.mjs → toolchain-mLA_km-b.mjs} +321 -15
- package/dist/{toolchain-DoavrvIA.mjs → toolchain-qktiV8xc.mjs} +1 -1
- package/dist/{trigger-KVaWWNyn.mjs → trigger-DMou-X7j.mjs} +2 -2
- package/dist/trigger-qp2ji5wE.mjs +2 -0
- package/dist/{warm-progress-DvhTX_eu.mjs → warm-progress-B0Vpuvpl.mjs} +731 -727
- package/dist/{web-Bihbf7-u.mjs → web-BYmK0TjL.mjs} +9 -9
- package/dist/web-CrVLVQZY.mjs +2 -0
- package/dist/web-run.mjs +9 -9
- package/dist/windows-report.mjs +1 -1
- package/dist/{workspace-state-pUg3_RRA.mjs → workspace-state-kIZrdlSg.mjs} +3 -3
- package/dist/{workspaces-g2lhdBXF.mjs → workspaces-CmOcceDN.mjs} +1879 -74
- package/dist/{worktree-BKuklFh_.mjs → worktree-2dk5edza.mjs} +933 -534
- package/dist/worktree-nliAoHxB.mjs +2 -0
- package/package.json +7 -7
- package/dist/ccache-Bx5TbxwG.mjs +0 -143
- package/dist/eas-fallback-FwkeqqGi.mjs +0 -381
- package/dist/hosted-ios-D55QhYaD.mjs +0 -15
- package/dist/native-run-BfIDFKLH.mjs +0 -275
- package/dist/server-expo-wvcj5tiZ.mjs +0 -2
- package/dist/settings-write-QjYfSrjF.mjs +0 -360
- package/dist/trigger-DzJu208Q.mjs +0 -2
- package/dist/web-BFLueSh-.mjs +0 -2
- package/dist/worktree-Bm4cb-nU.mjs +0 -2
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { c as throwIfCancelled, l as WorkspaceProcessCleanupError, n as isTimeoutError, t as getExecutor } from "./exec-
|
|
2
|
-
import { _ as loadConfig$1, d as getConfigDir, f as getConfigPath$1, h as getRepoSettings, m as getProjectSettings } from "./config-
|
|
3
|
-
import { c as gitQuiet, l as gitQuietAsync, n as runOperationFileQuiet, o as git, r as childEnvironment, s as gitAsync, t as runOperationFile } from "./operation-exec-
|
|
4
|
-
import { accessSync, chmodSync, constants, lstatSync, mkdirSync, mkdtempSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
1
|
+
import { D as ownership_claim_exports, c as throwIfCancelled, l as WorkspaceProcessCleanupError, n as isTimeoutError, t as getExecutor } from "./exec-aULwtNly.mjs";
|
|
2
|
+
import { _ as loadConfig$1, d as getConfigDir, f as getConfigPath$1, h as getRepoSettings, m as getProjectSettings } from "./config-Cn94Jc0g.mjs";
|
|
3
|
+
import { c as gitQuiet, l as gitQuietAsync, n as runOperationFileQuiet, o as git, r as childEnvironment, s as gitAsync, t as runOperationFile } from "./operation-exec-Dp4FuIGR.mjs";
|
|
4
|
+
import { accessSync, chmodSync, constants, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
7
7
|
import { ambientEnv, buildCacheRoot, compiledHelper, configDir } from "@stim-cli/core";
|
|
8
|
-
import { REMOTE_DEVICE_BACKENDS, SETTINGS, SETTING_GROUPS, TUNNEL_MODES, WEB_VIEWPORTS, acceptsShape, coerceSettingText, expectedShape, isLayeredSetting, settingDefinition, settingValueError } from "@stim-cli/core/state";
|
|
8
|
+
import { REMOTE_DEVICE_BACKENDS, REPLACED_SETTINGS, SETTINGS, SETTING_GROUPS, TUNNEL_MODES, WEB_VIEWPORTS, acceptsShape, coerceSettingText, expectedShape, isLayeredSetting, isPathPrefix, placementWord, replacementAdvice, settingDefinition, settingValueError, trashRoot } from "@stim-cli/core/state";
|
|
9
9
|
import { basename as basename$1, dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, normalize, relative as relative$1, resolve as resolve$1, sep as sep$1 } from "path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { captureProcessIdentity } from "@stim-cli/core/process-identity";
|
|
11
12
|
import { existsSync as existsSync$1, lstatSync as lstatSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, statSync as statSync$1 } from "fs";
|
|
12
|
-
import { chmod, lstat, mkdir, readdir, realpath, rm, utimes } from "node:fs/promises";
|
|
13
|
+
import { chmod, lstat, mkdir, mkdtemp, readdir, realpath, rename, rm, rmdir, utimes, writeFile } from "node:fs/promises";
|
|
13
14
|
//#region src/temporary.ts
|
|
14
15
|
function existingPath(path) {
|
|
15
16
|
const missing = [];
|
|
@@ -108,6 +109,248 @@ async function removeTemporaryEntryAsync(path, signal) {
|
|
|
108
109
|
signal?.throwIfAborted();
|
|
109
110
|
}
|
|
110
111
|
//#endregion
|
|
112
|
+
//#region src/workspace/worktree-trash.ts
|
|
113
|
+
const TRASH_MANIFEST = "trash.json";
|
|
114
|
+
const TRASH_ENTRY_PREFIX = "remove-";
|
|
115
|
+
const TRASH_ENTRIES = "entries";
|
|
116
|
+
const TRASH_CLAIMS = "claims";
|
|
117
|
+
const LIST_TIMEOUT_MS = 3e4;
|
|
118
|
+
const DELETE_NICENESS = "10";
|
|
119
|
+
function rethrowCancellation(error, signal) {
|
|
120
|
+
if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
|
|
121
|
+
signal?.throwIfAborted();
|
|
122
|
+
}
|
|
123
|
+
async function isPlainDirectory(path) {
|
|
124
|
+
const stat = await lstat(path).catch(() => null);
|
|
125
|
+
return Boolean(stat?.isDirectory());
|
|
126
|
+
}
|
|
127
|
+
async function ignoredDirectories(worktree, options) {
|
|
128
|
+
const out = await gitAsync(worktree, [
|
|
129
|
+
"ls-files",
|
|
130
|
+
"--others",
|
|
131
|
+
"--ignored",
|
|
132
|
+
"--exclude-standard",
|
|
133
|
+
"--directory",
|
|
134
|
+
"--no-empty-directory",
|
|
135
|
+
"-z"
|
|
136
|
+
], {
|
|
137
|
+
...options.env ? childEnvironment(options.env) : {},
|
|
138
|
+
signal: options.signal,
|
|
139
|
+
declareFor: options.declareFor,
|
|
140
|
+
timeoutMs: LIST_TIMEOUT_MS,
|
|
141
|
+
untrimmed: true
|
|
142
|
+
});
|
|
143
|
+
const found = [];
|
|
144
|
+
for (const entry of out.split("\0")) {
|
|
145
|
+
if (!entry.endsWith("/")) continue;
|
|
146
|
+
const rel = entry.slice(0, -1);
|
|
147
|
+
const parts = rel.split("/");
|
|
148
|
+
let plain = true;
|
|
149
|
+
for (let depth = 1; depth <= parts.length && plain; depth++) plain = await isPlainDirectory(join(worktree, ...parts.slice(0, depth)));
|
|
150
|
+
if (plain) found.push(rel);
|
|
151
|
+
}
|
|
152
|
+
return found;
|
|
153
|
+
}
|
|
154
|
+
async function openTrash(worktree, options, kind) {
|
|
155
|
+
if ((options.platform ?? process.platform) === "win32") return null;
|
|
156
|
+
const root = trashRoot();
|
|
157
|
+
let dir = null;
|
|
158
|
+
let claim = null;
|
|
159
|
+
try {
|
|
160
|
+
await mkdir(root, { recursive: true });
|
|
161
|
+
if (filesystemDevice(root) !== filesystemDevice(worktree)) return null;
|
|
162
|
+
dir = await mkdtemp(join(root, TRASH_ENTRY_PREFIX));
|
|
163
|
+
claim = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
164
|
+
root: join(dir, "claims"),
|
|
165
|
+
mode: "exclusive",
|
|
166
|
+
label: "worktree trash"
|
|
167
|
+
}).acquired ?? null;
|
|
168
|
+
if (!claim) throw new Error("the trash entry claim was not acquired");
|
|
169
|
+
const manifest = {
|
|
170
|
+
worktree,
|
|
171
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
172
|
+
...kind ? { kind } : {}
|
|
173
|
+
};
|
|
174
|
+
await writeFile(join(dir, TRASH_MANIFEST), `${JSON.stringify(manifest)}\n`);
|
|
175
|
+
await mkdir(join(dir, TRASH_ENTRIES));
|
|
176
|
+
} catch (error) {
|
|
177
|
+
if (claim) (0, ownership_claim_exports.releaseClaim)(claim);
|
|
178
|
+
if (dir) await rm(dir, {
|
|
179
|
+
recursive: true,
|
|
180
|
+
force: true
|
|
181
|
+
}).catch(() => {});
|
|
182
|
+
rethrowCancellation(error, options.signal);
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
dir,
|
|
187
|
+
worktree,
|
|
188
|
+
moved: [],
|
|
189
|
+
claim
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Moves the worktree's ignored directories, which `git worktree remove` would delete, into a new entry under
|
|
194
|
+
* `$STIM_HOME/trash` held by an exclusive ownership claim. Null, with nothing moved, when the trash is on another
|
|
195
|
+
* filesystem, the platform is Windows, git cannot list the entries, or the claim cannot be taken. A directory that
|
|
196
|
+
* does not rename stays in the worktree for git to delete.
|
|
197
|
+
*/
|
|
198
|
+
async function moveIgnoredTreesToTrash(worktree, options = {}) {
|
|
199
|
+
if ((options.platform ?? process.platform) === "win32") return null;
|
|
200
|
+
let listed;
|
|
201
|
+
try {
|
|
202
|
+
listed = await ignoredDirectories(worktree, options);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
rethrowCancellation(error, options.signal);
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
if (!listed.length) return null;
|
|
208
|
+
const trash = await openTrash(worktree, options);
|
|
209
|
+
if (!trash) return null;
|
|
210
|
+
for (const from of listed) {
|
|
211
|
+
const to = String(trash.moved.length);
|
|
212
|
+
try {
|
|
213
|
+
await rename(join(worktree, from), join(trash.dir, TRASH_ENTRIES, to));
|
|
214
|
+
trash.moved.push({
|
|
215
|
+
from,
|
|
216
|
+
to
|
|
217
|
+
});
|
|
218
|
+
} catch {}
|
|
219
|
+
}
|
|
220
|
+
if (trash.moved.length) return trash;
|
|
221
|
+
await discardTrash(trash);
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* A trash entry that takes directories out of a live worktree while it warms, so the delete runs in the background.
|
|
226
|
+
* `take` is false, with the directory untouched, when the entry cannot be opened or the rename fails; the caller
|
|
227
|
+
* deletes it in place. gc deletes a crashed entry whatever the state of the worktree.
|
|
228
|
+
*/
|
|
229
|
+
function warmTrash(worktree, options = {}) {
|
|
230
|
+
let trash;
|
|
231
|
+
return {
|
|
232
|
+
async take(path) {
|
|
233
|
+
if (trash === void 0) trash = await openTrash(worktree, options, "warm");
|
|
234
|
+
if (!trash) return false;
|
|
235
|
+
const to = String(trash.moved.length);
|
|
236
|
+
try {
|
|
237
|
+
await rename(path, join(trash.dir, TRASH_ENTRIES, to));
|
|
238
|
+
} catch {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
trash.moved.push({
|
|
242
|
+
from: path,
|
|
243
|
+
to
|
|
244
|
+
});
|
|
245
|
+
return true;
|
|
246
|
+
},
|
|
247
|
+
async dispose(operation) {
|
|
248
|
+
if (!trash) return;
|
|
249
|
+
if (trash.moved.length) await disposeTrash(trash, operation);
|
|
250
|
+
else await discardTrash(trash);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
async function discardTrash(trash) {
|
|
255
|
+
await rmdir(join(trash.dir, TRASH_ENTRIES)).catch(() => {});
|
|
256
|
+
await rm(join(trash.dir, TRASH_MANIFEST), { force: true }).catch(() => {});
|
|
257
|
+
(0, ownership_claim_exports.releaseClaim)(trash.claim);
|
|
258
|
+
await rmdir(trash.dir).catch(() => {});
|
|
259
|
+
}
|
|
260
|
+
/** Moves every tree back into the worktree. Returns the relative paths that stay in the trash for gc. */
|
|
261
|
+
async function restoreTrashedTrees(trash) {
|
|
262
|
+
const kept = [];
|
|
263
|
+
for (const entry of trash.moved.toReversed()) {
|
|
264
|
+
const target = join(trash.worktree, entry.from);
|
|
265
|
+
try {
|
|
266
|
+
if (await lstat(target).catch(() => null) || !await isPlainDirectory(dirname(target))) {
|
|
267
|
+
kept.push(entry.from);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
await rename(join(trash.dir, TRASH_ENTRIES, entry.to), target);
|
|
271
|
+
} catch {
|
|
272
|
+
kept.push(entry.from);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (kept.length) (0, ownership_claim_exports.releaseClaim)(trash.claim);
|
|
276
|
+
else await discardTrash(trash);
|
|
277
|
+
return kept;
|
|
278
|
+
}
|
|
279
|
+
/** Deletes one trash entry: `rm -rf` for the bulk, then a walk that also clears read-only directories. */
|
|
280
|
+
async function deleteTrashEntry(dir, operation) {
|
|
281
|
+
if (process.platform !== "win32") try {
|
|
282
|
+
await runOperationFile(operation, getExecutor(), "rm", [
|
|
283
|
+
"-rf",
|
|
284
|
+
"--",
|
|
285
|
+
join(dir, TRASH_ENTRIES)
|
|
286
|
+
], {
|
|
287
|
+
timeoutMs: "unbounded",
|
|
288
|
+
signal: operation?.signal,
|
|
289
|
+
cwd: dirname(dir)
|
|
290
|
+
});
|
|
291
|
+
} catch (error) {
|
|
292
|
+
rethrowCancellation(error, operation?.signal);
|
|
293
|
+
}
|
|
294
|
+
await removeTemporaryEntryAsync(dir, operation?.signal);
|
|
295
|
+
}
|
|
296
|
+
function deleteInBackground(trash) {
|
|
297
|
+
try {
|
|
298
|
+
(0, ownership_claim_exports.markClaimChildPending)(trash.claim);
|
|
299
|
+
const child = getExecutor().spawn("nice", [
|
|
300
|
+
"-n",
|
|
301
|
+
DELETE_NICENESS,
|
|
302
|
+
"sh",
|
|
303
|
+
"-c",
|
|
304
|
+
"rm -rf -- \"$1\" && rm -rf -- \"$2\"",
|
|
305
|
+
"--",
|
|
306
|
+
join(trash.dir, TRASH_ENTRIES),
|
|
307
|
+
trash.dir
|
|
308
|
+
], {
|
|
309
|
+
cwd: dirname(trash.dir),
|
|
310
|
+
detached: true,
|
|
311
|
+
stdio: "ignore"
|
|
312
|
+
});
|
|
313
|
+
child.on?.("error", () => {});
|
|
314
|
+
child.unref?.();
|
|
315
|
+
const captured = child.pid === void 0 ? null : captureProcessIdentity(child.pid);
|
|
316
|
+
if (captured?.ok === false && captured.reason.startsWith("NOT_FOUND")) {
|
|
317
|
+
(0, ownership_claim_exports.clearClaimChild)(trash.claim);
|
|
318
|
+
(0, ownership_claim_exports.releaseClaim)(trash.claim);
|
|
319
|
+
return existsSync(trash.dir) ? "left" : "deleted";
|
|
320
|
+
}
|
|
321
|
+
if (!captured?.ok || child.pid === void 0) throw new Error("the trash deletion process was not recorded");
|
|
322
|
+
(0, ownership_claim_exports.setClaimChild)(trash.claim, {
|
|
323
|
+
pid: child.pid,
|
|
324
|
+
processToken: captured.token
|
|
325
|
+
});
|
|
326
|
+
return "background";
|
|
327
|
+
} catch {
|
|
328
|
+
try {
|
|
329
|
+
(0, ownership_claim_exports.clearClaimChild)(trash.claim);
|
|
330
|
+
} catch {}
|
|
331
|
+
(0, ownership_claim_exports.releaseClaim)(trash.claim);
|
|
332
|
+
return "left";
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Deletes the trash entry once its trees are out of the way. A CLI command starts a detached, low-priority `rm` recorded
|
|
337
|
+
* as the claim's child, so gc reports the entry as in use until `rm` exits. Inside a bounded report, such as the
|
|
338
|
+
* programmatic API, every child is stopped when the report settles, so the entry is deleted before returning.
|
|
339
|
+
* `left` means the entry waits for gc with its claim released.
|
|
340
|
+
*/
|
|
341
|
+
async function disposeTrash(trash, operation) {
|
|
342
|
+
if (!getExecutor().reportSignal?.()) return deleteInBackground(trash);
|
|
343
|
+
try {
|
|
344
|
+
await deleteTrashEntry(trash.dir, operation);
|
|
345
|
+
return "deleted";
|
|
346
|
+
} catch (error) {
|
|
347
|
+
rethrowCancellation(error, operation?.signal);
|
|
348
|
+
return "left";
|
|
349
|
+
} finally {
|
|
350
|
+
(0, ownership_claim_exports.releaseClaim)(trash.claim);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
//#endregion
|
|
111
354
|
//#region src/clonefile.ts
|
|
112
355
|
const SOURCE = "stim-clonefile.c";
|
|
113
356
|
const COMPILE_TIMEOUT_MS = 12e4;
|
|
@@ -397,7 +640,7 @@ function knownCopiedPaths(rel) {
|
|
|
397
640
|
function isMissingError(error) {
|
|
398
641
|
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
399
642
|
}
|
|
400
|
-
async function removeCopiedPath(root, rel, signal) {
|
|
643
|
+
async function removeCopiedPath(root, rel, signal, trash) {
|
|
401
644
|
signal.throwIfAborted();
|
|
402
645
|
const path = join$1(root, rel);
|
|
403
646
|
let parent;
|
|
@@ -411,21 +654,22 @@ async function removeCopiedPath(root, rel, signal) {
|
|
|
411
654
|
if (inside === ".." || inside.startsWith(`..${sep$1}`) || isAbsolute$1(inside)) return;
|
|
412
655
|
const stat = await lstat(parent);
|
|
413
656
|
const target = join$1(parent, basename$1(path));
|
|
657
|
+
let targetStat;
|
|
414
658
|
try {
|
|
415
|
-
await lstat(target);
|
|
659
|
+
targetStat = await lstat(target);
|
|
416
660
|
} catch (error) {
|
|
417
661
|
if (isMissingError(error)) return;
|
|
418
662
|
throw error;
|
|
419
663
|
}
|
|
420
664
|
await chmod(parent, stat.mode | 448);
|
|
421
665
|
try {
|
|
422
|
-
await removeTemporaryEntryAsync(target, signal);
|
|
666
|
+
if (!(targetStat.isDirectory() && await trash.take(target))) await removeTemporaryEntryAsync(target, signal);
|
|
423
667
|
} finally {
|
|
424
668
|
await utimes(parent, stat.atime, stat.mtime);
|
|
425
669
|
await chmod(parent, stat.mode);
|
|
426
670
|
}
|
|
427
671
|
}
|
|
428
|
-
async function removeKnownCopiedPaths(path, rel, signal) {
|
|
672
|
+
async function removeKnownCopiedPaths(path, rel, signal, trash) {
|
|
429
673
|
const paths = knownCopiedPaths(rel);
|
|
430
674
|
if (basename$1(rel) === "node_modules") {
|
|
431
675
|
const virtualStore = await readdir(join$1(path, ".pnpm")).catch((error) => {
|
|
@@ -435,7 +679,7 @@ async function removeKnownCopiedPaths(path, rel, signal) {
|
|
|
435
679
|
for (const name of virtualStore) if (name.startsWith("expo-modules-jsi@")) paths.push(`.pnpm/${name}/node_modules/expo-modules-jsi/apple/.DerivedData`);
|
|
436
680
|
}
|
|
437
681
|
const root = await realpath(path);
|
|
438
|
-
for (const known of paths) await removeCopiedPath(root, known, signal);
|
|
682
|
+
for (const known of paths) await removeCopiedPath(root, known, signal, trash);
|
|
439
683
|
}
|
|
440
684
|
async function cloneIgnoredEntries({ root, target, patterns, operation }) {
|
|
441
685
|
const options = {
|
|
@@ -460,58 +704,65 @@ async function cloneIgnoredEntries({ root, target, patterns, operation }) {
|
|
|
460
704
|
let cloned = true;
|
|
461
705
|
let helper;
|
|
462
706
|
const clonefile = () => helper ??= clonefileHelper(operation);
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
copying = true;
|
|
479
|
-
const copiedWith = async (file, args) => {
|
|
480
|
-
try {
|
|
481
|
-
await getExecutor().runFileAsync(file, args, options);
|
|
482
|
-
return true;
|
|
483
|
-
} catch (cause) {
|
|
484
|
-
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
485
|
-
operation.signal.throwIfAborted();
|
|
486
|
-
await removeTemporaryEntryAsync(to);
|
|
487
|
-
return false;
|
|
707
|
+
const trash = warmTrash(target, { signal: operation.signal });
|
|
708
|
+
try {
|
|
709
|
+
for (const rel of entries) {
|
|
710
|
+
operation.signal.throwIfAborted();
|
|
711
|
+
const from = join$1(root, rel);
|
|
712
|
+
const to = join$1(target, rel);
|
|
713
|
+
let copying = false;
|
|
714
|
+
try {
|
|
715
|
+
const reason = guard.covers(rel) ? "tracked" : overlapsNestedWorktree(rel, nested) ? "nested worktree" : missingDestinationReason(target, rel);
|
|
716
|
+
if (reason) {
|
|
717
|
+
skipped.push({
|
|
718
|
+
file: rel,
|
|
719
|
+
reason
|
|
720
|
+
});
|
|
721
|
+
continue;
|
|
488
722
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
723
|
+
await mkdir(dirname$1(to), { recursive: true });
|
|
724
|
+
copying = true;
|
|
725
|
+
const copiedWith = async (file, args) => {
|
|
726
|
+
try {
|
|
727
|
+
await getExecutor().runFileAsync(file, args, options);
|
|
728
|
+
return true;
|
|
729
|
+
} catch (cause) {
|
|
730
|
+
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
731
|
+
operation.signal.throwIfAborted();
|
|
732
|
+
await removeTemporaryEntryAsync(to);
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
const directoryClone = (await lstat(from)).isDirectory() ? await clonefile() : null;
|
|
737
|
+
if (!(directoryClone && await copiedWith(directoryClone, [from, to])) && !await copiedWith("cp", [
|
|
738
|
+
"-Rc",
|
|
498
739
|
from,
|
|
499
740
|
to
|
|
500
|
-
]
|
|
501
|
-
|
|
741
|
+
])) {
|
|
742
|
+
await getExecutor().runFileAsync("cp", [
|
|
743
|
+
"-R",
|
|
744
|
+
from,
|
|
745
|
+
to
|
|
746
|
+
], options);
|
|
747
|
+
cloned = false;
|
|
748
|
+
}
|
|
749
|
+
if ((await lstat(to)).isDirectory()) await removeKnownCopiedPaths(to, rel, operation.signal, trash);
|
|
750
|
+
copied.push(rel);
|
|
751
|
+
} catch (cause) {
|
|
752
|
+
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
753
|
+
if (copying) await removeTemporaryEntryAsync(to);
|
|
754
|
+
operation.signal.throwIfAborted();
|
|
755
|
+
failed.push({
|
|
756
|
+
file: rel,
|
|
757
|
+
error: String(cause?.message || cause)
|
|
758
|
+
});
|
|
502
759
|
}
|
|
503
|
-
if ((await lstat(to)).isDirectory()) await removeKnownCopiedPaths(to, rel, operation.signal);
|
|
504
|
-
copied.push(rel);
|
|
505
|
-
} catch (cause) {
|
|
506
|
-
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
507
|
-
if (copying) await removeTemporaryEntryAsync(to);
|
|
508
|
-
operation.signal.throwIfAborted();
|
|
509
|
-
failed.push({
|
|
510
|
-
file: rel,
|
|
511
|
-
error: String(cause?.message || cause)
|
|
512
|
-
});
|
|
513
760
|
}
|
|
761
|
+
} catch (error) {
|
|
762
|
+
await trash.dispose(operation).catch(() => {});
|
|
763
|
+
throw error;
|
|
514
764
|
}
|
|
765
|
+
await trash.dispose(operation);
|
|
515
766
|
return {
|
|
516
767
|
copied,
|
|
517
768
|
skipped,
|
|
@@ -811,6 +1062,32 @@ async function deleteBranchAsync(cwd, branch, expectedSha, options = {}) {
|
|
|
811
1062
|
write: true
|
|
812
1063
|
});
|
|
813
1064
|
}
|
|
1065
|
+
function nativeCanonicalPath(path) {
|
|
1066
|
+
const missing = [];
|
|
1067
|
+
for (let existing = resolve$1(path);; existing = dirname$1(existing)) try {
|
|
1068
|
+
return resolve$1(realpathSync$1.native(existing), ...missing);
|
|
1069
|
+
} catch {
|
|
1070
|
+
if (dirname$1(existing) === existing) return resolve$1(path);
|
|
1071
|
+
missing.unshift(basename$1(existing));
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
function matchWorktreeEntry(entries, path) {
|
|
1075
|
+
let best = null;
|
|
1076
|
+
const target = nativeCanonicalPath(path);
|
|
1077
|
+
(entries || []).forEach((entry, index) => {
|
|
1078
|
+
if (!entry?.path || !isPathPrefix(nativeCanonicalPath(entry.path), target)) return;
|
|
1079
|
+
if (!best || entry.path.length > best.path.length) best = {
|
|
1080
|
+
...entry,
|
|
1081
|
+
index
|
|
1082
|
+
};
|
|
1083
|
+
});
|
|
1084
|
+
return best;
|
|
1085
|
+
}
|
|
1086
|
+
const LOCKED_REASON = "locked with git worktree lock";
|
|
1087
|
+
const LOCK_UNKNOWN_REASON = "git could not tell whether its worktree is locked";
|
|
1088
|
+
function lockReason(lock) {
|
|
1089
|
+
return lock === "locked" ? LOCKED_REASON : LOCK_UNKNOWN_REASON;
|
|
1090
|
+
}
|
|
814
1091
|
function parseWorktrees(out) {
|
|
815
1092
|
const entries = [];
|
|
816
1093
|
let current = {};
|
|
@@ -856,6 +1133,24 @@ async function listWorktreesAsync(cwd, options = {}) {
|
|
|
856
1133
|
], options);
|
|
857
1134
|
return out ? parseWorktrees(out) : [];
|
|
858
1135
|
}
|
|
1136
|
+
function insideGitCheckout(root) {
|
|
1137
|
+
for (let dir = resolve$1(root);; dir = dirname$1(dir)) {
|
|
1138
|
+
if (existsSync$1(join$1(dir, ".git"))) return true;
|
|
1139
|
+
if (dirname$1(dir) === dir) return false;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
function lockOf(entries, root) {
|
|
1143
|
+
const entry = matchWorktreeEntry(entries, root);
|
|
1144
|
+
if (entry) return entry.locked ? "locked" : null;
|
|
1145
|
+
return existsSync$1(root) && insideGitCheckout(root) ? "unknown" : null;
|
|
1146
|
+
}
|
|
1147
|
+
/** Null when `root` is not in a locked worktree; 'unknown' when git lists nothing for a path inside a git checkout. */
|
|
1148
|
+
function worktreeLock(root) {
|
|
1149
|
+
return lockOf(listWorktrees(root), root);
|
|
1150
|
+
}
|
|
1151
|
+
async function worktreeLockAsync(root, options = {}) {
|
|
1152
|
+
return lockOf(await listWorktreesAsync(root, options), root);
|
|
1153
|
+
}
|
|
859
1154
|
function branchOf(head) {
|
|
860
1155
|
return head.startsWith("ref: refs/heads/") ? head.slice(16) : void 0;
|
|
861
1156
|
}
|
|
@@ -1043,7 +1338,7 @@ function settingShapeErrors(settings) {
|
|
|
1043
1338
|
if (SETTINGS_WITH_RESOLVE_TIME_FALLBACK.has(setting.key)) continue;
|
|
1044
1339
|
const value = settingValueAt(settings, setting.key);
|
|
1045
1340
|
if (value === void 0) continue;
|
|
1046
|
-
const expected = setting.key === "ios.remote" || setting.key === "android.remote" || setting.key === "android.deviceProfile" || setting.type.kind === "number" && !BOUNDS_CHECKED_WHEN_USED.has(setting.key) ? settingValueError(setting, value) : acceptsShape(setting, value) ? null : expectedShape(setting.type);
|
|
1341
|
+
const expected = setting.key === "ios.remote" || setting.key === "android.remote" || setting.key === "macos.remote" || setting.key === "android.deviceProfile" || setting.type.kind === "number" && !BOUNDS_CHECKED_WHEN_USED.has(setting.key) ? settingValueError(setting, value) : acceptsShape(setting, value) ? null : expectedShape(setting.type);
|
|
1047
1342
|
if (expected) errors.push(`Invalid ${setting.key} setting ${JSON.stringify(value)}. Expected ${expected}.`);
|
|
1048
1343
|
}
|
|
1049
1344
|
return errors;
|
|
@@ -1440,6 +1735,10 @@ function unknownSettingKeys(settings, prefix = "") {
|
|
|
1440
1735
|
}
|
|
1441
1736
|
return unknown;
|
|
1442
1737
|
}
|
|
1738
|
+
function inertSettingWarning(settings, key) {
|
|
1739
|
+
const advice = replacementAdvice(key, settingValueAt(settings, key));
|
|
1740
|
+
return `Warning: setting "${key}" is not read by Stim and will be ignored.${advice ? advice.command ? ` Run \`${advice.command}\` instead.` : ` Use ${advice.key} instead.` : ""}`;
|
|
1741
|
+
}
|
|
1443
1742
|
function readCommittedSettings(directory) {
|
|
1444
1743
|
if (!directory) return {};
|
|
1445
1744
|
const p = join$1(directory, ".stim.json");
|
|
@@ -1462,8 +1761,16 @@ function setSettingValueAt(settings, path, value) {
|
|
|
1462
1761
|
node[segments[segments.length - 1]] = value;
|
|
1463
1762
|
}
|
|
1464
1763
|
const MACHINE_READABLE_SETTINGS = SETTINGS.filter((setting) => isLayeredSetting(setting) && setting.scopes.includes("machine") && !setting.key.startsWith("optimizations."));
|
|
1465
|
-
function
|
|
1764
|
+
function removedMachineSettings(machine) {
|
|
1466
1765
|
const settings = {};
|
|
1766
|
+
for (const key of Object.keys(REPLACED_SETTINGS)) {
|
|
1767
|
+
const value = settingValueAt(machine, key);
|
|
1768
|
+
if (value !== void 0) setSettingValueAt(settings, key, value);
|
|
1769
|
+
}
|
|
1770
|
+
return settings;
|
|
1771
|
+
}
|
|
1772
|
+
function machineLayerSettings(machine) {
|
|
1773
|
+
const settings = removedMachineSettings(machine);
|
|
1467
1774
|
const optimizations = settingValueAt(machine, "optimizations");
|
|
1468
1775
|
if (optimizations !== void 0) settings.optimizations = optimizations;
|
|
1469
1776
|
for (const setting of MACHINE_READABLE_SETTINGS) {
|
|
@@ -1635,13 +1942,19 @@ function cacheProviderSettingError(settings) {
|
|
|
1635
1942
|
function parseIosRemote(remote) {
|
|
1636
1943
|
const selected = remote.trim();
|
|
1637
1944
|
const reserved = selected.toLowerCase();
|
|
1638
|
-
|
|
1945
|
+
const word = placementWord(selected);
|
|
1946
|
+
if (word === "local") return null;
|
|
1947
|
+
if (word) return {
|
|
1948
|
+
kind: "machine",
|
|
1949
|
+
machine: "auto",
|
|
1950
|
+
placement: word
|
|
1951
|
+
};
|
|
1639
1952
|
return REMOTE_DEVICE_BACKENDS.includes(reserved) ? {
|
|
1640
1953
|
kind: "backend",
|
|
1641
1954
|
backend: reserved
|
|
1642
1955
|
} : {
|
|
1643
1956
|
kind: "machine",
|
|
1644
|
-
machine:
|
|
1957
|
+
machine: selected
|
|
1645
1958
|
};
|
|
1646
1959
|
}
|
|
1647
1960
|
function remoteIosSetting(settings) {
|
|
@@ -1742,4 +2055,4 @@ function webSettings(settings) {
|
|
|
1742
2055
|
};
|
|
1743
2056
|
}
|
|
1744
2057
|
//#endregion
|
|
1745
|
-
export {
|
|
2058
|
+
export { runnableMetroCommand as $, TRASH_MANIFEST as $t, metroCommandSetting as A, listWorktrees as At, publicUrlSetting as B, repoRoot as Bt, iosSigningIdentitySettingError as C, gitCommonDirOnDisk as Ct, iosSimSlimProfileSetting as D, isPodInstallChurn as Dt, iosSimSlimDefaultSetting as E, hasUncommittedWorkAsync as Et, metroWarmupUrlSetting as F, matchWorktreeEntry as Ft, remoteIosSetting as G, restoreFileAsync as Gt, realpathInside as H, resolveFullRef as Ht, ngrokUrlSetting as I, nativeCanonicalPath as It, resolveCacheProviderConfig as J, warmWorktreePaths as Jt, removedMachineSettings as K, sourceCheckoutOf as Kt, parseIosRemote as L, podsOutOfSync as Lt, metroIdleStopMinutesSetting as M, locallyKnownUpstream as Mt, metroPortSetting as N, locallyKnownUpstreamAsync as Nt, maintenanceKeepSetting as O, linkedWorktreesOnDisk as Ot, metroTunnelSettingError as P, lockReason as Pt, resolveSettings as Q, TRASH_ENTRY_PREFIX as Qt, projectSettingsContext as R, readWorktreeExclude as Rt, iosSigningIdentitySetting as S, gitCommonDirAsync as St, iosSigningIdentitySha1SettingError as T, hasRemoteAsync as Tt, remoteAndroidSetting as U, resolveFullRefAsync as Ut, readCommittedSettings as V, repoRootAsync as Vt, remoteEasFallbackSetting as W, resolveSourceCheckoutAsync as Wt, resolveProjectSettings as X, worktreeLockAsync as Xt, resolveIosProjectDir as Y, worktreeLock as Yt, resolveProjectSettingsAsync as Z, TRASH_CLAIMS as Zt, inertSettingWarning as _, deleteBranchAsync as _t, SETTING_SHAPE_REMEDY as a, makeTemporaryDirectory as an, settingsLayers as at, iosProjectDirSetting as b, dirtyPathsAsync as bt, androidDataPartitionSizeBytes as c, temporaryRoot as cn, webSettings as ct, androidLayoutSetting as d, detectProviders as dt, deleteTrashEntry as en, settingFile as et, androidLayoutSettingError as f, planMetroReach as ft, deviceReclaimIdleMinutesSetting as g, cloneIgnoredEntries as gt, deviceIdleShutdownMinutesSetting as h, branchExistsAsync as ht, SETTINGS_WITH_RESOLVE_TIME_FALLBACK as i, filesystemDevice as in, settingValueAt as it, metroCommandSettingError as j, listWorktreesAsync as jt, mergeSettingsLayers as k, listCarryableIgnoredEntries as kt, androidDataPartitionSizeGbSetting as l, workspaceHiddenSetting as lt, defaultAndroidLayout as m, LOCKED_REASON as mt, METRO_COMMAND_PORT as n, moveIgnoredTreesToTrash as nn, settingOriginScope as nt, androidAvdConfigSetting as o, removeTemporaryEntry as on, tunnelModeSetting as ot, cacheProviderSettingError as p, resolveTailscaleBinary as pt, resolveAndroidLayout as q, unpushedCommitsAsync as qt, PATH_SETTINGS as r, restoreTrashedTrees as rn, settingShapeErrors as rt, androidAvdConfigSettingError as s, removeTemporaryEntryAsync as sn, unknownSettingKeys as st, ANDROID_AVD_CONFIG_HELP as t, disposeTrash as tn, settingOrigin as tt, androidDataPartitionSizeGbSettingError as u, PUBLIC_METRO_ENV as ut, iosLanHostSetting as v, depsOutOfSync as vt, iosSigningIdentitySha1Setting as w, hasPopulatedSubmodulesAsync as wt, iosProjectDirSettingError as x, gitCommonDir as xt, iosLanHostSettingError as y, dirtyFingerprintFiles as yt, projectSettingsContextAsync as z, removeWorktreeAsync as zt };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as readSettingsPayload, l as settingEntry, o as layerFile, s as readSettingsContext, t as SettingsRefusal } from "./settings-payload-DwQiEMCn.mjs";
|
|
2
|
+
import { i as unsetReplacedSetting, n as readScope, r as requireSetting, t as mutateSetting } from "./settings-write-CJpjkeAd.mjs";
|
|
3
|
+
import { REPLACED_SETTINGS, SETTING_SCOPES } from "@stim-cli/core/state";
|
|
3
4
|
import chalk from "chalk";
|
|
4
5
|
//#region src/commands/settings.ts
|
|
5
6
|
function formatValue(value) {
|
|
@@ -45,7 +46,7 @@ function registerSettings(program, io = CONSOLE, env = process.env) {
|
|
|
45
46
|
const shown = entry.origin === null ? "" : formatValue(entry.value);
|
|
46
47
|
io.out(`${entry.key.padEnd(width)} ${shown}${shown ? " " : ""}${chalk.dim(`(${formatOrigin(entry)})`)}`);
|
|
47
48
|
}
|
|
48
|
-
for (const entry of payload.unknown) io.note(chalk.yellow(`Warning: ${entry.key} in ${entry.file} is not read by Stim.`));
|
|
49
|
+
for (const entry of payload.unknown) io.note(chalk.yellow(`Warning: ${entry.key} in ${entry.file} is not read by Stim.${entry.replacement ? ` Run \`${entry.replacement}\` instead.` : ""}`));
|
|
49
50
|
}));
|
|
50
51
|
settings.command("get <key>").description("Print the effective value of a setting, or its value in one layer").option("--scope <scope>", `read one layer: ${SETTING_SCOPES.join(", ")}`).option("--json", "print the setting entry as JSON").action((key, opts, command) => run(wantsJson(opts, command), io, async () => {
|
|
51
52
|
const setting = requireSetting(key);
|
|
@@ -80,6 +81,18 @@ function registerSettings(program, io = CONSOLE, env = process.env) {
|
|
|
80
81
|
report(io, wantsJson(opts, command), result, "set");
|
|
81
82
|
}));
|
|
82
83
|
settings.command("unset <key>").description("Remove a setting from one layer").option("--scope <scope>", `the layer to clear: ${SETTING_SCOPES.join(", ")}`).option("--json", "print the setting after removal as JSON").action((key, opts, command) => run(wantsJson(opts, command), io, async () => {
|
|
84
|
+
if (Object.hasOwn(REPLACED_SETTINGS, key)) {
|
|
85
|
+
const removal = await unsetReplacedSetting({
|
|
86
|
+
key,
|
|
87
|
+
scope: opts.scope
|
|
88
|
+
}, {
|
|
89
|
+
cwd: process.cwd(),
|
|
90
|
+
env,
|
|
91
|
+
note: io.note
|
|
92
|
+
});
|
|
93
|
+
reportRemoval(io, wantsJson(opts, command), removal, opts.scope);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
83
96
|
const result = await mutateSetting({
|
|
84
97
|
action: "unset",
|
|
85
98
|
key,
|
|
@@ -92,6 +105,14 @@ function registerSettings(program, io = CONSOLE, env = process.env) {
|
|
|
92
105
|
report(io, wantsJson(opts, command), result, "unset");
|
|
93
106
|
}));
|
|
94
107
|
}
|
|
108
|
+
function reportRemoval(io, json, removal, scope) {
|
|
109
|
+
if (json) {
|
|
110
|
+
io.out(JSON.stringify(removal));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
for (const { file } of removal.removed) io.out(`unset ${removal.key} in ${file}`);
|
|
114
|
+
if (removal.removed.length === 0) io.out(`${removal.key} was not set in ${scope ? `the ${scope} layer` : "any layer"}.`);
|
|
115
|
+
}
|
|
95
116
|
function report(io, json, result, verb) {
|
|
96
117
|
const { setting: entry, recordingsDeleted, ...write } = result;
|
|
97
118
|
if (json) {
|