stim 1.18.0 → 1.20.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 +21 -4
- package/dist/{activity-BxnkDZDi.mjs → activity-BrGh9EAI.mjs} +3 -3
- package/dist/{agent-device-usage-output-CZ66YA4T.mjs → agent-device-usage-output-DVyv_hWj.mjs} +7 -7
- package/dist/android-0vv-OruW.mjs +6 -0
- package/dist/android-Brx6EKvJ.mjs +1258 -0
- package/dist/{android-DC3ZLuw0.mjs → android-BsYNR81W.mjs} +103 -45
- package/dist/{android-CBwCNicO.mjs → android-CK3fpEyZ.mjs} +2 -2
- package/dist/{android-cas-BBFyr9CA.mjs → android-cas-DCAuXryb.mjs} +9 -5
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/api-run.mjs +159 -8
- package/dist/{api-D0VtFhqk.mjs → api-zuX3ynYN.mjs} +9 -7
- package/dist/api.d.mts +104 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-install-D-PUENug.mjs → app-install-0LgaQRT7.mjs} +39 -18
- package/dist/artifact-CnC0mfov.mjs +807 -0
- package/dist/artifact-DClXJNWx.mjs +772 -0
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
- package/dist/{web-DTU0uiWj.mjs → browser-web-CzBmhmgs.mjs} +136 -174
- package/dist/{budget-DIhL2BKx.mjs → budget-BONq9vXY.mjs} +3096 -3244
- package/dist/build-BixRI6sB.mjs +462 -0
- package/dist/build-plan-CP0tckNU.mjs +553 -0
- package/dist/{cache-manifest-BI7ozfmH.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/ccache-CjHQ5F8g.mjs +142 -0
- package/dist/{chrome-DJnmnS5q.mjs → chrome-Dp2lMLBe.mjs} +1 -1
- package/dist/{cli-DNJMwADx.mjs → cli-B2R8wH1F.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-DzhapoMB.mjs → client-BLy1Pw2V.mjs} +172 -165
- package/dist/collector-run.d.mts +10 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-CBtzyIgF.mjs → command-output-BjPN99ZB.mjs} +2 -2
- package/dist/{config-CgYMahz7.mjs → config-D0LhTY3S.mjs} +13 -13
- package/dist/{created-devices-DKbeWsiK.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
- package/dist/{dependency-state-xKoOypBm.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
- package/dist/{detached-entry-BLfcgc4O.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
- package/dist/{dev-client-CLnIH02x.mjs → dev-client-ClATaJoH.mjs} +2 -2
- package/dist/{device-D7oCHGWi.mjs → device-B7lsC0K1.mjs} +8 -8
- package/dist/device-DVCwAFlX.mjs +727 -0
- package/dist/{device-capacity-EUOOYr8T.mjs → device-capacity-Ca_ke1LE.mjs} +25 -15
- package/dist/device-host-worker.mjs +38 -18
- package/dist/{device-ios-6MewKKnc.mjs → device-ios-CRUqPxKw.mjs} +12 -11
- package/dist/{device-lease-Co-EwifR.mjs → device-lease-DHOBXGgS.mjs} +135 -22
- package/dist/{device-lease-run-w1xhCqIW.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
- package/dist/{device-pool-F5WvRPtD.mjs → device-pool-L2-5GxMy.mjs} +3 -3
- package/dist/{device-remote-tHbd1fKy.mjs → device-remote-Bmg42063.mjs} +17 -69
- package/dist/doctor-C2MSuMMg.mjs +515 -0
- package/dist/{doctor-B9ckYUoU.mjs → doctor-DPAqhVCK.mjs} +334 -721
- package/dist/doctor-watchman-CB4NnVZm.mjs +260 -0
- package/dist/{simslim-EHBQ2R4G.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
- package/dist/{stim-installations-aR_WsNOA.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
- package/dist/{error-diagnostics-BRXOqDzG.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
- package/dist/errors-DzkMYh8Q.mjs +205 -0
- package/dist/{exec-DWhCZDGm.mjs → exec-B81Qodjn.mjs} +69 -15
- package/dist/{gc-Dh6mXOKC.mjs → gc-PWp34zGb.mjs} +23 -22
- package/dist/{gradle-C6GKnunQ.mjs → gradle-C2OEKCCI.mjs} +50 -125
- package/dist/{guide-tm6igAaa.mjs → guide-Dai9lphv.mjs} +862 -538
- package/dist/{hosted-android-Bv285t_t.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
- package/dist/{hosted-client-C-rMtppF.mjs → hosted-client-Io01s5By.mjs} +9 -3
- package/dist/{hosted-ios-D5mNmtj4.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
- package/dist/{hosted-logs-DN8Iz4mJ.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
- package/dist/{hosted-macos-B-wEjlwG.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
- package/dist/{hosted-native-DeeOG8xZ.mjs → hosted-native-BdAQi21M.mjs} +23 -16
- package/dist/{idle-shutdown-jjtxAn5C.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
- package/dist/ios-BZ9dg2Fr.mjs +9 -0
- package/dist/{ios-B3SbOWdw.mjs → ios-CXLIUxXJ.mjs} +180 -24
- package/dist/ios-CZuv6gRv.mjs +1112 -0
- package/dist/{ios-Bvbf0SGY.mjs → ios-VGvNdsv2.mjs} +1 -1
- package/dist/{ios-device-Bn7jWDB1.mjs → ios-device-B1B14xND.mjs} +1 -1
- package/dist/{ios-device-vOaByMhw.mjs → ios-device-BreZOpM0.mjs} +3 -3
- package/dist/ios-project-B9drt_aY.mjs +197 -0
- package/dist/{ios-state-B2pES6Vs.mjs → ios-state-CjrL2qv-.mjs} +1 -1
- package/dist/js-swap-C8icNYIY.mjs +432 -0
- package/dist/launch-DxH0THLP.mjs +745 -0
- package/dist/launch-YrbqaIFj.mjs +1530 -0
- package/dist/{launch-verify-hskNcWkZ.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
- package/dist/{logs-1Ylc1Ri6.mjs → logs-DHaRNfg7.mjs} +11 -11
- package/dist/macos-C0iljhsN.mjs +2 -0
- package/dist/{macos-DF6C7wUU.mjs → macos-V_3Ui7g4.mjs} +125 -155
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -10
- package/dist/{metro-Dh8T4Ytd.mjs → metro-D_j9sN-B.mjs} +209 -43
- package/dist/{metro-gateway-CEUw9RMH.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
- package/dist/miss-reason-BPAzZS0r.mjs +238 -0
- package/dist/{named-ports-BFIz1Shz.mjs → named-ports-C2lvoPsb.mjs} +12 -5
- package/dist/native-android-lHzaew7r.mjs +226 -0
- package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
- package/dist/{native-runtime-D_603JiC.mjs → native-runtime-BRmWL7ru.mjs} +9 -8
- package/dist/native-xcode-inputs-eutS19jU.mjs +307 -0
- package/dist/native-xcode-ios-DP3cHLwu.mjs +434 -0
- package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
- package/dist/offload-worker.d.mts +12 -6
- package/dist/offload-worker.mjs +409 -73
- package/dist/{ownership-D6Se7gg_.mjs → ownership-DXzMMSx6.mjs} +2 -2
- package/dist/{placement-log-BcPhRwR4.mjs → placement-log-reFbjqEr.mjs} +7 -3
- package/dist/plan-BDk2AeY_.mjs +260 -0
- package/dist/plan-placement-D_YYlE6N.mjs +73 -0
- package/dist/{ports-BLTtfBq-.mjs → ports-jzvAJXXL.mjs} +3 -3
- package/dist/{prebuild-juCyreaR.mjs → prebuild-Bw44QxVh.mjs} +4 -4
- package/dist/{preview-D5V07Nrl.mjs → preview-BaBJ72Al.mjs} +51 -34
- package/dist/project-B8_duAzW.mjs +1067 -0
- package/dist/project-plan-BPwbLwQu.mjs +10 -0
- package/dist/{pull-request-u4vp7zmK.mjs → pull-request-vOhLNmIb.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-android-chm1DMlA.mjs +921 -0
- package/dist/react-native-build-oAw6gQeW.mjs +239 -0
- package/dist/react-native-doctor-DYXoh-6I.mjs +78 -0
- package/dist/react-native-ios-SCTK_CT5.mjs +595 -0
- package/dist/{recordings-BAWltsVt.mjs → recordings-Bk-VivUV.mjs} +1 -1
- package/dist/{reload-DvyWzVjJ.mjs → reload-D34GkY78.mjs} +17 -14
- package/dist/remote-BU9UyhCJ.mjs +192 -0
- package/dist/{remote-cache-BGg7aGIZ.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
- package/dist/result-BDoRk1k3.mjs +186 -0
- package/dist/{run-vhtDgpHO.mjs → run-qvff78hv.mjs} +3 -3
- package/dist/{server-bare-B9E7S1aR.mjs → server-bare-dWjAarki.mjs} +6 -6
- package/dist/server-command-7XIKlWtO.mjs +69 -0
- package/dist/{server-expo-DoBHhuzK.mjs → server-expo-CsYu2aKL.mjs} +107 -82
- package/dist/server-expo-DV43vep4.mjs +2 -0
- package/dist/settings-Bbztm4oV.mjs +1503 -0
- package/dist/{settings-Byp2AQ_E.mjs → settings-CT3E71-i.mjs} +6 -7
- package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
- package/dist/settings.schema.json +156 -6
- package/dist/simslim-ChMfe8rg.mjs +149 -0
- package/dist/{slot-launch-C1nqh4mu.mjs → slot-launch-B9hn96wd.mjs} +6 -6
- package/dist/{stage-g_WqWeaE.mjs → stage-BNKKdDNc.mjs} +6 -3
- package/dist/start-CbQCSnXQ.mjs +2 -0
- package/dist/{start-D-IeOyoK.mjs → start-CdvcTaXr.mjs} +113 -77
- package/dist/{state-xnqpx3AD.mjs → state-Boo0IMJq.mjs} +4 -2
- package/dist/{state-BG-aAk4k.mjs → state-DI84A-uu.mjs} +29 -10
- package/dist/{stats-DY6ekz8F.mjs → stats-BIIDrjA8.mjs} +6 -6
- package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
- package/dist/{status-DCjZeE-K.mjs → status-DARMkc9q.mjs} +80 -294
- package/dist/status-watch-DvmI3SmN.mjs +296 -0
- package/dist/{stim-desktop-Behws_fi.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
- package/dist/{stop-DIJtD2GL.mjs → stop-CCZS-C9m.mjs} +2 -2
- package/dist/stop-WQPQHLuy.mjs +72 -0
- package/dist/{stop-BTjs3xbc.mjs → stop-iNemHsJC.mjs} +81 -33
- package/dist/supervisor-run.d.mts +7 -2
- package/dist/supervisor-run.mjs +32 -20
- package/dist/{support-Bwvbrq5-.mjs → support-CnE_SIjt.mjs} +17 -7
- package/dist/{support-BaayeYCf.mjs → support-DCco5fut.mjs} +61 -8
- package/dist/swiftpm-macos-afeNUExW.mjs +119 -0
- package/dist/{native-run-B06FkmZx.mjs → tailnet-CoJUb2tB.mjs} +113 -6
- package/dist/toolchain-BIupIro1.mjs +2 -0
- package/dist/{toolchain-Bnyd_K3A.mjs → toolchain-DqyDXs30.mjs} +225 -315
- package/dist/{trigger-CJMhwXe8.mjs → trigger-C0MWBi8O.mjs} +3 -3
- package/dist/trigger-SHLOWJ4O.mjs +2 -0
- package/dist/{warm-progress-CjB-MP6H.mjs → warm-progress-C3ASD6z5.mjs} +134 -37
- package/dist/{status-Dcr0Qexd.mjs → watchman-CQl51YZu.mjs} +75 -7
- package/dist/web-B3eldHFH.mjs +123 -0
- package/dist/web-BLXpOe6b.mjs +2 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-C59dqG-Z.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
- package/dist/{workspaces-xXItD8Dj.mjs → workspaces-D2xSHBDY.mjs} +1297 -1211
- package/dist/{worktree-BSYlofkq.mjs → worktree-BxDqaTev.mjs} +102 -63
- package/dist/worktree-q7_OZNY0.mjs +2 -0
- package/package.json +8 -6
- package/shim/bundle-response.cjs +2 -1
- package/shim/bundle-response.d.cts +1 -1
- package/shim/expo-metro-config.cjs +1 -1
- package/shim/native-android.gradle +101 -0
- package/dist/android-BKA16DTf.mjs +0 -4
- package/dist/android-BvwuMUJ9.mjs +0 -3572
- package/dist/guide-status-Bhf9SJXc.mjs +0 -125
- package/dist/ios-CPdkoKaa.mjs +0 -3953
- package/dist/ios-DNpdygiv.mjs +0 -7
- package/dist/macos-Ck7OBMNY.mjs +0 -2
- package/dist/metro-store-BAHFcJm6.mjs +0 -106
- package/dist/plan-placement-CtxkCO54.mjs +0 -1859
- package/dist/project-C3ChRLZy.mjs +0 -212
- package/dist/projects-DD7dBTCj.mjs +0 -92
- package/dist/server-expo-Db9HBUoa.mjs +0 -2
- package/dist/settings-CQyMElEP.mjs +0 -701
- package/dist/start-NTc1Ifqs.mjs +0 -2
- package/dist/stop-BGhKMOuH.mjs +0 -48
- package/dist/trigger-DWAq9hkw.mjs +0 -2
- package/dist/web-B6_bFDn7.mjs +0 -2
- package/dist/worktree-BJfnU6r5.mjs +0 -2
- package/dist/worktree-CsKYexJM.mjs +0 -753
|
@@ -1,153 +1,18 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { b as workspaceDerivedData } from "./workspace-state-CSIFuuDa.mjs";
|
|
2
3
|
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
|
|
3
|
-
import { a as formatElapsed, l as phaseLine } from "./command-output-
|
|
4
|
-
import {
|
|
5
|
-
import { h as resolvePackageJson } from "./project-C3ChRLZy.mjs";
|
|
6
|
-
import { _ as workspaceDerivedData, f as sharedCcache$1, p as sharedCompilationCache$1, x as workspaceLogsDir$1 } from "./workspace-state-C59dqG-Z.mjs";
|
|
7
|
-
import { r as register } from "./cache-manifest-BI7ozfmH.mjs";
|
|
8
|
-
import { o as machineNumber } from "./budget-DIhL2BKx.mjs";
|
|
4
|
+
import { a as formatElapsed, l as phaseLine } from "./command-output-BjPN99ZB.mjs";
|
|
5
|
+
import { o as androidHome } from "./android-BsYNR81W.mjs";
|
|
9
6
|
import { a as spawnDeclared } from "./spawn-claims-Kqiifsk2.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { t as cleanLine } from "./server-expo-DoBHhuzK.mjs";
|
|
7
|
+
import { p as resolveOptimizations } from "./errors-DzkMYh8Q.mjs";
|
|
8
|
+
import { t as cleanLine } from "./server-expo-CsYu2aKL.mjs";
|
|
13
9
|
import { createRequire } from "node:module";
|
|
14
|
-
import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
10
|
+
import { existsSync, mkdtempSync, readFileSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
15
11
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
16
12
|
import { stimBuildDigest } from "@stim-cli/core/state";
|
|
17
13
|
import { fileURLToPath } from "node:url";
|
|
18
|
-
import { homedir } from "node:os";
|
|
19
|
-
import chalk from "chalk";
|
|
20
14
|
import { createHash } from "node:crypto";
|
|
21
|
-
|
|
22
|
-
const STATS_LOG_FILE = "ccache-stats.log";
|
|
23
|
-
const CCACHE_UNAVAILABLE = {
|
|
24
|
-
status: "unavailable",
|
|
25
|
-
hits: null,
|
|
26
|
-
misses: null,
|
|
27
|
-
hitRatePercent: null
|
|
28
|
-
};
|
|
29
|
-
const CCACHE_NOT_RUN = {
|
|
30
|
-
status: "not-run",
|
|
31
|
-
hits: null,
|
|
32
|
-
misses: null,
|
|
33
|
-
hitRatePercent: null
|
|
34
|
-
};
|
|
35
|
-
function ccacheStatsLog(root) {
|
|
36
|
-
return join(workspaceLogsDir$1(root), STATS_LOG_FILE);
|
|
37
|
-
}
|
|
38
|
-
function ccacheMaxSize(config = loadConfig$1(), env = process.env) {
|
|
39
|
-
const { value, error } = machineNumber("caches.ccacheMaxGb", config, env);
|
|
40
|
-
return error || value === void 0 ? "5G" : `${value}G`;
|
|
41
|
-
}
|
|
42
|
-
function ccacheEnvironment({ binary, dir, workspaceRoot, statsLog, maxSize = "5G" }) {
|
|
43
|
-
return {
|
|
44
|
-
CMAKE_C_COMPILER_LAUNCHER: binary,
|
|
45
|
-
CMAKE_CXX_COMPILER_LAUNCHER: binary,
|
|
46
|
-
CCACHE_DIR: dir,
|
|
47
|
-
CCACHE_BASEDIR: workspaceRoot,
|
|
48
|
-
CCACHE_NOHASHDIR: "true",
|
|
49
|
-
CCACHE_SLOPPINESS,
|
|
50
|
-
CCACHE_MAXSIZE: maxSize,
|
|
51
|
-
CCACHE_STATSLOG: statsLog
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function parseCcacheBinary(output) {
|
|
55
|
-
const first = String(output ?? "").split("\n")[0]?.trim();
|
|
56
|
-
if (!first || !isAbsolute(first)) return null;
|
|
57
|
-
return first;
|
|
58
|
-
}
|
|
59
|
-
const CMAKE_LAUNCHER = /CMAKE_(C|CXX)_COMPILER_LAUNCHER\b/;
|
|
60
|
-
function projectCmakeLauncher(source) {
|
|
61
|
-
if (typeof source !== "string") return null;
|
|
62
|
-
const match = CMAKE_LAUNCHER.exec(source);
|
|
63
|
-
return match ? `CMAKE_${match[1]}_COMPILER_LAUNCHER` : null;
|
|
64
|
-
}
|
|
65
|
-
const HIT_COUNTERS = /* @__PURE__ */ new Set(["direct_cache_hit", "preprocessed_cache_hit"]);
|
|
66
|
-
function parseCcacheStatsLog(text) {
|
|
67
|
-
if (typeof text !== "string") return null;
|
|
68
|
-
let hits = 0;
|
|
69
|
-
let misses = 0;
|
|
70
|
-
for (const raw of text.split("\n")) {
|
|
71
|
-
const line = raw.trim();
|
|
72
|
-
if (HIT_COUNTERS.has(line)) hits += 1;
|
|
73
|
-
else if (line === "cache_miss") misses += 1;
|
|
74
|
-
}
|
|
75
|
-
const total = hits + misses;
|
|
76
|
-
if (total === 0) return null;
|
|
77
|
-
return {
|
|
78
|
-
status: "reported",
|
|
79
|
-
hits,
|
|
80
|
-
misses,
|
|
81
|
-
hitRatePercent: Math.round(hits / total * 1e3) / 10
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function readCcacheActivity(statsLog) {
|
|
85
|
-
let text;
|
|
86
|
-
try {
|
|
87
|
-
text = readFileSync(statsLog, "utf-8");
|
|
88
|
-
} catch {
|
|
89
|
-
return CCACHE_UNAVAILABLE;
|
|
90
|
-
}
|
|
91
|
-
return parseCcacheStatsLog(text) ?? CCACHE_UNAVAILABLE;
|
|
92
|
-
}
|
|
93
|
-
function ccacheActivityLine(activity) {
|
|
94
|
-
if (activity.status === "reported") return `${activity.hits} hits / ${activity.misses} misses (${activity.hitRatePercent}%)`;
|
|
95
|
-
if (activity.status === "not-run") return "not run; artifact cache supplied the app";
|
|
96
|
-
return "unavailable; no C++ compile went through ccache";
|
|
97
|
-
}
|
|
98
|
-
function lookupCcache() {
|
|
99
|
-
try {
|
|
100
|
-
return parseCcacheBinary(getExecutor().findExecutable("ccache"));
|
|
101
|
-
} catch {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function readOrNull$1(file) {
|
|
106
|
-
try {
|
|
107
|
-
return readFileSync(file, "utf-8");
|
|
108
|
-
} catch {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function canonical(root) {
|
|
113
|
-
try {
|
|
114
|
-
return realpathSync(root);
|
|
115
|
-
} catch {
|
|
116
|
-
return root;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function resolveCcache({ root, dir = sharedCcache$1(), lookup = lookupCcache, onNote = (line) => console.error(line) }) {
|
|
120
|
-
const binary = lookup();
|
|
121
|
-
if (!binary) {
|
|
122
|
-
onNote(chalk.dim(phaseLine("cache", "ccache off (not installed; brew install ccache)")));
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
const declared = projectCmakeLauncher(readOrNull$1(join(root, "android", "app", "build.gradle")));
|
|
126
|
-
if (declared) {
|
|
127
|
-
onNote(chalk.dim(phaseLine("cache", `ccache off (android/app/build.gradle sets ${declared} itself)`)));
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
const statsLog = ccacheStatsLog(root);
|
|
131
|
-
register({
|
|
132
|
-
dir,
|
|
133
|
-
name: "ccache",
|
|
134
|
-
prune: "atomic",
|
|
135
|
-
note: "ccache keeps itself under CCACHE_MAXSIZE, so it is emptied whole or not at all"
|
|
136
|
-
});
|
|
137
|
-
onNote(chalk.dim(phaseLine("cache", `ccache on (${dir})`)));
|
|
138
|
-
return {
|
|
139
|
-
dir,
|
|
140
|
-
statsLog,
|
|
141
|
-
env: ccacheEnvironment({
|
|
142
|
-
binary,
|
|
143
|
-
dir,
|
|
144
|
-
workspaceRoot: canonical(root),
|
|
145
|
-
statsLog,
|
|
146
|
-
maxSize: ccacheMaxSize()
|
|
147
|
-
})
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
//#endregion
|
|
15
|
+
import { homedir, tmpdir } from "node:os";
|
|
151
16
|
//#region src/engine/bundler.ts
|
|
152
17
|
const COCOAPODS_SPEC = /^ {4}cocoapods \(/m;
|
|
153
18
|
function bundlerPin(root) {
|
|
@@ -308,15 +173,6 @@ function describeDiagnostic(diagnostic) {
|
|
|
308
173
|
}
|
|
309
174
|
//#endregion
|
|
310
175
|
//#region src/engine/xcode.ts
|
|
311
|
-
const IOS_DIR = "ios";
|
|
312
|
-
const PREBUILD_REMEDY = "Generate it with `npx expo prebuild -p ios` (stim ios does this automatically for an Expo project with no ios/ directory), or commit the native project.";
|
|
313
|
-
function buildFailure(message, remedy) {
|
|
314
|
-
return { error: {
|
|
315
|
-
code: "STIM_BUILD_FAILED",
|
|
316
|
-
message,
|
|
317
|
-
remedy
|
|
318
|
-
} };
|
|
319
|
-
}
|
|
320
176
|
function pickXcodeProject(entries) {
|
|
321
177
|
const names = (Array.isArray(entries) ? entries : []).filter((e) => typeof e === "string");
|
|
322
178
|
const workspaces = names.filter((e) => e.endsWith(".xcworkspace")).toSorted();
|
|
@@ -344,22 +200,6 @@ function pickXcodeProject(entries) {
|
|
|
344
200
|
}
|
|
345
201
|
return null;
|
|
346
202
|
}
|
|
347
|
-
function discoverXcodeProject(root) {
|
|
348
|
-
const dir = join(root, IOS_DIR);
|
|
349
|
-
let entries;
|
|
350
|
-
try {
|
|
351
|
-
entries = readdirSync(dir);
|
|
352
|
-
} catch {
|
|
353
|
-
return buildFailure(`No ${IOS_DIR}/ directory in ${root}.`, PREBUILD_REMEDY);
|
|
354
|
-
}
|
|
355
|
-
const picked = pickXcodeProject(entries);
|
|
356
|
-
if (!picked) return buildFailure(`${dir} contains no .xcworkspace and no .xcodeproj.`, PREBUILD_REMEDY);
|
|
357
|
-
return {
|
|
358
|
-
...picked,
|
|
359
|
-
dir,
|
|
360
|
-
path: join(dir, picked.file)
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
203
|
function parseSchemeList(text) {
|
|
364
204
|
const empty = {
|
|
365
205
|
name: null,
|
|
@@ -429,12 +269,12 @@ function resolveScheme(project, { exec = null, scheme: requested = null } = {})
|
|
|
429
269
|
return { error: {
|
|
430
270
|
code: "STIM_NO_SCHEME",
|
|
431
271
|
message: `No shared Xcode scheme named ${JSON.stringify(requested)} in ${project.path}. Available schemes: ${listing.schemes.join(", ") || "none"}.`,
|
|
432
|
-
remedy: "Pass an exact available name with --scheme, or share the intended app scheme in Xcode."
|
|
272
|
+
remedy: "Pass an exact available name with --scheme or set it in ios.scheme, or share the intended app scheme in Xcode."
|
|
433
273
|
} };
|
|
434
274
|
}
|
|
435
275
|
let scheme = pickScheme(listing.schemes, listing.name || project.name);
|
|
436
276
|
if (!scheme && project.dir) try {
|
|
437
|
-
const app = JSON.parse(readFileSync(join(project.dir, "..", "app.json"), "utf8"));
|
|
277
|
+
const app = JSON.parse(readFileSync(join(project.appRoot ?? join(project.dir, ".."), "app.json"), "utf8"));
|
|
438
278
|
scheme = pickScheme(listing.schemes, app?.name);
|
|
439
279
|
} catch {}
|
|
440
280
|
if (!scheme) {
|
|
@@ -442,7 +282,7 @@ function resolveScheme(project, { exec = null, scheme: requested = null } = {})
|
|
|
442
282
|
return { error: {
|
|
443
283
|
code: "STIM_NO_SCHEME",
|
|
444
284
|
message: `Could not select an app scheme in ${project.path} (schemes: ${found}).`,
|
|
445
|
-
remedy: listing.schemes.length > 0 ? "Pass --scheme <name
|
|
285
|
+
remedy: listing.schemes.length > 0 ? "Pass --scheme <name>, or set ios.scheme, to select the intended shared app scheme. Stim does not guess between unmatched schemes." : "Share the app scheme in Xcode (Product > Scheme > Manage Schemes, tick Shared) so xcodebuild can see it."
|
|
446
286
|
} };
|
|
447
287
|
}
|
|
448
288
|
return {
|
|
@@ -462,18 +302,6 @@ function compilationPrefixMappings(workspaceRoot, derivedDataPath) {
|
|
|
462
302
|
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) mappings.push(`${derived}=/^derived-data`);
|
|
463
303
|
return mappings.map((mapping) => /[\s"\\]/.test(mapping) ? `"${mapping.replace(/["\\]/g, "\\$&")}"` : mapping).join(" ");
|
|
464
304
|
}
|
|
465
|
-
function ccacheEnabled(podfileProperties) {
|
|
466
|
-
if (!podfileProperties || typeof podfileProperties !== "object") return false;
|
|
467
|
-
return podfileProperties["apple.ccacheEnabled"] === "true";
|
|
468
|
-
}
|
|
469
|
-
function readPodfileProperties(root) {
|
|
470
|
-
try {
|
|
471
|
-
const parsed = JSON.parse(readFileSync(join(root, IOS_DIR, "Podfile.properties.json"), "utf-8"));
|
|
472
|
-
return parsed && typeof parsed === "object" ? parsed : null;
|
|
473
|
-
} catch {
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
305
|
const SWIFT_PREFIX_MAPPING_MIN_SWIFT = {
|
|
478
306
|
major: 6,
|
|
479
307
|
minor: 4
|
|
@@ -483,40 +311,12 @@ function swiftPrefixMappingSupported(version) {
|
|
|
483
311
|
const min = SWIFT_PREFIX_MAPPING_MIN_SWIFT;
|
|
484
312
|
return version.major > min.major || version.major === min.major && version.minor >= min.minor;
|
|
485
313
|
}
|
|
486
|
-
|
|
487
|
-
major: 0,
|
|
488
|
-
minor: 87
|
|
489
|
-
};
|
|
490
|
-
function reactNativeSupportsSwiftCache(version) {
|
|
491
|
-
if (!version) return false;
|
|
492
|
-
const min = SWIFT_CACHE_MIN_REACT_NATIVE;
|
|
493
|
-
return version.major > min.major || version.major === min.major && version.minor >= min.minor;
|
|
494
|
-
}
|
|
495
|
-
function parseReactNativeVersion(packageJson) {
|
|
496
|
-
if (!packageJson || typeof packageJson !== "object") return null;
|
|
497
|
-
const raw = packageJson.version;
|
|
498
|
-
const m = typeof raw === "string" ? /^(\d+)\.(\d+)\./.exec(raw) : null;
|
|
499
|
-
if (!m || m[1] === void 0 || m[2] === void 0) return null;
|
|
500
|
-
return {
|
|
501
|
-
major: parseInt(m[1], 10),
|
|
502
|
-
minor: parseInt(m[2], 10)
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
function detectReactNativeVersion(root) {
|
|
506
|
-
const file = resolvePackageJson(root, "react-native");
|
|
507
|
-
if (!file) return null;
|
|
508
|
-
try {
|
|
509
|
-
return parseReactNativeVersion(JSON.parse(readFileSync(file, "utf-8")));
|
|
510
|
-
} catch {
|
|
511
|
-
return null;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
function compilationCacheSettings({ workspaceRoot, derivedDataPath, casPath, xcodeMajor, swiftVersion = null, reactNativeVersion = null, ccache = false, optimizations = resolveOptimizations({}, {}).ios }) {
|
|
314
|
+
function compilationCacheSettings({ workspaceRoot, derivedDataPath, casPath, xcodeMajor, swiftVersion = null, swiftCacheCompatible = false, ccache = false, optimizations = resolveOptimizations({}, {}).ios }) {
|
|
515
315
|
if (xcodeMajor === null || xcodeMajor === void 0) return [];
|
|
516
316
|
if (xcodeMajor < 26) return [];
|
|
517
317
|
if (ccache) return [];
|
|
518
318
|
const swiftMappable = swiftPrefixMappingSupported(swiftVersion);
|
|
519
|
-
const auto = swiftMappable &&
|
|
319
|
+
const auto = swiftMappable && swiftCacheCompatible;
|
|
520
320
|
const swift = optimizations.compilationCache && (optimizations.swiftCompilationCache ?? auto);
|
|
521
321
|
const mappings = optimizations.prefixMapping ? compilationPrefixMappings(workspaceRoot, derivedDataPath) : "";
|
|
522
322
|
return [
|
|
@@ -552,34 +352,6 @@ function parseXcodeMajor(output) {
|
|
|
552
352
|
function detectXcodeMajor(exec = null) {
|
|
553
353
|
return parseXcodeMajor((exec || getExecutor()).runQuiet("xcodebuild -version", { timeoutMs: 1e4 }));
|
|
554
354
|
}
|
|
555
|
-
function resolveCompilationCacheSettings({ root, derivedDataPath, exec = null, casPath = sharedCompilationCache$1(), optimizations = resolveOptimizations({}, {}).ios, onNote = (line) => console.error(line) }) {
|
|
556
|
-
const xcodeMajor = detectXcodeMajor(exec);
|
|
557
|
-
const ccache = ccacheEnabled(readPodfileProperties(root));
|
|
558
|
-
const probe = xcodeMajor !== null && xcodeMajor >= 26 && !ccache && optimizations.compilationCache && optimizations.swiftCompilationCache !== false;
|
|
559
|
-
const swiftVersion = probe ? detectSwiftVersion(exec) : null;
|
|
560
|
-
const reactNativeVersion = probe ? detectReactNativeVersion(root) : null;
|
|
561
|
-
const settings = compilationCacheSettings({
|
|
562
|
-
workspaceRoot: root,
|
|
563
|
-
derivedDataPath,
|
|
564
|
-
casPath,
|
|
565
|
-
xcodeMajor,
|
|
566
|
-
swiftVersion,
|
|
567
|
-
reactNativeVersion,
|
|
568
|
-
ccache,
|
|
569
|
-
optimizations
|
|
570
|
-
});
|
|
571
|
-
if (settings.length > 0 && optimizations.compilationCache) {
|
|
572
|
-
register({
|
|
573
|
-
dir: casPath,
|
|
574
|
-
name: "Xcode compilation cache",
|
|
575
|
-
prune: "atomic",
|
|
576
|
-
note: "shared Xcode compilation cache"
|
|
577
|
-
});
|
|
578
|
-
const swift = settings.includes("SWIFT_ENABLE_COMPILE_CACHE=YES") ? settings.includes("SWIFT_ENABLE_PREFIX_MAPPING=YES") ? "Swift on" : "Swift on, unmapped" : swiftVersion && !swiftPrefixMappingSupported(swiftVersion) ? `Swift off, ${swiftVersion.major}.${swiftVersion.minor} < ${SWIFT_PREFIX_MAPPING_MIN_SWIFT.major}.${SWIFT_PREFIX_MAPPING_MIN_SWIFT.minor}` : swiftVersion && reactNativeVersion && !reactNativeSupportsSwiftCache(reactNativeVersion) ? `Swift off, react-native ${reactNativeVersion.major}.${reactNativeVersion.minor} < ${SWIFT_CACHE_MIN_REACT_NATIVE.major}.${SWIFT_CACHE_MIN_REACT_NATIVE.minor}` : "Swift off";
|
|
579
|
-
onNote(chalk.dim(phaseLine("cache", `compilation cache on (CAS at ${casPath}, ${swift})`)));
|
|
580
|
-
}
|
|
581
|
-
return settings;
|
|
582
|
-
}
|
|
583
355
|
function xcodebuildArgs({ project, scheme, udid = null, destination = null, configuration = "Debug", sdk = "iphonesimulator", derivedDataPath, extraArgs = [], buildSettings = [] }) {
|
|
584
356
|
return [
|
|
585
357
|
project.flag,
|
|
@@ -782,13 +554,13 @@ function compilationCacheActivityLine(activity) {
|
|
|
782
554
|
if (activity.status === "not-run") return "not run; artifact cache supplied the app";
|
|
783
555
|
return "unavailable; Xcode did not report reliable statistics";
|
|
784
556
|
}
|
|
785
|
-
async function
|
|
786
|
-
if (!root || typeof root !== "string") throw new TypeError("
|
|
787
|
-
if (!logWriter || typeof logWriter.write !== "function") throw new TypeError("
|
|
788
|
-
if (!udid && !destination) throw new TypeError("
|
|
557
|
+
async function buildXcode({ root, udid = null, logWriter, project, scheme = null, configuration = "Debug", applicationTarget, sdk = "iphonesimulator", destination = null, arch = null, derivedDataPath = null, extraArgs = [], compilationCache, startedAt: clockStart, now = () => Date.now(), exec = null, heartbeatMs = HEARTBEAT_INTERVAL_MS, estimateMs = null, onHeartbeat = (line) => console.error(line) }) {
|
|
558
|
+
if (!root || typeof root !== "string") throw new TypeError("buildXcode requires {root}");
|
|
559
|
+
if (!logWriter || typeof logWriter.write !== "function") throw new TypeError("buildXcode requires {logWriter} with a write() method");
|
|
560
|
+
if (!udid && !destination) throw new TypeError("buildXcode requires {udid} (or an explicit {destination})");
|
|
789
561
|
const executor = exec || getExecutor();
|
|
790
562
|
const dd = derivedDataPath || (scheme ? join(workspaceDerivedData(root), `scheme-${createHash("sha256").update(scheme).digest("hex")}`) : workspaceDerivedData(root));
|
|
791
|
-
const startedAt = now();
|
|
563
|
+
const startedAt = clockStart ?? now();
|
|
792
564
|
const elapsed = () => now() - startedAt;
|
|
793
565
|
const reportError = (message, remedy) => {
|
|
794
566
|
logWriter.write({
|
|
@@ -799,23 +571,18 @@ async function buildIos({ root, udid = null, logWriter, project = null, scheme =
|
|
|
799
571
|
...remedy ? { remedy } : {}
|
|
800
572
|
});
|
|
801
573
|
};
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
}],
|
|
813
|
-
durationMs: elapsed()
|
|
814
|
-
});
|
|
815
|
-
}
|
|
816
|
-
target = discovered;
|
|
574
|
+
if (project.error) {
|
|
575
|
+
reportError(project.error.message, project.error.remedy);
|
|
576
|
+
return failedResult({
|
|
577
|
+
code: project.error.code,
|
|
578
|
+
diagnostics: [{
|
|
579
|
+
message: project.error.message,
|
|
580
|
+
remedy: project.error.remedy ?? void 0
|
|
581
|
+
}],
|
|
582
|
+
durationMs: elapsed()
|
|
583
|
+
});
|
|
817
584
|
}
|
|
818
|
-
const resolvedTarget =
|
|
585
|
+
const resolvedTarget = project;
|
|
819
586
|
const selected = resolveScheme(resolvedTarget, {
|
|
820
587
|
exec: executor,
|
|
821
588
|
scheme
|
|
@@ -832,12 +599,9 @@ async function buildIos({ root, udid = null, logWriter, project = null, scheme =
|
|
|
832
599
|
});
|
|
833
600
|
}
|
|
834
601
|
const buildScheme = selected.scheme;
|
|
835
|
-
const cacheSettings = compilationCache ===
|
|
836
|
-
root,
|
|
602
|
+
const cacheSettings = typeof compilationCache === "function" ? compilationCache({
|
|
837
603
|
derivedDataPath: dd,
|
|
838
|
-
exec: executor
|
|
839
|
-
onNote,
|
|
840
|
-
optimizations
|
|
604
|
+
exec: executor
|
|
841
605
|
}) : compilationCache || [];
|
|
842
606
|
const buildSettings = arch ? [
|
|
843
607
|
...cacheSettings,
|
|
@@ -1019,6 +783,7 @@ async function buildIos({ root, udid = null, logWriter, project = null, scheme =
|
|
|
1019
783
|
for (const item of Array.isArray(targets) ? targets : []) {
|
|
1020
784
|
const settings = item?.buildSettings;
|
|
1021
785
|
if (settings?.PRODUCT_TYPE !== "com.apple.product-type.application" || settings.PLATFORM_NAME !== sdk) continue;
|
|
786
|
+
if (applicationTarget && (settings.TARGET_NAME !== applicationTarget.name || typeof settings.PROJECT_FILE_PATH !== "string" || realpathSync(settings.PROJECT_FILE_PATH) !== realpathSync(applicationTarget.projectPath))) continue;
|
|
1022
787
|
const dir = settings.TARGET_BUILD_DIR;
|
|
1023
788
|
const name = settings.FULL_PRODUCT_NAME;
|
|
1024
789
|
if (typeof dir !== "string" || !isAbsolute(dir) || typeof name !== "string" || basename(name) !== name || !name.endsWith(".app")) continue;
|
|
@@ -1155,7 +920,7 @@ function extractRubyHead(lines) {
|
|
|
1155
920
|
}
|
|
1156
921
|
return null;
|
|
1157
922
|
}
|
|
1158
|
-
function podsAreStale(lockText, manifestText) {
|
|
923
|
+
function podsAreStale(lockText, manifestText, dir = "ios/") {
|
|
1159
924
|
const lock = normalize(lockText);
|
|
1160
925
|
const manifest = normalize(manifestText);
|
|
1161
926
|
if (lock === null && manifest === null) return {
|
|
@@ -1164,15 +929,15 @@ function podsAreStale(lockText, manifestText) {
|
|
|
1164
929
|
};
|
|
1165
930
|
if (lock === null) return {
|
|
1166
931
|
stale: true,
|
|
1167
|
-
reason:
|
|
932
|
+
reason: `${dir}Podfile.lock is missing but ${dir}Pods exists`
|
|
1168
933
|
};
|
|
1169
934
|
if (manifest === null) return {
|
|
1170
935
|
stale: true,
|
|
1171
|
-
reason:
|
|
936
|
+
reason: `${dir}Pods/Manifest.lock is missing (pods have never been installed here)`
|
|
1172
937
|
};
|
|
1173
938
|
if (lock !== manifest) return {
|
|
1174
939
|
stale: true,
|
|
1175
|
-
reason:
|
|
940
|
+
reason: `${dir}Podfile.lock and ${dir}Pods/Manifest.lock differ`
|
|
1176
941
|
};
|
|
1177
942
|
return { stale: false };
|
|
1178
943
|
}
|
|
@@ -1180,14 +945,13 @@ function normalize(text) {
|
|
|
1180
945
|
if (typeof text !== "string") return null;
|
|
1181
946
|
return text.replace(/\r\n/g, "\n").trimEnd();
|
|
1182
947
|
}
|
|
1183
|
-
function
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1186
|
-
function readPodState(root) {
|
|
948
|
+
function readPodState(root, directory = join(root, "ios")) {
|
|
949
|
+
const rel = relative(root, directory);
|
|
1187
950
|
return {
|
|
1188
|
-
hasPodfile: existsSync(
|
|
1189
|
-
lockText: readOrNull(join(
|
|
1190
|
-
manifestText: readOrNull(join(
|
|
951
|
+
hasPodfile: existsSync(join(directory, "Podfile")),
|
|
952
|
+
lockText: readOrNull(join(directory, "Podfile.lock")),
|
|
953
|
+
manifestText: readOrNull(join(directory, "Pods", "Manifest.lock")),
|
|
954
|
+
dir: rel ? `${rel}/` : ""
|
|
1191
955
|
};
|
|
1192
956
|
}
|
|
1193
957
|
function readOrNull(file) {
|
|
@@ -1200,7 +964,96 @@ function readOrNull(file) {
|
|
|
1200
964
|
function podEnv(root, options = {}) {
|
|
1201
965
|
return podEnvForRuby(readRubyVersion(root), options);
|
|
1202
966
|
}
|
|
1203
|
-
|
|
967
|
+
const LOGIN_ENV_BEGIN = "@@ruby-env-begin@@";
|
|
968
|
+
const LOGIN_ENV_END = "@@ruby-env-end@@";
|
|
969
|
+
const LOGIN_ENV_SCRIPT = `printf '\\n${LOGIN_ENV_BEGIN}\\nPATH=%s\\nGEM_HOME=%s\\nGEM_PATH=%s\\n${LOGIN_ENV_END}\\n' "\$PATH" "\$GEM_HOME" "\$GEM_PATH" > "\$1"`;
|
|
970
|
+
function parseLoginRubyEnv(output) {
|
|
971
|
+
const lines = output.split("\n").map((line) => line.replace(/\r$/, ""));
|
|
972
|
+
const begin = lines.lastIndexOf(LOGIN_ENV_BEGIN);
|
|
973
|
+
const end = lines.indexOf(LOGIN_ENV_END, begin + 1);
|
|
974
|
+
if (begin < 0 || end < 0) return null;
|
|
975
|
+
const out = {};
|
|
976
|
+
for (const line of lines.slice(begin + 1, end)) {
|
|
977
|
+
const eq = line.indexOf("=");
|
|
978
|
+
if (eq < 0) continue;
|
|
979
|
+
const key = line.slice(0, eq);
|
|
980
|
+
const value = line.slice(eq + 1);
|
|
981
|
+
if (value && (key === "PATH" || key === "GEM_HOME" || key === "GEM_PATH")) out[key] = value;
|
|
982
|
+
}
|
|
983
|
+
return out;
|
|
984
|
+
}
|
|
985
|
+
const loginRubyEnvByShell = /* @__PURE__ */ new Map();
|
|
986
|
+
const LOGIN_ENV_OPTIONS = {
|
|
987
|
+
timeoutMs: 1e4,
|
|
988
|
+
killSignal: "SIGKILL",
|
|
989
|
+
detachedSilent: true
|
|
990
|
+
};
|
|
991
|
+
function readLoginRubyEnv(shell = process.env.SHELL, platform = process.platform) {
|
|
992
|
+
if (platform !== "darwin" || !shell || !isAbsolute(shell)) return null;
|
|
993
|
+
if (loginRubyEnvByShell.has(shell)) return loginRubyEnvByShell.get(shell) ?? null;
|
|
994
|
+
let dir = null;
|
|
995
|
+
let parsed = null;
|
|
996
|
+
try {
|
|
997
|
+
dir = mkdtempSync(join(tmpdir(), "stim-ruby-env-"));
|
|
998
|
+
const file = join(dir, "env");
|
|
999
|
+
getExecutor().runFile(shell, [
|
|
1000
|
+
"-lic",
|
|
1001
|
+
LOGIN_ENV_SCRIPT,
|
|
1002
|
+
"stim",
|
|
1003
|
+
file
|
|
1004
|
+
], LOGIN_ENV_OPTIONS);
|
|
1005
|
+
parsed = parseLoginRubyEnv(readFileSync(file, "utf-8"));
|
|
1006
|
+
} catch {
|
|
1007
|
+
parsed = null;
|
|
1008
|
+
} finally {
|
|
1009
|
+
if (dir) rmSync(dir, {
|
|
1010
|
+
recursive: true,
|
|
1011
|
+
force: true
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
loginRubyEnvByShell.set(shell, parsed);
|
|
1015
|
+
return parsed;
|
|
1016
|
+
}
|
|
1017
|
+
async function readLoginRubyEnvAsync(shell = process.env.SHELL, platform = process.platform) {
|
|
1018
|
+
if (platform !== "darwin" || !shell || !isAbsolute(shell)) return null;
|
|
1019
|
+
if (loginRubyEnvByShell.has(shell)) return loginRubyEnvByShell.get(shell) ?? null;
|
|
1020
|
+
let dir = null;
|
|
1021
|
+
let parsed = null;
|
|
1022
|
+
try {
|
|
1023
|
+
dir = mkdtempSync(join(tmpdir(), "stim-ruby-env-"));
|
|
1024
|
+
const file = join(dir, "env");
|
|
1025
|
+
await getExecutor().runFileAsync(shell, [
|
|
1026
|
+
"-lic",
|
|
1027
|
+
LOGIN_ENV_SCRIPT,
|
|
1028
|
+
"stim",
|
|
1029
|
+
file
|
|
1030
|
+
], LOGIN_ENV_OPTIONS);
|
|
1031
|
+
parsed = parseLoginRubyEnv(readFileSync(file, "utf-8"));
|
|
1032
|
+
} catch {
|
|
1033
|
+
parsed = null;
|
|
1034
|
+
} finally {
|
|
1035
|
+
if (dir) rmSync(dir, {
|
|
1036
|
+
recursive: true,
|
|
1037
|
+
force: true
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
loginRubyEnvByShell.set(shell, parsed);
|
|
1041
|
+
return parsed;
|
|
1042
|
+
}
|
|
1043
|
+
function rubyPathEntries(login, callerPath, exists) {
|
|
1044
|
+
const have = new Set((callerPath ?? "").split(delimiter));
|
|
1045
|
+
const gemDirs = [login.GEM_HOME, ...(login.GEM_PATH ?? "").split(delimiter)].filter((dir) => !!dir);
|
|
1046
|
+
return (login.PATH ?? "").split(delimiter).filter((entry) => {
|
|
1047
|
+
if (!entry || have.has(entry)) return false;
|
|
1048
|
+
if (gemDirs.some((gem) => entry === gem || entry.startsWith(gem + sep))) return true;
|
|
1049
|
+
return exists(join(entry, "ruby")) || exists(join(entry, "pod"));
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
function prependPath(entries, existing) {
|
|
1053
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1054
|
+
return [...entries, ...(existing ?? "").split(delimiter)].filter((entry) => entry && !seen.has(entry) && seen.add(entry)).join(delimiter);
|
|
1055
|
+
}
|
|
1056
|
+
function podEnvForRuby(version, { env = process.env, home = homedir(), exists = existsSync, loginEnv = readLoginRubyEnv } = {}) {
|
|
1204
1057
|
const out = {
|
|
1205
1058
|
...env,
|
|
1206
1059
|
FORCE_COLOR: "0",
|
|
@@ -1208,8 +1061,7 @@ function podEnvForRuby(version, { env = process.env, home = homedir(), exists =
|
|
|
1208
1061
|
LANG: env.LANG ?? "en_US.UTF-8",
|
|
1209
1062
|
LC_ALL: env.LC_ALL ?? env.LANG ?? "en_US.UTF-8"
|
|
1210
1063
|
};
|
|
1211
|
-
|
|
1212
|
-
const candidates = [
|
|
1064
|
+
const candidates = version ? [
|
|
1213
1065
|
{ bin: join(home, ".rbenv", "versions", version, "bin") },
|
|
1214
1066
|
{
|
|
1215
1067
|
bin: join(home, ".rvm", "rubies", `ruby-${version}`, "bin"),
|
|
@@ -1217,7 +1069,7 @@ function podEnvForRuby(version, { env = process.env, home = homedir(), exists =
|
|
|
1217
1069
|
},
|
|
1218
1070
|
{ bin: join(home, ".asdf", "installs", "ruby", version, "bin") },
|
|
1219
1071
|
{ bin: join(home, ".local", "share", "mise", "installs", "ruby", version, "bin") }
|
|
1220
|
-
];
|
|
1072
|
+
] : [];
|
|
1221
1073
|
for (const c of candidates) {
|
|
1222
1074
|
if (!exists(c.bin)) continue;
|
|
1223
1075
|
out.PATH = `${c.bin}${delimiter}${out.PATH ?? ""}`;
|
|
@@ -1225,10 +1077,27 @@ function podEnvForRuby(version, { env = process.env, home = homedir(), exists =
|
|
|
1225
1077
|
out.GEM_HOME = c.gems;
|
|
1226
1078
|
out.GEM_PATH = c.gems;
|
|
1227
1079
|
}
|
|
1228
|
-
|
|
1080
|
+
return out;
|
|
1229
1081
|
}
|
|
1082
|
+
if (env.GEM_HOME) return out;
|
|
1083
|
+
const login = loginEnv();
|
|
1084
|
+
if (!login) return out;
|
|
1085
|
+
const rubyPath = rubyPathEntries(login, out.PATH, exists);
|
|
1086
|
+
if (rubyPath.length) out.PATH = prependPath(rubyPath, out.PATH);
|
|
1087
|
+
if (login.GEM_HOME) out.GEM_HOME = login.GEM_HOME;
|
|
1088
|
+
if (login.GEM_PATH) out.GEM_PATH = login.GEM_PATH;
|
|
1230
1089
|
return out;
|
|
1231
1090
|
}
|
|
1091
|
+
async function podEnvForRubyAsync(version) {
|
|
1092
|
+
let loginNeeded = false;
|
|
1093
|
+
const withoutLogin = podEnvForRuby(version, { loginEnv: () => {
|
|
1094
|
+
loginNeeded = true;
|
|
1095
|
+
return null;
|
|
1096
|
+
} });
|
|
1097
|
+
if (!loginNeeded) return withoutLogin;
|
|
1098
|
+
const login = await readLoginRubyEnvAsync();
|
|
1099
|
+
return podEnvForRuby(version, { loginEnv: () => login });
|
|
1100
|
+
}
|
|
1232
1101
|
function readRubyVersion(root, { read = readFileSync } = {}) {
|
|
1233
1102
|
try {
|
|
1234
1103
|
const first = String(read(join(root, ".ruby-version"), "utf-8")).split("\n").map((l) => l.trim()).find((l) => l && !l.startsWith("#"));
|
|
@@ -1399,12 +1268,12 @@ function gemInstallRemedy(root, pin) {
|
|
|
1399
1268
|
const version = readRubyVersion(root);
|
|
1400
1269
|
return `${version ? `This repo pins ruby ${version} (.ruby-version), so put that ruby on PATH (rbenv/rvm/asdf/mise) first. ` : ""}Bundler could not install the gems ${pin.lockfile} pins, so \`bundle exec pod install\` cannot run. Run \`cd ${root} && bundle install\` and fix what it reports, then run again.`;
|
|
1401
1270
|
}
|
|
1402
|
-
async function runPodInstall(root, logWriter, { spawnFn = null, now = Date.now, heartbeatMs = HEARTBEAT_INTERVAL_MS, estimateMs = null, onHeartbeat = (line) => console.error(line) } = {}) {
|
|
1403
|
-
const iosDir =
|
|
1271
|
+
async function runPodInstall(root, logWriter, { spawnFn = null, now = Date.now, heartbeatMs = HEARTBEAT_INTERVAL_MS, estimateMs = null, onHeartbeat = (line) => console.error(line), directory = join(root, "ios") } = {}) {
|
|
1272
|
+
const iosDir = directory;
|
|
1404
1273
|
if (!existsSync(iosDir)) return {
|
|
1405
1274
|
failed: true,
|
|
1406
1275
|
code: DEPS_ERROR,
|
|
1407
|
-
reason: `No
|
|
1276
|
+
reason: `No ${relative(root, iosDir) || "."}/ directory in ${root}, so there is nothing to pod install.`,
|
|
1408
1277
|
remedy: "Run `stim ios` on a project with native iOS sources, or let prebuild generate them.",
|
|
1409
1278
|
lastLines: []
|
|
1410
1279
|
};
|
|
@@ -1515,40 +1384,71 @@ function missingPod(err) {
|
|
|
1515
1384
|
};
|
|
1516
1385
|
}
|
|
1517
1386
|
//#endregion
|
|
1518
|
-
//#region src/offload/manifest.ts
|
|
1519
|
-
function manifestDigest(entries) {
|
|
1520
|
-
const hash = createHash("sha256");
|
|
1521
|
-
for (const entry of entries.toSorted((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0)) hash.update(`${entry.path}\0${entry.kind}\0${entry.sha256}\n`);
|
|
1522
|
-
return hash.digest("hex");
|
|
1523
|
-
}
|
|
1524
|
-
//#endregion
|
|
1525
1387
|
//#region src/offload/toolchain.ts
|
|
1526
1388
|
const distDir = dirname(fileURLToPath(import.meta.url));
|
|
1527
1389
|
function quiet(file, args) {
|
|
1528
1390
|
return getExecutor().runFileQuiet(file, args, { timeoutMs: 2e4 });
|
|
1529
1391
|
}
|
|
1530
|
-
function iosToolchain(root) {
|
|
1531
|
-
return iosToolchainForRuby(readRubyVersion(root));
|
|
1392
|
+
function iosToolchain(root, native) {
|
|
1393
|
+
return iosToolchainForRuby(native ? null : readRubyVersion(root), native);
|
|
1532
1394
|
}
|
|
1533
|
-
function
|
|
1534
|
-
|
|
1395
|
+
async function quietAsync(file, args) {
|
|
1396
|
+
try {
|
|
1397
|
+
return await getExecutor().runFileAsync(file, args, { timeoutMs: 2e4 });
|
|
1398
|
+
} catch {
|
|
1399
|
+
return null;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
async function iosToolchainAsync(root) {
|
|
1403
|
+
const rubyVersion = readRubyVersion(root);
|
|
1404
|
+
const [xcode, simulatorSdk, cocoapods] = await Promise.all([
|
|
1405
|
+
quietAsync("xcodebuild", ["-version"]),
|
|
1406
|
+
quietAsync("xcrun", [
|
|
1407
|
+
"--sdk",
|
|
1408
|
+
"iphonesimulator",
|
|
1409
|
+
"--show-sdk-version"
|
|
1410
|
+
]),
|
|
1411
|
+
cocoapodsVersionAsync(rubyVersion)
|
|
1412
|
+
]);
|
|
1413
|
+
return assembleIosToolchain(xcode, simulatorSdk, cocoapods);
|
|
1414
|
+
}
|
|
1415
|
+
function iosToolchainForRuby(rubyVersion, native) {
|
|
1416
|
+
return assembleIosToolchain(quiet("xcodebuild", ["-version"]), quiet("xcrun", [
|
|
1417
|
+
"--sdk",
|
|
1418
|
+
"iphonesimulator",
|
|
1419
|
+
"--show-sdk-version"
|
|
1420
|
+
]), native ? null : cocoapodsVersion(rubyVersion));
|
|
1421
|
+
}
|
|
1422
|
+
function assembleIosToolchain(xcode, simulatorSdk, cocoapods) {
|
|
1535
1423
|
return {
|
|
1536
1424
|
stimBuild: stimBuildDigest(distDir),
|
|
1537
1425
|
arch: process.arch,
|
|
1538
1426
|
xcode: xcode ? xcode.trim().replace(/\n/g, " / ") : null,
|
|
1539
|
-
simulatorSdk:
|
|
1540
|
-
|
|
1541
|
-
"iphonesimulator",
|
|
1542
|
-
"--show-sdk-version"
|
|
1543
|
-
])?.trim() ?? null,
|
|
1544
|
-
cocoapods: cocoapodsVersion(rubyVersion)
|
|
1427
|
+
simulatorSdk: simulatorSdk?.trim() ?? null,
|
|
1428
|
+
cocoapods
|
|
1545
1429
|
};
|
|
1546
1430
|
}
|
|
1431
|
+
function podProbeEnv(env) {
|
|
1432
|
+
return Object.fromEntries(Object.entries(env).filter((entry) => entry[1] !== void 0));
|
|
1433
|
+
}
|
|
1434
|
+
function podVersionLine(output) {
|
|
1435
|
+
return output?.trim().split("\n").pop()?.trim() ?? null;
|
|
1436
|
+
}
|
|
1547
1437
|
function cocoapodsVersion(rubyVersion) {
|
|
1548
|
-
return getExecutor().runFileQuiet("pod", ["--version"], {
|
|
1438
|
+
return podVersionLine(getExecutor().runFileQuiet("pod", ["--version"], {
|
|
1549
1439
|
timeoutMs: 2e4,
|
|
1550
|
-
env:
|
|
1551
|
-
})
|
|
1440
|
+
env: podProbeEnv(podEnvForRuby(rubyVersion))
|
|
1441
|
+
}));
|
|
1442
|
+
}
|
|
1443
|
+
async function cocoapodsVersionAsync(rubyVersion) {
|
|
1444
|
+
try {
|
|
1445
|
+
return podVersionLine(await getExecutor().runFileAsync("pod", ["--version"], {
|
|
1446
|
+
timeoutMs: 2e4,
|
|
1447
|
+
env: podProbeEnv(await podEnvForRubyAsync(rubyVersion))
|
|
1448
|
+
}));
|
|
1449
|
+
} catch {
|
|
1450
|
+
return null;
|
|
1451
|
+
}
|
|
1552
1452
|
}
|
|
1553
1453
|
function macosToolchain() {
|
|
1554
1454
|
const xcode = quiet("xcodebuild", ["-version"]);
|
|
@@ -1639,7 +1539,17 @@ function sdkPackages() {
|
|
|
1639
1539
|
platforms
|
|
1640
1540
|
};
|
|
1641
1541
|
}
|
|
1642
|
-
function workerToolchain(rubyVersion = null) {
|
|
1542
|
+
function workerToolchain(rubyVersion = null, native) {
|
|
1543
|
+
if (native === "gradle") return {
|
|
1544
|
+
...androidToolchain(),
|
|
1545
|
+
xcode: null,
|
|
1546
|
+
simulatorSdk: null,
|
|
1547
|
+
cocoapods: null,
|
|
1548
|
+
macosSdk: null,
|
|
1549
|
+
bundler: null,
|
|
1550
|
+
runtimes: [],
|
|
1551
|
+
androidSdk: sdkPackages()
|
|
1552
|
+
};
|
|
1643
1553
|
let listed = null;
|
|
1644
1554
|
try {
|
|
1645
1555
|
listed = JSON.parse(quiet("xcrun", [
|
|
@@ -1651,16 +1561,16 @@ function workerToolchain(rubyVersion = null) {
|
|
|
1651
1561
|
]) ?? "null");
|
|
1652
1562
|
} catch {}
|
|
1653
1563
|
return {
|
|
1654
|
-
...iosToolchainForRuby(rubyVersion),
|
|
1655
|
-
macosSdk: quiet("xcrun", [
|
|
1564
|
+
...iosToolchainForRuby(rubyVersion, native),
|
|
1565
|
+
macosSdk: native ? null : quiet("xcrun", [
|
|
1656
1566
|
"--sdk",
|
|
1657
1567
|
"macosx",
|
|
1658
1568
|
"--show-sdk-version"
|
|
1659
1569
|
])?.trim() ?? null,
|
|
1660
|
-
bundler: quiet("bundle", ["--version"])?.trim() || null,
|
|
1570
|
+
bundler: native ? null : quiet("bundle", ["--version"])?.trim() || null,
|
|
1661
1571
|
runtimes: iphoneRuntimes(listed),
|
|
1662
|
-
jdk: localJdk(),
|
|
1663
|
-
androidSdk: sdkPackages()
|
|
1572
|
+
jdk: native ? null : localJdk(),
|
|
1573
|
+
androidSdk: native ? null : sdkPackages()
|
|
1664
1574
|
};
|
|
1665
1575
|
}
|
|
1666
1576
|
/** The API level of an SDK `platforms/` directory: `android-37.0` and `android-37` are both 37. */
|
|
@@ -1728,12 +1638,12 @@ function toolchainMismatches(target, worker) {
|
|
|
1728
1638
|
code: "simulator-sdk",
|
|
1729
1639
|
reason: versionMismatch("simulator SDK", worker.simulatorSdk, ios.simulatorSdk)
|
|
1730
1640
|
});
|
|
1731
|
-
if (target.cocoapodsPinned) {
|
|
1641
|
+
if (!target.native && target.cocoapodsPinned) {
|
|
1732
1642
|
if (!worker.bundler) out.push({
|
|
1733
1643
|
code: "bundler",
|
|
1734
1644
|
reason: "no Bundler there to run the CocoaPods this project's Gemfile.lock pins"
|
|
1735
1645
|
});
|
|
1736
|
-
} else if (worker.cocoapods !== ios.cocoapods) out.push({
|
|
1646
|
+
} else if (!target.native && worker.cocoapods !== ios.cocoapods) out.push({
|
|
1737
1647
|
code: "cocoapods",
|
|
1738
1648
|
reason: versionMismatch("CocoaPods", worker.cocoapods, ios.cocoapods)
|
|
1739
1649
|
});
|
|
@@ -1744,4 +1654,4 @@ function toolchainMismatches(target, worker) {
|
|
|
1744
1654
|
return out;
|
|
1745
1655
|
}
|
|
1746
1656
|
//#endregion
|
|
1747
|
-
export {
|
|
1657
|
+
export { readBundleId as A, compilationCacheSettings as C, parseXcodeMajor as D, parseSwiftVersion as E, describeDiagnostic as F, bundlerPin as I, podInstallCommand as L, startBuildHeartbeat as M, swiftPrefixMappingSupported as N, pickXcodeProject as O, tailLines as P, compilationCacheActivityLine as S, detectXcodeMajor as T, COMPILATION_CACHE_NOT_RUN as _, iphoneRuntimes as a, SWIFT_PREFIX_MAPPING_MIN_SWIFT as b, parseAndroidRequirements as c, DEPS_ERROR as d, podsAreStale as f, runPodInstall as g, runCaptured as h, iosToolchainAsync as i, resolveScheme as j, readBundleExecutable as k, toolchainMismatches as l, readRubyVersion as m, androidToolchain as n, jdkMajor as o, readPodState as p, iosToolchain as r, macosToolchain as s, androidRequirements as t, workerToolchain as u, COMPILATION_CACHE_UNAVAILABLE as v, detectSwiftVersion as w, buildXcode as x, HEARTBEAT_INTERVAL_MS as y };
|