stim 1.20.2 → 1.22.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 +141 -8
- package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
- package/dist/act-DsuqEkiM.mjs +2801 -0
- package/dist/activity-CMLmzp7o.mjs +1397 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
- package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
- package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
- package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
- package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/android-project-DVWyCbWU.d.mts +391 -0
- package/dist/api.d.mts +810 -64
- package/dist/api.mjs +782 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
- package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
- package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
- package/dist/budget-Cvwn54qV.mjs +9285 -0
- package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
- package/dist/build-cache-Dv7RN200.mjs +602 -0
- package/dist/build-plan-DUC8Ka9y.mjs +248 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-OyRoEuSr.mjs +1577 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
- package/dist/config-DlrsduwG.mjs +955 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
- package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
- package/dist/device-DklWZLqb.mjs +1068 -0
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
- package/dist/device-host-worker.mjs +76 -79
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
- package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
- package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
- package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/doctor-thjWAV0z.mjs +2 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
- package/dist/exec-DEoAhcze.mjs +858 -0
- package/dist/exec-DnYc4HGH.d.mts +78 -0
- package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
- package/dist/gc-DnNDQyaP.mjs +3 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
- package/dist/idle-C4cZ757K.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
- package/dist/ios-CDvlmUs7.d.mts +24 -0
- package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
- package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
- package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
- package/dist/ios-signing-BtAffm0A.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
- package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
- package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
- package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
- package/dist/logs-BfwwadsZ.mjs +479 -0
- package/dist/logs-jTS_lHSo.mjs +248 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
- package/dist/macos-NfV2D7dO.mjs +694 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +123 -248
- package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
- package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
- package/dist/native-android-CqgnOgsT.mjs +645 -0
- package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
- package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-NwUuxbkg.mjs +276 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
- package/dist/native-source-Y0yLhFyQ.mjs +133 -0
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +59 -41
- package/dist/offload-worker.mjs +478 -115
- package/dist/operation-exec-BW0em61G.mjs +171 -0
- package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
- package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
- package/dist/prebuild-D4JoEAEs.mjs +484 -0
- package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
- package/dist/pull-request-eODyIqZF.d.mts +124 -0
- package/dist/pull-requests.d.mts +2 -120
- package/dist/pull-requests.mjs +2 -2
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
- package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
- package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
- package/dist/registration-BcRgF6Ox.mjs +51 -0
- package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
- package/dist/reload-D7AVlb8N.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
- package/dist/result-D2Ykz_iD.mjs +435 -0
- package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
- package/dist/selection-DSMbWEX2.mjs +620 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
- package/dist/server-expo-D58c9L0M.mjs +2 -0
- package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
- package/dist/settings-DpR-1Wnn.mjs +114 -0
- package/dist/settings-write-CzD60rOD.mjs +360 -0
- package/dist/settings.schema.json +176 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-Bps5oius.mjs +200 -0
- package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
- package/dist/start-EojN4WFz.mjs +1364 -0
- package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
- package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
- package/dist/stats-report-BzaPrRm6.mjs +16 -0
- package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
- package/dist/status-EvrK72L2.mjs +2 -0
- package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
- package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
- package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +56 -28
- package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
- package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
- package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
- package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
- package/dist/toolchain-BY8X8HXx.mjs +2 -0
- package/dist/toolchain-DpJMHq0n.mjs +876 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
- package/dist/trigger-yb_nFzPF.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
- package/dist/web-CZ07gd77.mjs +2 -0
- package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
- package/dist/web-run.mjs +13 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
- package/dist/worktree-ZqZVjD9K.mjs +2 -0
- package/dist/xcode-BXn9-xYx.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-audio/Main.java +24 -0
- package/shim/android-audio/README.md +17 -0
- package/shim/android-audio.jar +0 -0
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/macos-Ch5VJmcS.mjs +0 -584
- package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/settings-vk3mJGSm.d.mts +0 -13
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/start-BWqzODpb.mjs +0 -1116
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { i as withWorkspaceProcessLock, l as refuseDeclaredSpawns, m as operationState, p as isTermination, s as allowDeclaredSpawns, u as signalDeclaredSpawns, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
|
|
3
|
+
import { a as formatElapsed, l as phaseLine } from "./command-output-gwpm28fu.mjs";
|
|
4
|
+
import { o as updateWorkspaceState, r as readWorkspaceState, t as clearWorkspaceStateKey } from "./workspace-state-U08dEzhG.mjs";
|
|
5
|
+
import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
|
|
6
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
7
|
+
import { basename, dirname, join } from "node:path";
|
|
8
|
+
import { setTimeout } from "node:timers/promises";
|
|
9
|
+
//#region src/cache/cache-claim.ts
|
|
10
|
+
const LABEL = "cache";
|
|
11
|
+
const POLL_MS = 500;
|
|
12
|
+
const EMPTYING_WAIT_MS = 6e5;
|
|
13
|
+
/**
|
|
14
|
+
* The claim set guarding a cache Stim can only empty whole. It sits beside the cache's resolved directory, so emptying
|
|
15
|
+
* the cache never removes it and every path that reaches the same cache names the same set; before the cache exists,
|
|
16
|
+
* its resolved parent stands in for it.
|
|
17
|
+
*/
|
|
18
|
+
function cacheClaimRoot(dir) {
|
|
19
|
+
return `${existsSync(dir) ? canonicalPath(dir) : join(canonicalPath(dirname(dir)), basename(dir))}.claims`;
|
|
20
|
+
}
|
|
21
|
+
function describe(holder) {
|
|
22
|
+
const { platform, projectRoot } = holder.details;
|
|
23
|
+
const where = typeof projectRoot === "string" ? ` in ${projectRoot}` : "";
|
|
24
|
+
return holder.mode === "shared" ? `the ${typeof platform === "string" ? platform : "iOS"} build (pid ${holder.owner.pid}${where}) may be using it` : `pid ${holder.owner.pid} is emptying it`;
|
|
25
|
+
}
|
|
26
|
+
/** Why the cache at `dir` may be in use, from its claim set, without taking or removing any claim. */
|
|
27
|
+
function cacheUser(dir) {
|
|
28
|
+
const root = cacheClaimRoot(dir);
|
|
29
|
+
const survey = (0, ownership_claim_exports.readClaimSet)(root);
|
|
30
|
+
const problem = survey.unresolved[0];
|
|
31
|
+
if (problem) return `the cache claim ${problem.path} is unresolved, so a build may be using it`;
|
|
32
|
+
const holder = survey.live[0];
|
|
33
|
+
return holder ? describe(holder) : void 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Takes the exclusive claim an emptier holds while it removes the cache's contents; a string is why it cannot.
|
|
37
|
+
* It never waits for a build that holds the cache.
|
|
38
|
+
*/
|
|
39
|
+
function claimForEmptying(dir) {
|
|
40
|
+
try {
|
|
41
|
+
const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
42
|
+
root: cacheClaimRoot(dir),
|
|
43
|
+
mode: "exclusive",
|
|
44
|
+
label: LABEL
|
|
45
|
+
});
|
|
46
|
+
if (attempt.acquired) return attempt.acquired;
|
|
47
|
+
if (attempt.pending) (0, ownership_claim_exports.releaseClaim)(attempt.pending);
|
|
48
|
+
const holder = attempt.held ?? attempt.waitingFor?.[0];
|
|
49
|
+
return holder ? describe(holder) : `its claim at ${cacheClaimRoot(dir)} could not be taken`;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if ((0, ownership_claim_exports.isClaimRefusal)(error) || (0, ownership_claim_exports.isClaimUnavailable)(error)) return error.message;
|
|
52
|
+
return `its claim at ${cacheClaimRoot(dir)} could not be taken: ${error instanceof Error ? error.message : String(error)}`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Takes the shared claim a build holds on the compilation cache it compiles with, waiting while an emptier holds it.
|
|
57
|
+
* A claim set Stim cannot resolve, or no process identity, is a failure: the build never runs unguarded.
|
|
58
|
+
*/
|
|
59
|
+
async function shareCompilationCache({ dir, projectRoot, note, signal }) {
|
|
60
|
+
const started = Date.now();
|
|
61
|
+
let told = false;
|
|
62
|
+
for (;;) {
|
|
63
|
+
signal?.throwIfAborted();
|
|
64
|
+
let attempt;
|
|
65
|
+
let root = `${dir}.claims`;
|
|
66
|
+
try {
|
|
67
|
+
mkdirSync(dirname(dir), { recursive: true });
|
|
68
|
+
root = cacheClaimRoot(dir);
|
|
69
|
+
attempt = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
70
|
+
root,
|
|
71
|
+
mode: "shared",
|
|
72
|
+
label: LABEL,
|
|
73
|
+
details: {
|
|
74
|
+
platform: "ios",
|
|
75
|
+
projectRoot
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return { failure: (0, ownership_claim_exports.claimFailure)(error, null) ?? {
|
|
80
|
+
code: ownership_claim_exports.CLAIM_UNAVAILABLE,
|
|
81
|
+
message: `Stim could not take the compilation cache claim at ${root}: ${error instanceof Error ? error.message : String(error)}.`,
|
|
82
|
+
remedy: `Restore write access to ${dirname(root)}, then retry the same Stim command.`
|
|
83
|
+
} };
|
|
84
|
+
}
|
|
85
|
+
if (attempt.acquired) return { claim: attempt.acquired };
|
|
86
|
+
const emptier = attempt.held ? `pid ${attempt.held.owner.pid}` : "another process";
|
|
87
|
+
const waited = Date.now() - started;
|
|
88
|
+
if (waited >= EMPTYING_WAIT_MS) return { failure: {
|
|
89
|
+
code: "STIM_BUILD_FAILED",
|
|
90
|
+
message: `${emptier} has been emptying the compilation cache at ${dir} for ${formatElapsed(waited)}.`,
|
|
91
|
+
remedy: "Run the same command again once it has finished."
|
|
92
|
+
} };
|
|
93
|
+
if (!told) note(phaseLine("build", `waiting for ${emptier} to finish emptying the compilation cache at ${dir}`));
|
|
94
|
+
told = true;
|
|
95
|
+
await setTimeout(POLL_MS);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/engine/native-run.ts
|
|
100
|
+
const NATIVE_RUN_LOCK = "native-run";
|
|
101
|
+
const NATIVE_RUN_WAIT_MS = 18e5;
|
|
102
|
+
const WAIT_HEARTBEAT_MS = 3e4;
|
|
103
|
+
const CANCEL_REQUEST_KEY = "nativeRunCancel";
|
|
104
|
+
const REQUEST_POLL_MS = 250;
|
|
105
|
+
function nativeRunHolder(holder) {
|
|
106
|
+
const { command, platform, slot, interrupt } = holder.details;
|
|
107
|
+
return {
|
|
108
|
+
command: typeof command === "string" ? command : null,
|
|
109
|
+
platform: typeof platform === "string" ? platform : null,
|
|
110
|
+
slot: typeof slot === "string" ? slot : "default",
|
|
111
|
+
takesSignals: interrupt === "signal"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function describeNativeRunHolder(holder, now) {
|
|
115
|
+
const { command, slot } = nativeRunHolder(holder);
|
|
116
|
+
const started = Date.parse(holder.startedAt);
|
|
117
|
+
const facts = [`pid ${holder.owner.pid}`];
|
|
118
|
+
if (Number.isFinite(started)) facts.push(`running for ${formatElapsed(now - started)}`);
|
|
119
|
+
if (command === null) return `another Stim run (${facts.join(", ")})`;
|
|
120
|
+
if (command === "build") return `an artifact build (${facts.join(", ")})`;
|
|
121
|
+
return `\`stim ${command}${slot === "default" ? "" : ` --slot ${slot}`}\` (${facts.join(", ")})`;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Report a wait on the native-run lock: one line as soon as a holder is seen, a line for each new
|
|
125
|
+
* holder, and a heartbeat every WAIT_HEARTBEAT_MS while the same holder keeps it.
|
|
126
|
+
*/
|
|
127
|
+
function nativeRunWaitNotice({ write, now = Date.now, describe = describeNativeRunHolder }) {
|
|
128
|
+
let claimId = null;
|
|
129
|
+
let lastAt = 0;
|
|
130
|
+
return (holder, firstLine) => {
|
|
131
|
+
const at = now();
|
|
132
|
+
if (holder.claimId !== claimId) {
|
|
133
|
+
claimId = holder.claimId;
|
|
134
|
+
lastAt = at;
|
|
135
|
+
write(firstLine ?? `waiting for ${describe(holder, at)} in this workspace to finish`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (at - lastAt < WAIT_HEARTBEAT_MS) return;
|
|
139
|
+
lastAt = at;
|
|
140
|
+
write(`still waiting for ${describe(holder, at)}`);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* What `stop` does about the run holding the native-run lock. A build is interrupted only when the stop
|
|
145
|
+
* leaves it nothing to deploy to: the whole workspace stops, the build targets the stopped slot, or the
|
|
146
|
+
* stopped slot is the workspace's only device. A build for another slot that stays is left running and
|
|
147
|
+
* the stop proceeds without the lock. Only an owner whose identity is proven live is signalled.
|
|
148
|
+
*/
|
|
149
|
+
function decideStopAction({ stopSlot, holder, ownerIdentity, deviceSlots }) {
|
|
150
|
+
if (holder.command === "macos" || holder.command === "build") {
|
|
151
|
+
if (stopSlot !== void 0) return { action: "proceed" };
|
|
152
|
+
return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
|
|
153
|
+
}
|
|
154
|
+
if (holder.command !== "ios" && holder.command !== "android") return { action: "wait" };
|
|
155
|
+
if (!(stopSlot === void 0 || holder.slot === stopSlot || deviceSlots.includes(stopSlot) && deviceSlots.every((slot) => slot === stopSlot))) return { action: "proceed" };
|
|
156
|
+
return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
|
|
157
|
+
}
|
|
158
|
+
const requestListeners = /* @__PURE__ */ new Map();
|
|
159
|
+
/**
|
|
160
|
+
* Ask the run holding `claimId` to cancel: the request is written to the workspace state, where the run's watch
|
|
161
|
+
* finds it, and a run in this process is told at once.
|
|
162
|
+
*/
|
|
163
|
+
function requestNativeRunCancel(root, claimId, pid = process.pid) {
|
|
164
|
+
updateWorkspaceState(root, (state) => ({
|
|
165
|
+
...state,
|
|
166
|
+
[CANCEL_REQUEST_KEY]: {
|
|
167
|
+
claimId,
|
|
168
|
+
pid,
|
|
169
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
170
|
+
}
|
|
171
|
+
}));
|
|
172
|
+
requestListeners.get(claimId)?.();
|
|
173
|
+
}
|
|
174
|
+
function cancelRequestFor(root, claimId) {
|
|
175
|
+
const request = readWorkspaceState(root)?.[CANCEL_REQUEST_KEY];
|
|
176
|
+
if (request?.claimId !== claimId || typeof request.pid !== "number") return null;
|
|
177
|
+
return { pid: request.pid };
|
|
178
|
+
}
|
|
179
|
+
function clearNativeRunCancel(root, claimId) {
|
|
180
|
+
try {
|
|
181
|
+
clearWorkspaceStateKey(root, CANCEL_REQUEST_KEY, (value) => value?.claimId === claimId);
|
|
182
|
+
} catch {}
|
|
183
|
+
}
|
|
184
|
+
/** The active native run of `context`'s operation aborts this signal when it is cancelled. */
|
|
185
|
+
function runCancellationSignal(context) {
|
|
186
|
+
return operationState(context).runSignal;
|
|
187
|
+
}
|
|
188
|
+
/** Why `context`'s native run was cancelled, or null while it was not. */
|
|
189
|
+
function runCancellation(context) {
|
|
190
|
+
return operationState(context).cancelled;
|
|
191
|
+
}
|
|
192
|
+
function cancelledFailure(context, platform, { code, message }) {
|
|
193
|
+
const cancelled = runCancellation(context);
|
|
194
|
+
if (cancelled === null || code === "STIM_CLAIM_UNAVAILABLE") return null;
|
|
195
|
+
return {
|
|
196
|
+
code: "STIM_CANCELLED",
|
|
197
|
+
message: `The ${platform} run was ${cancelled} before it finished.`,
|
|
198
|
+
remedy: `Run \`stim ${platform}\` again when you want the app on a device.`,
|
|
199
|
+
lines: [`it stopped at ${code ?? "an unfinished step"}${message ? `: ${message}` : ""}`]
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function cancelOnAbort({ context, root, claim, write, controller }) {
|
|
203
|
+
const state = operationState(context);
|
|
204
|
+
const cancel = () => {
|
|
205
|
+
if (controller.signal.aborted) return;
|
|
206
|
+
const request = cancelRequestFor(root, claim.claimId);
|
|
207
|
+
const cancelled = request ? `cancelled by \`stim stop\` (pid ${request.pid})` : "cancelled by an interrupt";
|
|
208
|
+
state.cancelled = cancelled;
|
|
209
|
+
state.handled = true;
|
|
210
|
+
controller.abort();
|
|
211
|
+
refuseDeclaredSpawns(context, `the run was ${cancelled}`);
|
|
212
|
+
const signalled = signalDeclaredSpawns(context, "SIGINT");
|
|
213
|
+
if (signalled > 0 || request) state.draining = true;
|
|
214
|
+
write(signalled > 0 ? `${cancelled}; stopping the running build tool` : request ? `${cancelled}; stopping before the next build tool or install` : cancelled);
|
|
215
|
+
};
|
|
216
|
+
const onAbort = () => {
|
|
217
|
+
if (!isTermination(context.signal.reason)) cancel();
|
|
218
|
+
};
|
|
219
|
+
const onRequest = () => {
|
|
220
|
+
if (controller.signal.aborted || !cancelRequestFor(root, claim.claimId)) return;
|
|
221
|
+
cancel();
|
|
222
|
+
state.abortOperation?.("stop");
|
|
223
|
+
};
|
|
224
|
+
context.signal.addEventListener("abort", onAbort);
|
|
225
|
+
if (context.signal.aborted) onAbort();
|
|
226
|
+
requestListeners.set(claim.claimId, onRequest);
|
|
227
|
+
const watch = setInterval(onRequest, REQUEST_POLL_MS);
|
|
228
|
+
watch.unref();
|
|
229
|
+
return () => {
|
|
230
|
+
clearInterval(watch);
|
|
231
|
+
requestListeners.delete(claim.claimId);
|
|
232
|
+
context.signal.removeEventListener("abort", onAbort);
|
|
233
|
+
allowDeclaredSpawns(context);
|
|
234
|
+
clearNativeRunCancel(root, claim.claimId);
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Run an `ios`, `android` or `macos` invocation under the workspace's native-run lock: the claim records the
|
|
239
|
+
* command, platform and slot, and a wait for another holder is reported on `write`. An abort of `context.signal`
|
|
240
|
+
* forwards an interrupt to the running declared build tool and refuses any later one; a run `stim stop` cancelled
|
|
241
|
+
* stops before its next build tool or install. A `SIGTERM` abort reason is left to the caller.
|
|
242
|
+
*/
|
|
243
|
+
function withNativeBuildRun(context, root, details, fn, { write }) {
|
|
244
|
+
const notice = nativeRunWaitNotice({ write });
|
|
245
|
+
const state = operationState(context);
|
|
246
|
+
return withWorkspaceProcessLock(workspaceDir(root), NATIVE_RUN_LOCK, async (claim) => {
|
|
247
|
+
state.cancelled = null;
|
|
248
|
+
const controller = new AbortController();
|
|
249
|
+
state.runSignal = controller.signal;
|
|
250
|
+
const dispose = cancelOnAbort({
|
|
251
|
+
context,
|
|
252
|
+
root,
|
|
253
|
+
claim,
|
|
254
|
+
write,
|
|
255
|
+
controller
|
|
256
|
+
});
|
|
257
|
+
try {
|
|
258
|
+
return await fn(claim);
|
|
259
|
+
} finally {
|
|
260
|
+
dispose();
|
|
261
|
+
state.runSignal = void 0;
|
|
262
|
+
}
|
|
263
|
+
}, {
|
|
264
|
+
external: true,
|
|
265
|
+
signal: context.signal,
|
|
266
|
+
waitMs: NATIVE_RUN_WAIT_MS,
|
|
267
|
+
declareSpawnsFor: context,
|
|
268
|
+
details: {
|
|
269
|
+
...details,
|
|
270
|
+
interrupt: state.takesSignals ? "signal" : "request"
|
|
271
|
+
},
|
|
272
|
+
onHeld: (holder) => notice(holder)
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
//#endregion
|
|
276
|
+
export { decideStopAction as a, nativeRunWaitNotice as c, runCancellationSignal as d, withNativeBuildRun as f, shareCompilationCache as h, clearNativeRunCancel as i, requestNativeRunCancel as l, claimForEmptying as m, NATIVE_RUN_WAIT_MS as n, describeNativeRunHolder as o, cacheUser as p, cancelledFailure as r, nativeRunHolder as s, NATIVE_RUN_LOCK as t, runCancellation as u };
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { n as ensureWorkspaceStorage } from "./paths-DQtTgsBf.mjs";
|
|
2
|
+
import { l as phaseLine } from "./command-output-gwpm28fu.mjs";
|
|
3
|
+
import { r as readWorkspaceState$1 } from "./workspace-state-U08dEzhG.mjs";
|
|
4
|
+
import { j as metroPortSetting } from "./settings-C7O8A6ZI.mjs";
|
|
5
|
+
import { d as resolveProjectMetro } from "./metro-DiXtA3Ty.mjs";
|
|
6
|
+
import { Yt as LAUNCH_UNVERIFIED, qt as LAUNCH_BUNDLING } from "./budget-Cvwn54qV.mjs";
|
|
7
|
+
import { c as startDevServer } from "./start-EojN4WFz.mjs";
|
|
7
8
|
import { readIdleStop } from "@stim-cli/core/state";
|
|
8
9
|
import chalk from "chalk";
|
|
9
10
|
//#region src/commands/native-runtime.ts
|
|
10
|
-
async function ensureDevServer({ root, port, settings, settingsContext, remote, note, resolve = resolveProjectMetro, start = startDevServer, readState = readWorkspaceState$1 }) {
|
|
11
|
-
const pin = metroPortSetting(settings);
|
|
11
|
+
async function ensureDevServer({ root, port, settings, settingsContext, remote, env, note, resolve = resolveProjectMetro, start = startDevServer, readState = readWorkspaceState$1 }) {
|
|
12
|
+
const pin = metroPortSetting(settings, env);
|
|
12
13
|
const canReuse = !pin.error && (pin.port === null || pin.port === port);
|
|
13
14
|
const held = port === null || !canReuse ? null : (await resolve(port, root)).metro;
|
|
14
15
|
if (port !== null && held) return {
|
|
@@ -34,7 +35,8 @@ async function ensureDevServer({ root, port, settings, settingsContext, remote,
|
|
|
34
35
|
message: `Could not start this workspace's dev server: ${result.error.message}`,
|
|
35
36
|
remedy: result.error.remedy,
|
|
36
37
|
lines: result.lines,
|
|
37
|
-
reclaimed: result.reclaimed
|
|
38
|
+
reclaimed: result.reclaimed,
|
|
39
|
+
...result.retainedClaimRoots ? { retainedClaimRoots: result.retainedClaimRoots } : {}
|
|
38
40
|
};
|
|
39
41
|
const { facts } = result;
|
|
40
42
|
return {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { s as gitAsync } from "./operation-exec-BW0em61G.mjs";
|
|
2
|
+
import { n as fingerprintNativeInputs, r as manifestDigest } from "./native-inputs-TRTTTRxt.mjs";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { createReadStream } from "node:fs";
|
|
5
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
|
+
import { lstat, readlink, realpath } from "node:fs/promises";
|
|
7
|
+
//#region src/offload/native-source.ts
|
|
8
|
+
function* repositoryInputs(snapshot) {
|
|
9
|
+
const links = snapshot.entries.filter((entry) => entry.kind === "link").map((entry) => `${entry.path}/@target`);
|
|
10
|
+
for (const entry of snapshot.entries) {
|
|
11
|
+
if (entry.path === "repository") continue;
|
|
12
|
+
if (!entry.path.startsWith("repository/")) throw new Error("Native offload requires every input to be inside the repository.");
|
|
13
|
+
if (links.some((link) => entry.path === link || entry.path.startsWith(`${link}/`))) continue;
|
|
14
|
+
yield {
|
|
15
|
+
entry,
|
|
16
|
+
path: entry.path.slice(11)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const absentInput = (path) => /* @__PURE__ */ new Error(`Native input ${path} is ignored or absent from the source transfer; it was not uploaded.`);
|
|
21
|
+
/** Throws the same membership refusal as nativeTransferManifest, from the git-visible paths alone. */
|
|
22
|
+
function checkNativeTransferMembership(snapshot, visible) {
|
|
23
|
+
for (const { entry, path } of repositoryInputs(snapshot)) {
|
|
24
|
+
if (entry.kind === "directory" || visible.has(path)) continue;
|
|
25
|
+
for (let index = path.indexOf("/"); index !== -1; index = path.indexOf("/", index + 1)) if (visible.has(path.slice(0, index))) throw new Error(`Native input ${path} is inside the git submodule ${path.slice(0, index)}; submodules are not transferred.`);
|
|
26
|
+
throw absentInput(path);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function nativeTransferManifest(root, snapshot, visible, signal) {
|
|
30
|
+
const files = new Map(visible.map((file) => [file.path, file]));
|
|
31
|
+
signal?.throwIfAborted();
|
|
32
|
+
root = await realpath(root);
|
|
33
|
+
const selected = [];
|
|
34
|
+
const empty = createHash("sha256").update("").digest("hex");
|
|
35
|
+
for (const { entry, path } of repositoryInputs(snapshot)) {
|
|
36
|
+
signal?.throwIfAborted();
|
|
37
|
+
if (entry.kind === "directory") {
|
|
38
|
+
selected.push({
|
|
39
|
+
path,
|
|
40
|
+
kind: "directory",
|
|
41
|
+
size: 0,
|
|
42
|
+
sha256: empty
|
|
43
|
+
});
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const file = files.get(path);
|
|
47
|
+
if (!file) throw absentInput(path);
|
|
48
|
+
const kind = entry.kind === "file:0" ? "file" : entry.kind === "file:73" ? "exec" : entry.kind;
|
|
49
|
+
if (kind !== file.kind || entry.sha256 !== file.sha256) throw new Error(`Native input ${path} changed or has an unsupported executable mode.`);
|
|
50
|
+
selected.push(file);
|
|
51
|
+
if (kind === "link") {
|
|
52
|
+
const link = join(root, path);
|
|
53
|
+
const target = await readlink(link);
|
|
54
|
+
const destination = relative(root, await realpath(resolve(dirname(link), target)));
|
|
55
|
+
if (isAbsolute(target) || isAbsolute(destination) || destination === ".." || destination.startsWith(`..${sep}`)) throw new Error(`Native input ${path} has a link that cannot be relocated inside the repository.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return selected.toSorted((a, b) => a.path.localeCompare(b.path));
|
|
59
|
+
}
|
|
60
|
+
async function verifyNativeTransfer(root, files, digest, ignoredDirectoryMarkers = []) {
|
|
61
|
+
const snapshot = await fingerprintNativeInputs([{
|
|
62
|
+
name: "repository",
|
|
63
|
+
path: root
|
|
64
|
+
}], {
|
|
65
|
+
excluded: [join(root, ".git")],
|
|
66
|
+
ignoredDirectoryMarkers,
|
|
67
|
+
parameters: null
|
|
68
|
+
});
|
|
69
|
+
return manifestDigest(await nativeTransferManifest(root, snapshot, files)) === digest;
|
|
70
|
+
}
|
|
71
|
+
/** SHA-256 and byte count of one regular file, streamed without blocking the caller. */
|
|
72
|
+
async function nativeFileDigest(path, signal) {
|
|
73
|
+
const hash = createHash("sha256");
|
|
74
|
+
let size = 0;
|
|
75
|
+
try {
|
|
76
|
+
for await (const chunk of createReadStream(path, { signal })) {
|
|
77
|
+
hash.update(chunk);
|
|
78
|
+
size += chunk.length;
|
|
79
|
+
}
|
|
80
|
+
} finally {
|
|
81
|
+
signal?.throwIfAborted();
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
size,
|
|
85
|
+
sha256: hash.digest("hex")
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** The exact source a build needs: tracked and untracked, not ignored, as `git ls-files -co --exclude-standard`. */
|
|
89
|
+
async function sourceManifest(repoRoot, strict = false, signal) {
|
|
90
|
+
const files = [];
|
|
91
|
+
for (const path of await gitVisiblePaths(repoRoot, signal)) {
|
|
92
|
+
signal?.throwIfAborted();
|
|
93
|
+
const absolute = join(repoRoot, path);
|
|
94
|
+
let stat;
|
|
95
|
+
try {
|
|
96
|
+
stat = await lstat(absolute);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (strict && error.code !== "ENOENT") throw error;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (stat.isSymbolicLink()) {
|
|
102
|
+
const target = Buffer.from(await readlink(absolute));
|
|
103
|
+
files.push({
|
|
104
|
+
path,
|
|
105
|
+
kind: "link",
|
|
106
|
+
size: target.length,
|
|
107
|
+
sha256: createHash("sha256").update(target).digest("hex")
|
|
108
|
+
});
|
|
109
|
+
} else if (stat.isFile()) files.push({
|
|
110
|
+
path,
|
|
111
|
+
kind: stat.mode & 73 ? "exec" : "file",
|
|
112
|
+
...await nativeFileDigest(absolute, signal)
|
|
113
|
+
});
|
|
114
|
+
else if (strict) throw new Error(`Native source ${path} is not a file or link; transfer submodule contents explicitly.`);
|
|
115
|
+
}
|
|
116
|
+
signal?.throwIfAborted();
|
|
117
|
+
return files;
|
|
118
|
+
}
|
|
119
|
+
async function gitVisiblePaths(repoRoot, signal) {
|
|
120
|
+
const listed = await gitAsync(repoRoot, [
|
|
121
|
+
"ls-files",
|
|
122
|
+
"-z",
|
|
123
|
+
"-co",
|
|
124
|
+
"--exclude-standard"
|
|
125
|
+
], {
|
|
126
|
+
untrimmed: true,
|
|
127
|
+
timeoutMs: 12e4,
|
|
128
|
+
signal
|
|
129
|
+
});
|
|
130
|
+
return new Set(listed.split("\0").filter(Boolean));
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { sourceManifest as a, nativeTransferManifest as i, gitVisiblePaths as n, verifyNativeTransfer as o, nativeFileDigest as r, checkNativeTransferMembership as t };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { d as workspaceDir, u as workspaceDerivedData } from "./paths-DQtTgsBf.mjs";
|
|
2
|
+
import { a as killOnAbort, l as gitQuietAsync, r as childEnvironment } from "./operation-exec-BW0em61G.mjs";
|
|
3
|
+
import { h as pbxString, m as pbxReferences } from "./project-wM_XFTvE.mjs";
|
|
4
|
+
import { n as fingerprintNativeInputs, t as NativeInputError } from "./native-inputs-TRTTTRxt.mjs";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
6
7
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
7
|
-
import { createHash } from "node:crypto";
|
|
8
8
|
//#region src/integrations/native-xcode-inputs.ts
|
|
9
9
|
function nativeXcodePackages(root) {
|
|
10
10
|
return join(workspaceDir(root), "xcode-packages");
|
|
@@ -66,24 +66,30 @@ function inside(root, path) {
|
|
|
66
66
|
function fold(path) {
|
|
67
67
|
return path.normalize("NFC").toLowerCase();
|
|
68
68
|
}
|
|
69
|
-
function gitVisibility(sourceRoot) {
|
|
69
|
+
async function gitVisibility(sourceRoot, env, signal) {
|
|
70
|
+
signal?.throwIfAborted();
|
|
70
71
|
if (!existsSync(join(sourceRoot, ".git"))) return null;
|
|
71
|
-
const
|
|
72
|
+
const childEnv = childEnvironment(env);
|
|
73
|
+
const listing = await gitQuietAsync(sourceRoot, [
|
|
72
74
|
"ls-files",
|
|
73
75
|
"-z",
|
|
74
76
|
"--cached",
|
|
75
77
|
"--others",
|
|
76
78
|
"--exclude-standard"
|
|
77
79
|
], {
|
|
80
|
+
env: childEnv.env,
|
|
78
81
|
untrimmed: true,
|
|
79
82
|
omitEnv: [
|
|
83
|
+
...childEnv.omitEnv,
|
|
80
84
|
"GIT_DIR",
|
|
81
85
|
"GIT_WORK_TREE",
|
|
82
86
|
"GIT_INDEX_FILE",
|
|
83
87
|
"GIT_COMMON_DIR"
|
|
84
88
|
],
|
|
85
|
-
timeoutMs: 12e4
|
|
89
|
+
timeoutMs: 12e4,
|
|
90
|
+
onSpawn: killOnAbort(signal)
|
|
86
91
|
});
|
|
92
|
+
signal?.throwIfAborted();
|
|
87
93
|
if (listing === null) return null;
|
|
88
94
|
const listed = /* @__PURE__ */ new Set();
|
|
89
95
|
const whole = /* @__PURE__ */ new Set();
|
|
@@ -105,9 +111,9 @@ function gitVisibility(sourceRoot) {
|
|
|
105
111
|
include
|
|
106
112
|
};
|
|
107
113
|
}
|
|
108
|
-
function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root) {
|
|
114
|
+
async function nativeXcodeInputSnapshot(root, selection, parameters, env, sourceRoot = root, signal) {
|
|
109
115
|
if (selection.platform === "unknown") return { cacheIneligible: "The selected application platform cannot be resolved from its project configuration" };
|
|
110
|
-
const visibility = gitVisibility(sourceRoot);
|
|
116
|
+
const visibility = await gitVisibility(sourceRoot, env, signal);
|
|
111
117
|
const inputs = [{
|
|
112
118
|
name: "repository",
|
|
113
119
|
path: sourceRoot,
|
|
@@ -120,7 +126,7 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
|
|
|
120
126
|
];
|
|
121
127
|
const reasons = /* @__PURE__ */ new Set();
|
|
122
128
|
const environment = {};
|
|
123
|
-
for (const [name, value] of Object.entries(
|
|
129
|
+
for (const [name, value] of Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))) if (value !== void 0 && /^(?:DEVELOPER_DIR|TOOLCHAINS|SDKROOT|CFLAGS|CPPFLAGS|CXXFLAGS|OBJCFLAGS|LDFLAGS|ARCHS|ONLY_ACTIVE_ARCH|SOURCE_DATE_EPOCH|ZERO_AR_DATE|IPHONEOS_DEPLOYMENT_TARGET|MACOSX_DEPLOYMENT_TARGET|DEVELOPMENT_TEAM|XCODE_.*|SWIFT_.*|CLANG_.*|GCC_.*|OTHER_.*FLAGS|CODE_SIGN.*|PROVISIONING_.*)$/.test(name)) environment[name] = value;
|
|
124
130
|
const dependencyRoots = /* @__PURE__ */ new Map();
|
|
125
131
|
const synchronizedRoots = [];
|
|
126
132
|
const reveal = (path, complete = true) => {
|
|
@@ -144,10 +150,10 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
|
|
|
144
150
|
const result = value.replace(/\$\(([^)]+)\)|\$\{([^}]+)\}/g, (_match, parenthesized, braced) => {
|
|
145
151
|
const name = parenthesized ?? braced;
|
|
146
152
|
if (known[name] !== void 0) return known[name];
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
149
|
-
environment[name] =
|
|
150
|
-
return
|
|
153
|
+
const supplied = env[name];
|
|
154
|
+
if (supplied !== void 0) {
|
|
155
|
+
environment[name] = supplied;
|
|
156
|
+
return supplied;
|
|
151
157
|
}
|
|
152
158
|
missing = true;
|
|
153
159
|
return "";
|
|
@@ -272,8 +278,8 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
|
|
|
272
278
|
"CCC_OVERRIDE_OPTIONS",
|
|
273
279
|
"CLANG_CONFIG_FILE_USER_DIR",
|
|
274
280
|
"CLANG_CONFIG_FILE_SYSTEM_DIR"
|
|
275
|
-
]) if (
|
|
276
|
-
if (
|
|
281
|
+
]) if (env[name]) reasons.add(`Environment ${name} supplies native inputs outside the resolved project`);
|
|
282
|
+
if (env.XCODE_XCCONFIG_FILE) xcconfig(resolve(selection.container.dir, env.XCODE_XCCONFIG_FILE), selection.targetProject);
|
|
277
283
|
for (const [name, value] of Object.entries(environment)) if (/(?:FLAGS|OTHER_.*FLAGS)$/.test(name) && /(?:[/@]|(?:^|\s)-(?:I|F|L|include|isystem|iquote|iframework|ivfsoverlay|fmodule|fplugin|resource-dir|sdk))/.test(value)) reasons.add(`Environment ${name} supplies compiler inputs outside the resolved project`);
|
|
278
284
|
if (nativeXcodeHasPackages(selection)) reasons.add("Swift package manifests, plugins and transitive local dependencies have no verified input closure");
|
|
279
285
|
if (reasons.size) return { cacheIneligible: [...reasons].join("; ") };
|
|
@@ -281,8 +287,9 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
|
|
|
281
287
|
name,
|
|
282
288
|
path: realpathSync(path)
|
|
283
289
|
});
|
|
284
|
-
const snapshot = fingerprintNativeInputs(inputs, {
|
|
290
|
+
const snapshot = await fingerprintNativeInputs(inputs, {
|
|
285
291
|
excluded,
|
|
292
|
+
signal,
|
|
286
293
|
ignoredDirectoryMarkers: nativeXcodeMetadataDirectories(selection),
|
|
287
294
|
parameters: {
|
|
288
295
|
recipe: "native-xcode-v1",
|
|
@@ -298,6 +305,7 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
|
|
|
298
305
|
if (snapshot.entries.some((entry) => synchronizedRoots.some((prefix) => entry.path.startsWith(`${prefix}/`)) && /\.(?:c|cc|cpp|cxx|m|mm|h|hh|hpp|hxx|metal)$/i.test(entry.path))) return { cacheIneligible: "C-family or Metal sources need a verified compiler include dependency graph" };
|
|
299
306
|
return snapshot;
|
|
300
307
|
} catch (error) {
|
|
308
|
+
signal?.throwIfAborted();
|
|
301
309
|
return { cacheIneligible: error instanceof NativeInputError ? error.message : `Native input closure is unavailable: ${error.message}` };
|
|
302
310
|
}
|
|
303
311
|
}
|