stim 1.19.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 +20 -3
- package/dist/{activity-BSw0x84R.mjs → activity-BrGh9EAI.mjs} +3 -3
- package/dist/{agent-device-usage-output-Bjxu_VmX.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-BdQC6zs1.mjs → android-BsYNR81W.mjs} +103 -45
- package/dist/{android-DE5g_5gv.mjs → android-CK3fpEyZ.mjs} +2 -2
- package/dist/{android-cas-C87geAg-.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-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
- package/dist/api.d.mts +98 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-install-CFI4ptUL.mjs → app-install-0LgaQRT7.mjs} +9 -8
- package/dist/artifact-CnC0mfov.mjs +807 -0
- package/dist/artifact-DClXJNWx.mjs +772 -0
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
- package/dist/{browser-web-CDhqQxhv.mjs → browser-web-CzBmhmgs.mjs} +19 -19
- package/dist/{budget-Dz-kyXLv.mjs → budget-BONq9vXY.mjs} +3101 -3062
- package/dist/build-BixRI6sB.mjs +462 -0
- package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
- package/dist/build-plan-CP0tckNU.mjs +553 -0
- package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{manifest-CX0d1IkZ.mjs → ccache-CjHQ5F8g.mjs} +13 -19
- package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
- package/dist/{cli-C9Zvgbdc.mjs → cli-B2R8wH1F.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-CuUo8Nvg.mjs → client-BLy1Pw2V.mjs} +89 -307
- package/dist/collector-run.d.mts +4 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-Bt8ygHE7.mjs → command-output-BjPN99ZB.mjs} +2 -2
- package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
- package/dist/{created-devices-D0s26Hx5.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
- package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
- package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
- package/dist/{dev-client-CDY_zAmD.mjs → dev-client-ClATaJoH.mjs} +2 -2
- package/dist/{device-BHw0WlHl.mjs → device-B7lsC0K1.mjs} +8 -8
- package/dist/device-DVCwAFlX.mjs +727 -0
- package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-Ca_ke1LE.mjs} +13 -14
- package/dist/device-host-worker.mjs +38 -18
- package/dist/device-ios-CRUqPxKw.mjs +413 -0
- package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-DHOBXGgS.mjs} +135 -22
- package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
- package/dist/{device-pool-CP4rAsHx.mjs → device-pool-L2-5GxMy.mjs} +3 -3
- package/dist/{device-remote-B5GiUifk.mjs → device-remote-Bmg42063.mjs} +17 -68
- package/dist/doctor-C2MSuMMg.mjs +515 -0
- package/dist/{doctor-PRJH94v6.mjs → doctor-DPAqhVCK.mjs} +333 -744
- package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-CB4NnVZm.mjs} +13 -12
- package/dist/{simslim-D9LkJxIO.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
- package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
- package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
- package/dist/errors-DzkMYh8Q.mjs +205 -0
- package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
- package/dist/{gc-CyHMcKcn.mjs → gc-PWp34zGb.mjs} +21 -20
- package/dist/{device-ios-B2ruohE-.mjs → gradle-C2OEKCCI.mjs} +21 -650
- package/dist/{guide-dRaQJJk9.mjs → guide-Dai9lphv.mjs} +504 -117
- package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
- package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client-Io01s5By.mjs} +9 -3
- package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
- package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
- package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
- package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-BdAQi21M.mjs} +17 -14
- package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
- package/dist/{ios-DYUr9LGc.mjs → ios-BZ9dg2Fr.mjs} +8 -7
- package/dist/{ios-BWbHFZVz.mjs → ios-CXLIUxXJ.mjs} +180 -24
- package/dist/ios-CZuv6gRv.mjs +1112 -0
- package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
- package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
- package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BreZOpM0.mjs} +3 -3
- package/dist/ios-project-B9drt_aY.mjs +197 -0
- package/dist/{ios-state-By0XuLTQ.mjs → ios-state-CjrL2qv-.mjs} +1 -1
- package/dist/js-swap-C8icNYIY.mjs +432 -0
- package/dist/launch-DxH0THLP.mjs +745 -0
- package/dist/{react-native-ios-CSpIxexZ.mjs → launch-YrbqaIFj.mjs} +59 -612
- package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
- package/dist/{logs-Bao1HOMy.mjs → logs-DHaRNfg7.mjs} +11 -11
- package/dist/macos-C0iljhsN.mjs +2 -0
- package/dist/{macos-ciyBdTY5.mjs → macos-V_3Ui7g4.mjs} +42 -50
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -10
- package/dist/{metro-DI2AjPF_.mjs → metro-D_j9sN-B.mjs} +18 -5
- package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
- package/dist/miss-reason-BPAzZS0r.mjs +238 -0
- package/dist/{named-ports-B4iWH4E-.mjs → named-ports-C2lvoPsb.mjs} +3 -3
- package/dist/native-android-lHzaew7r.mjs +226 -0
- package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
- package/dist/{native-runtime-BGxsbfny.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 +41 -7
- package/dist/offload-worker.mjs +409 -74
- package/dist/{ownership-EB0ySdGK.mjs → ownership-DXzMMSx6.mjs} +2 -2
- package/dist/{placement-log-Dxe34rJm.mjs → placement-log-reFbjqEr.mjs} +1 -1
- package/dist/plan-BDk2AeY_.mjs +260 -0
- package/dist/plan-placement-D_YYlE6N.mjs +73 -0
- package/dist/{ports-ByPc0_97.mjs → ports-jzvAJXXL.mjs} +3 -3
- package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-Bw44QxVh.mjs} +4 -4
- package/dist/{preview-BbSottmO.mjs → preview-BaBJ72Al.mjs} +50 -32
- package/dist/project-B8_duAzW.mjs +1067 -0
- package/dist/project-plan-BPwbLwQu.mjs +10 -0
- package/dist/{pull-request-IHNdMnG8.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-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
- package/dist/{reload-rAPdqeRR.mjs → reload-D34GkY78.mjs} +17 -13
- package/dist/remote-BU9UyhCJ.mjs +192 -0
- package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
- package/dist/result-BDoRk1k3.mjs +186 -0
- package/dist/{run-lAkle1-c.mjs → run-qvff78hv.mjs} +3 -3
- package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
- package/dist/server-command-7XIKlWtO.mjs +69 -0
- package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CsYu2aKL.mjs} +107 -82
- package/dist/server-expo-DV43vep4.mjs +2 -0
- package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
- package/dist/{settings-2am7TSxp.mjs → settings-CT3E71-i.mjs} +6 -6
- package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
- package/dist/settings.schema.json +84 -0
- package/dist/simslim-ChMfe8rg.mjs +149 -0
- package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-B9hn96wd.mjs} +6 -6
- package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
- package/dist/start-CbQCSnXQ.mjs +2 -0
- package/dist/{start-DtxthMfI.mjs → start-CdvcTaXr.mjs} +97 -68
- package/dist/{state-Tp4uImDS.mjs → state-Boo0IMJq.mjs} +1 -1
- package/dist/{state-D2KtnALG.mjs → state-DI84A-uu.mjs} +29 -10
- package/dist/{stats-8EJ5ivFT.mjs → stats-BIIDrjA8.mjs} +5 -5
- package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
- package/dist/{status-BOyp0CUl.mjs → status-DARMkc9q.mjs} +81 -293
- package/dist/status-watch-DvmI3SmN.mjs +296 -0
- package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
- package/dist/{stop-DRipAg-e.mjs → stop-CCZS-C9m.mjs} +2 -2
- package/dist/{stop-D0UIpZuh.mjs → stop-WQPQHLuy.mjs} +5 -5
- package/dist/{stop-zDlknFoz.mjs → stop-iNemHsJC.mjs} +21 -20
- package/dist/supervisor-run.d.mts +7 -2
- package/dist/supervisor-run.mjs +32 -20
- package/dist/{support-DsNaFg6D.mjs → support-CnE_SIjt.mjs} +17 -7
- package/dist/{support-CNqYkV0y.mjs → support-DCco5fut.mjs} +61 -8
- package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-afeNUExW.mjs} +5 -5
- package/dist/tailnet-CoJUb2tB.mjs +265 -0
- package/dist/toolchain-BIupIro1.mjs +2 -0
- package/dist/{toolchain-C3xSoyUl.mjs → toolchain-DqyDXs30.mjs} +206 -53
- package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
- package/dist/trigger-SHLOWJ4O.mjs +2 -0
- package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-C3ASD6z5.mjs} +6 -6
- package/dist/{watchman-BL1IdOtq.mjs → watchman-CQl51YZu.mjs} +6 -6
- package/dist/{web-DbbrPUn0.mjs → web-B3eldHFH.mjs} +9 -13
- package/dist/web-BLXpOe6b.mjs +2 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
- package/dist/{workspaces-Djb2gfi9.mjs → workspaces-D2xSHBDY.mjs} +1260 -1258
- package/dist/{worktree-BL4M1rhB.mjs → worktree-BxDqaTev.mjs} +84 -48
- package/dist/worktree-q7_OZNY0.mjs +2 -0
- package/package.json +8 -6
- package/shim/native-android.gradle +101 -0
- package/dist/android-BXc6BmEi.mjs +0 -3732
- package/dist/android-BvV1gGdN.mjs +0 -4
- package/dist/ios-ITYno9rO.mjs +0 -2241
- package/dist/macos-nIOATJmR.mjs +0 -2
- package/dist/metro-store-BAHFcJm6.mjs +0 -106
- package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
- package/dist/plan-placement-BVY59qa8.mjs +0 -290
- package/dist/project-B5eQ1USs.mjs +0 -612
- package/dist/react-native-ios-BMh2i25I.mjs +0 -2
- package/dist/server-expo-DGsdUGX2.mjs +0 -2
- package/dist/start-D8NbxNBb.mjs +0 -2
- package/dist/trigger-CoalsMTV.mjs +0 -2
- package/dist/web-DFpFeZu5.mjs +0 -2
- package/dist/worktree-DV-A0LNL.mjs +0 -2
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { _ as loadConfig$1, p as getProject } from "./config-D0LhTY3S.mjs";
|
|
3
|
+
import { Ft as removeTemporaryEntry, Pt as makeTemporaryDirectory, at as detectProviders, ot as planMetroReach } from "./settings-Bbztm4oV.mjs";
|
|
4
|
+
import { w as entryDir, y as artifactIn } from "./device-lease-DHOBXGgS.mjs";
|
|
5
|
+
import { i as formatDuration, l as phaseLine, m as shortHash, u as plural } from "./command-output-BjPN99ZB.mjs";
|
|
6
|
+
import { N as readRemoteSession, j as readMetroTunnel } from "./project-B8_duAzW.mjs";
|
|
7
|
+
import { Mt as readStats$1, s as peekBudget, wt as estimateBuild } from "./budget-BONq9vXY.mjs";
|
|
8
|
+
import { a as easAuthNote, f as resolveEasCliBin, s as isEasAuthFailureText } from "./remote-cache-Bsts6f6Y.mjs";
|
|
9
|
+
import { S as hostingMachines, h as namedBuildMachine, v as resolveBuildMachine } from "./client-BLy1Pw2V.mjs";
|
|
10
|
+
import { P as readHostMemoryPressure } from "./ios-CXLIUxXJ.mjs";
|
|
11
|
+
import { r as predictBuildMiss } from "./miss-reason-BPAzZS0r.mjs";
|
|
12
|
+
import { s as peekDeviceSlots } from "./device-capacity-Ca_ke1LE.mjs";
|
|
13
|
+
import { d as requireHostedAppMode, o as call, s as connectHost } from "./hosted-client-Io01s5By.mjs";
|
|
14
|
+
import { r as readHostedNative, s as writeHostedNative } from "./ios-state-CjrL2qv-.mjs";
|
|
15
|
+
import { n as prepareHostedNative } from "./hosted-native-BdAQi21M.mjs";
|
|
16
|
+
import { h as easCliSupport, m as MIN_EAS_CLI_SIMULATOR_VERSION, p as MIN_EAS_CLI_DEVICE_VERSION, s as readInstalledEasCliVersion } from "./device-remote-Bmg42063.mjs";
|
|
17
|
+
import { i as staleNativeDirRefusal } from "./prebuild-Bw44QxVh.mjs";
|
|
18
|
+
import { automaticMachineEnabled, isJsonObject, machineCapacity, parseHostedChoice, parseHostedNativeOffer } from "@stim-cli/core/state";
|
|
19
|
+
import { resolveTieredBuild } from "@stim-cli/cache";
|
|
20
|
+
import chalk from "chalk";
|
|
21
|
+
//#region src/device-host/placement.ts
|
|
22
|
+
function local$1(code, reason, skipped = [], atCapacity = false) {
|
|
23
|
+
return {
|
|
24
|
+
kind: "local",
|
|
25
|
+
code,
|
|
26
|
+
reason,
|
|
27
|
+
skipped,
|
|
28
|
+
...atCapacity ? { atCapacity: true } : {}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function decideDevicePlacement(inputs) {
|
|
32
|
+
if ("sticky" in inputs) {
|
|
33
|
+
if ("machine" in inputs.sticky) {
|
|
34
|
+
const reason = `recorded session on ${inputs.sticky.machine}`;
|
|
35
|
+
return {
|
|
36
|
+
kind: "host",
|
|
37
|
+
code: "sticky",
|
|
38
|
+
reason,
|
|
39
|
+
machines: [{
|
|
40
|
+
machine: inputs.sticky.machine,
|
|
41
|
+
reason
|
|
42
|
+
}],
|
|
43
|
+
skipped: []
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
kind: "local",
|
|
48
|
+
code: "sticky",
|
|
49
|
+
reason: "this workspace's device runs here",
|
|
50
|
+
skipped: []
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const { platform, here, offers, buildMachine, noWait, eas } = inputs;
|
|
54
|
+
const { count, max, queued } = here.devices;
|
|
55
|
+
const room = max === 0 || count !== null && count < max;
|
|
56
|
+
const localEnabled = here.localEnabled !== false;
|
|
57
|
+
const cannotTake = !localEnabled || !room || queued > 0;
|
|
58
|
+
const atCapacity = count !== null && (!room || queued > 0);
|
|
59
|
+
const usage = max > 0 ? `${count} of ${max} devices in use` : `${count} devices in use, no device cap`;
|
|
60
|
+
const localReason = !localEnabled ? "local is disabled in remote.devicePoolDisabled" : count === null ? "cannot tell how many devices run here; local boot admission decides" : cannotTake ? `${usage}${queued ? `, ${queued} runs queued ahead` : ""}` : here.budgetRefusal ?? (here.memoryPressure !== "normal" ? `host memory pressure ${here.memoryPressure ?? "unknown"} here` : `load ${here.loadPerCore.toFixed(1)}/core here, ${usage}`);
|
|
61
|
+
const nowhere = (code, reason, skipped = [], waiting = "") => {
|
|
62
|
+
if (!localEnabled && !atCapacity) return {
|
|
63
|
+
kind: "refused",
|
|
64
|
+
code: "pool-unavailable",
|
|
65
|
+
reason,
|
|
66
|
+
skipped
|
|
67
|
+
};
|
|
68
|
+
if (!cannotTake || count === null) return local$1(code, reason + waiting, skipped);
|
|
69
|
+
if (eas?.usable) return {
|
|
70
|
+
kind: "eas",
|
|
71
|
+
code: "eas-fallback",
|
|
72
|
+
reason: `${reason}; EAS Simulator (remote.easFallback)`,
|
|
73
|
+
skipped
|
|
74
|
+
};
|
|
75
|
+
const why = eas ? [...skipped, {
|
|
76
|
+
machine: "eas",
|
|
77
|
+
code: eas.code,
|
|
78
|
+
reason: eas.reason
|
|
79
|
+
}] : skipped;
|
|
80
|
+
return localEnabled ? local$1(code, reason + waiting, why, true) : {
|
|
81
|
+
kind: "refused",
|
|
82
|
+
code: "pool-unavailable",
|
|
83
|
+
reason,
|
|
84
|
+
skipped: why,
|
|
85
|
+
atCapacity: true
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
if (!offers.length) return nowhere("no-remote-mac", "no remote Macs configured; " + localReason);
|
|
89
|
+
if (localEnabled && count === null) return local$1("device-count-unknown", localReason);
|
|
90
|
+
if (!cannotTake && here.memoryPressure === "normal" && !here.budgetRefusal && here.loadPerCore < here.maxLoadPerCore) return local$1("this-mac-free", localReason);
|
|
91
|
+
const skipped = [];
|
|
92
|
+
const admitted = [];
|
|
93
|
+
offers.forEach((probe, index) => {
|
|
94
|
+
let reason = null;
|
|
95
|
+
let code = "unreachable";
|
|
96
|
+
if ("failure" in probe) reason = probe.failure;
|
|
97
|
+
else {
|
|
98
|
+
const { offer } = probe;
|
|
99
|
+
if (offer.declined !== null) [code, reason] = ["declined", `declined: ${offer.declined}`];
|
|
100
|
+
else if (offer.platform !== platform || !offer.choice) [code, reason] = ["no-matching-device", `no matching ${platform} device choice`];
|
|
101
|
+
else if (offer.resources.memoryPressure !== "normal") [code, reason] = ["memory", "host memory pressure unknown or elevated"];
|
|
102
|
+
else if (offer.capacity.available === 0) [code, reason] = ["no-capacity", "no hosted device capacity available"];
|
|
103
|
+
else if (!cannotTake && (offer.resources.loadPerCore === null || offer.resources.loadPerCore >= here.loadPerCore)) [code, reason] = ["load", offer.resources.loadPerCore === null ? "host load unknown while this Mac has room" : "host is not less loaded than this Mac"];
|
|
104
|
+
else admitted.push({
|
|
105
|
+
machine: probe.machine,
|
|
106
|
+
offer,
|
|
107
|
+
index
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (reason) skipped.push({
|
|
111
|
+
machine: probe.machine,
|
|
112
|
+
code,
|
|
113
|
+
reason
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
admitted.sort((a, b) => Number(b.machine === buildMachine) - Number(a.machine === buildMachine) || (a.offer.resources.loadPerCore ?? Infinity) - (b.offer.resources.loadPerCore ?? Infinity) || b.offer.resources.memoryFreeBytes - a.offer.resources.memoryFreeBytes || a.index - b.index);
|
|
117
|
+
if (!admitted.length) return nowhere("no-host-admits", `${localReason}; no host admits`, skipped, localEnabled && cannotTake && !noWait ? "; waiting locally if needed" : "");
|
|
118
|
+
const machines = admitted.map(({ machine, offer }) => ({
|
|
119
|
+
machine,
|
|
120
|
+
reason: `${localReason}; ${machine}${machine === buildMachine ? " is the explicit remote Mac," : ""} load ${offer.resources.loadPerCore === null ? "unknown" : offer.resources.loadPerCore.toFixed(1) + "/core"}`
|
|
121
|
+
}));
|
|
122
|
+
return {
|
|
123
|
+
kind: "host",
|
|
124
|
+
code: "placed",
|
|
125
|
+
machines,
|
|
126
|
+
reason: machines[0].reason,
|
|
127
|
+
skipped
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/device-host/auto-placement.ts
|
|
132
|
+
async function probeHost(machine, platform, selectors, appMode) {
|
|
133
|
+
let host;
|
|
134
|
+
const deadline = Date.now() + 3e3;
|
|
135
|
+
try {
|
|
136
|
+
host = await connectHost(machine, 3e3, true);
|
|
137
|
+
requireHostedAppMode(host, platform, appMode);
|
|
138
|
+
const offer = await call(host, "device-host.offer", {
|
|
139
|
+
platform,
|
|
140
|
+
...selectors
|
|
141
|
+
}, Math.max(1, deadline - Date.now()));
|
|
142
|
+
const resources = isJsonObject(offer.resources) ? offer.resources : {};
|
|
143
|
+
const parsed = parseHostedNativeOffer({
|
|
144
|
+
...offer,
|
|
145
|
+
resources: {
|
|
146
|
+
...resources,
|
|
147
|
+
loadPerCore: resources.loadPerCore ?? 0
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
let choice = platform === "ios" ? offer.platform === "ios" ? parseHostedChoice(offer.choice) : null : parsed?.platform === "android" ? parsed.choice : null;
|
|
151
|
+
if (choice && ("runtime" in choice ? selectors.deviceType && selectors.deviceType !== choice.deviceType || selectors.runtime && selectors.runtime.replace(/^iOS /, "") !== choice.runtime.replace(/^iOS /, "") : selectors.systemImage && selectors.systemImage !== choice.systemImage || selectors.deviceProfile && selectors.deviceProfile !== choice.deviceProfile)) choice = null;
|
|
152
|
+
if (!isJsonObject(offer.capacity) || offer.declined !== null && typeof offer.declined !== "string") throw new Error("unreadable device offer");
|
|
153
|
+
return {
|
|
154
|
+
probe: {
|
|
155
|
+
machine,
|
|
156
|
+
offer: {
|
|
157
|
+
platform,
|
|
158
|
+
choice,
|
|
159
|
+
declined: offer.declined,
|
|
160
|
+
capacity: { available: typeof offer.capacity.available === "number" ? offer.capacity.available : null },
|
|
161
|
+
resources: {
|
|
162
|
+
loadPerCore: typeof resources.loadPerCore === "number" && Number.isFinite(resources.loadPerCore) && resources.loadPerCore >= 0 ? resources.loadPerCore : null,
|
|
163
|
+
memoryFreeBytes: typeof resources.memoryFreeBytes === "number" ? resources.memoryFreeBytes : 0,
|
|
164
|
+
memoryPressure: typeof resources.memoryPressure === "string" ? resources.memoryPressure : null
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
...choice ? { target: {
|
|
169
|
+
host,
|
|
170
|
+
choice,
|
|
171
|
+
session: null
|
|
172
|
+
} } : {}
|
|
173
|
+
};
|
|
174
|
+
} catch (error) {
|
|
175
|
+
return { probe: {
|
|
176
|
+
machine,
|
|
177
|
+
failure: error instanceof Error ? error.message : String(error)
|
|
178
|
+
} };
|
|
179
|
+
} finally {
|
|
180
|
+
host?.connection.close();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function hosted(target, code, reason, skipped = []) {
|
|
184
|
+
target.selection = {
|
|
185
|
+
selected: "auto",
|
|
186
|
+
reason
|
|
187
|
+
};
|
|
188
|
+
return {
|
|
189
|
+
target,
|
|
190
|
+
placement: {
|
|
191
|
+
decision: "hosted",
|
|
192
|
+
machine: target.host.machine,
|
|
193
|
+
reason
|
|
194
|
+
},
|
|
195
|
+
code,
|
|
196
|
+
skipped
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function local(code, reason, skipped = []) {
|
|
200
|
+
return {
|
|
201
|
+
target: null,
|
|
202
|
+
placement: {
|
|
203
|
+
decision: "local",
|
|
204
|
+
reason
|
|
205
|
+
},
|
|
206
|
+
code,
|
|
207
|
+
skipped
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function viaEas(code, reason, skipped) {
|
|
211
|
+
return {
|
|
212
|
+
target: null,
|
|
213
|
+
placement: {
|
|
214
|
+
decision: "eas",
|
|
215
|
+
machine: "eas",
|
|
216
|
+
reason
|
|
217
|
+
},
|
|
218
|
+
code,
|
|
219
|
+
skipped
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
async function automaticDevicePlacement({ root, slot, platform, selectors, appMode, buildMachine, noWait, eas }, { machines = hostingMachines, read = readHostedNative, write = writeHostedNative, resume = prepareHostedNative, peek = () => peekDeviceSlots({
|
|
223
|
+
platform,
|
|
224
|
+
project: getProject(root),
|
|
225
|
+
slot
|
|
226
|
+
}), capacity = machineCapacity, memory = readHostMemoryPressure, probe = probeHost, budget = peekBudget } = {}) {
|
|
227
|
+
const recorded = read(root, platform, slot)[slot];
|
|
228
|
+
if (recorded) {
|
|
229
|
+
const target = await resume(recorded.machine, selectors, recorded, platform, true, appMode);
|
|
230
|
+
if (target) return {
|
|
231
|
+
target,
|
|
232
|
+
placement: {
|
|
233
|
+
decision: "hosted",
|
|
234
|
+
machine: recorded.machine,
|
|
235
|
+
reason: recorded.reason ?? decideDevicePlacement({ sticky: { machine: recorded.machine } }).reason
|
|
236
|
+
},
|
|
237
|
+
code: "sticky",
|
|
238
|
+
skipped: [],
|
|
239
|
+
sticky: true
|
|
240
|
+
};
|
|
241
|
+
write(root, slot, null, platform);
|
|
242
|
+
}
|
|
243
|
+
const devices = peek();
|
|
244
|
+
if (devices.localLive) return {
|
|
245
|
+
...local("sticky", decideDevicePlacement({ sticky: { local: true } }).reason),
|
|
246
|
+
sticky: true
|
|
247
|
+
};
|
|
248
|
+
const configured = machines();
|
|
249
|
+
if (configured === null) throw Object.assign(/* @__PURE__ */ new Error("remote.machines is invalid. Run stim guide settings and correct it."), { code: "STIM_HOSTING_REFUSED" });
|
|
250
|
+
const config = loadConfig$1();
|
|
251
|
+
const entries = configured.filter((machine) => automaticMachineEnabled("device", machine, config));
|
|
252
|
+
const preference = resolveBuildMachine(buildMachine, process.env.STIM_REMOTE_BUILD, config?.remote?.build);
|
|
253
|
+
buildMachine = namedBuildMachine(preference) ? preference : void 0;
|
|
254
|
+
const load = capacity();
|
|
255
|
+
const here = {
|
|
256
|
+
localEnabled: automaticMachineEnabled("device", "local", config),
|
|
257
|
+
loadPerCore: load.loadPerCore,
|
|
258
|
+
maxLoadPerCore: load.maxLoadPerCore,
|
|
259
|
+
memoryPressure: memory(),
|
|
260
|
+
devices,
|
|
261
|
+
budgetRefusal: await budget(root)
|
|
262
|
+
};
|
|
263
|
+
const inputs = (offers) => ({
|
|
264
|
+
platform,
|
|
265
|
+
here,
|
|
266
|
+
offers,
|
|
267
|
+
buildMachine,
|
|
268
|
+
noWait
|
|
269
|
+
});
|
|
270
|
+
const notProbed = entries.map((machine) => ({
|
|
271
|
+
machine,
|
|
272
|
+
failure: "not probed"
|
|
273
|
+
}));
|
|
274
|
+
const early = decideDevicePlacement(inputs(notProbed));
|
|
275
|
+
const probes = early.kind === "local" && early.skipped.length === 0 ? [] : await Promise.all(entries.map((machine) => probe(machine, platform, selectors, appMode)));
|
|
276
|
+
const offers = probes.length ? probes.map((each) => each.probe) : notProbed;
|
|
277
|
+
let decision = decideDevicePlacement(inputs(offers));
|
|
278
|
+
if ((decision.kind === "local" || decision.kind === "refused") && decision.atCapacity && eas) decision = decideDevicePlacement({
|
|
279
|
+
...inputs(offers),
|
|
280
|
+
eas: await eas()
|
|
281
|
+
});
|
|
282
|
+
if (decision.kind === "refused") throw Object.assign(new Error(devicePlacementLine({
|
|
283
|
+
decision: "local",
|
|
284
|
+
reason: decision.reason
|
|
285
|
+
}, decision.skipped)), {
|
|
286
|
+
code: "STIM_HOSTING_REFUSED",
|
|
287
|
+
remedy: "Enable an available member in remote.devicePoolDisabled or select a machine explicitly."
|
|
288
|
+
});
|
|
289
|
+
if (decision.kind === "eas") return viaEas(decision.code, decision.reason, decision.skipped);
|
|
290
|
+
if (decision.kind === "local") return local(decision.code, decision.reason, decision.skipped);
|
|
291
|
+
const target = probes.find((each) => each.probe.machine === decision.machines[0].machine).target;
|
|
292
|
+
return hosted(target, decision.code, decision.reason, decision.skipped);
|
|
293
|
+
}
|
|
294
|
+
function devicePlacementLine(placement, skipped) {
|
|
295
|
+
return `${placement.machine ?? "local"}, ${placement.reason}${placement.decision !== "hosted" && skipped.length ? "; " + skipped.map((each) => `${each.machine}: ${each.reason}`).join("; ") : ""}`;
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/engine/eas-fallback.ts
|
|
299
|
+
const AVAILABILITY_TIMEOUT_MS = 3e4;
|
|
300
|
+
function unusable(code, reason) {
|
|
301
|
+
return {
|
|
302
|
+
usable: false,
|
|
303
|
+
code,
|
|
304
|
+
reason
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/** Reads `eas simulator:availability --json`: `{"available": true, ...}` on stdout, or a failure on stderr. */
|
|
308
|
+
function parseSimulatorAvailability(outcome) {
|
|
309
|
+
if ("failure" in outcome) {
|
|
310
|
+
if (outcome.timedOut) return unusable("eas-unavailable", "eas simulator:availability timed out");
|
|
311
|
+
const detail = outcome.failure.split("\n").map((line) => line.trim()).find((line) => line && !/is now available\.$|^(To upgrade|npm install|Proceeding with|\(node:|\(Use `node)/.test(line));
|
|
312
|
+
if (isEasAuthFailureText(outcome.failure)) return unusable("eas-logged-out", "eas-cli is not logged in (run eas login or set EXPO_TOKEN)");
|
|
313
|
+
return unusable("eas-unavailable", `eas simulator:availability failed${detail ? `: ${detail}` : ""}`);
|
|
314
|
+
}
|
|
315
|
+
let data = null;
|
|
316
|
+
try {
|
|
317
|
+
data = JSON.parse(outcome.stdout.slice(outcome.stdout.indexOf("{")));
|
|
318
|
+
} catch {}
|
|
319
|
+
if (typeof data !== "object" || data === null || typeof data.available !== "boolean") return unusable("eas-unavailable", "eas simulator:availability printed no availability");
|
|
320
|
+
return data.available ? { usable: true } : unusable("eas-not-enabled", "EAS Simulator is not enabled for this EAS account");
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Whether this run could use an EAS Simulator the way `--remote eas` does, without starting a session or a build.
|
|
324
|
+
* Each refusal names what `--remote eas` would refuse later, so automatic placement falls through instead.
|
|
325
|
+
*/
|
|
326
|
+
async function checkEasFallback({ root, platform, slot, release, isExpo, tunnelMode, publicUrl, deviceTypeFlag, localOnlyFlags, env = process.env, resolveBin = resolveEasCliBin, readVersion = readInstalledEasCliVersion, onPath = (bin) => getExecutor().findExecutable(bin) !== null, readTunnel = readMetroTunnel, readSession = readRemoteSession, metroPort = () => getProject(root)?.metroPort ?? null, availability = async (bin) => {
|
|
327
|
+
try {
|
|
328
|
+
return { stdout: await getExecutor().runFileAsync(bin, [
|
|
329
|
+
"simulator:availability",
|
|
330
|
+
"--json",
|
|
331
|
+
"--non-interactive"
|
|
332
|
+
], {
|
|
333
|
+
cwd: root,
|
|
334
|
+
timeoutMs: AVAILABILITY_TIMEOUT_MS
|
|
335
|
+
}) };
|
|
336
|
+
} catch (error) {
|
|
337
|
+
const err = error;
|
|
338
|
+
return {
|
|
339
|
+
failure: String(err.stderr || err.message || error),
|
|
340
|
+
timedOut: err.code === "ETIMEDOUT"
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
} }) {
|
|
344
|
+
if (slot !== "default") return unusable("eas-named-slot", `an EAS Simulator takes only the default slot, not ${slot}`);
|
|
345
|
+
if (localOnlyFlags.length) return unusable("eas-local-flags", `${localOnlyFlags.join(" and ")} applies only to a ${platform} device on a Mac`);
|
|
346
|
+
const session = readSession(root);
|
|
347
|
+
if (session && session.platform !== platform) return unusable("eas-session-busy", `this workspace's EAS Simulator session ${session.sessionId} runs ${session.platform ?? "another platform"}`);
|
|
348
|
+
if (session && deviceTypeFlag?.trim() && session.deviceType !== deviceTypeFlag.trim()) return unusable("eas-session-busy", `this workspace's EAS Simulator session ${session.sessionId} runs ${session.deviceType ?? "the model EAS chose"}, not ${deviceTypeFlag.trim()}`);
|
|
349
|
+
if (!onPath("agent-device")) return unusable("eas-no-agent-device", "agent-device is not on PATH");
|
|
350
|
+
const bin = resolveBin(root);
|
|
351
|
+
if (!bin) return unusable("eas-no-cli", "eas-cli is not installed for this project or on PATH");
|
|
352
|
+
const versionOutput = readVersion(bin.file, root);
|
|
353
|
+
const minimum = platform === "ios" && deviceTypeFlag?.trim() ? MIN_EAS_CLI_DEVICE_VERSION : MIN_EAS_CLI_SIMULATOR_VERSION;
|
|
354
|
+
const { supported, version } = easCliSupport(versionOutput, minimum);
|
|
355
|
+
if (!supported) return unusable("eas-cli-too-old", `eas-cli ${version ?? "(unknown version)"} is older than ${minimum}`);
|
|
356
|
+
if (!release) {
|
|
357
|
+
const mode = tunnelMode ?? "auto";
|
|
358
|
+
if (mode === "off") return unusable("eas-metro-unreachable", "metro.tunnel is off, so an EAS Simulator cannot reach Metro");
|
|
359
|
+
const plan = planMetroReach({
|
|
360
|
+
mode,
|
|
361
|
+
metroPort: metroPort() ?? "unknown",
|
|
362
|
+
publicUrl: env["STIM_METRO_PUBLIC_URL"]?.trim() || publicUrl,
|
|
363
|
+
isExpo,
|
|
364
|
+
available: detectProviders(onPath, mode)
|
|
365
|
+
});
|
|
366
|
+
if ("failed" in plan) return unusable("eas-metro-unreachable", plan.failed);
|
|
367
|
+
if ("start" in plan && plan.start === "tailscale") return unusable("eas-metro-unreachable", "metro.tunnel is tailscale, which an EAS Simulator cannot reach");
|
|
368
|
+
if ("expoTunnel" in plan && readTunnel(root)?.kind !== "expo") return unusable("eas-metro-unreachable", "Metro has no Expo tunnel; run stim start --remote first");
|
|
369
|
+
}
|
|
370
|
+
return parseSimulatorAvailability(await availability(bin.file));
|
|
371
|
+
}
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/commands/build-plan.ts
|
|
374
|
+
const DISCARD = {
|
|
375
|
+
file: "",
|
|
376
|
+
written: 0,
|
|
377
|
+
dropped: 0,
|
|
378
|
+
lastError: null,
|
|
379
|
+
write: () => true,
|
|
380
|
+
close: () => ({
|
|
381
|
+
file: "",
|
|
382
|
+
written: 0,
|
|
383
|
+
dropped: 0,
|
|
384
|
+
lastError: null
|
|
385
|
+
})
|
|
386
|
+
};
|
|
387
|
+
async function providerHit({ root, platform, cacheKey, providerConfig }, deps) {
|
|
388
|
+
if (!providerConfig) return null;
|
|
389
|
+
let destinationDir;
|
|
390
|
+
try {
|
|
391
|
+
destinationDir = makeTemporaryDirectory(root, "stim-plan-");
|
|
392
|
+
} catch (error) {
|
|
393
|
+
deps.note(chalk.yellow(phaseLine("cache", `provider not checked: ${error?.message || error}`)));
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
const found = await resolveTieredBuild({
|
|
398
|
+
local: {
|
|
399
|
+
resolve: () => null,
|
|
400
|
+
store: () => null
|
|
401
|
+
},
|
|
402
|
+
loadProvider: () => deps.loadCacheProvider({
|
|
403
|
+
projectRoot: root,
|
|
404
|
+
config: providerConfig
|
|
405
|
+
}),
|
|
406
|
+
target: {
|
|
407
|
+
projectRoot: root,
|
|
408
|
+
platform,
|
|
409
|
+
key: cacheKey
|
|
410
|
+
},
|
|
411
|
+
destinationDir,
|
|
412
|
+
warn: (_code, message) => deps.note(chalk.yellow(phaseLine("cache", message)))
|
|
413
|
+
});
|
|
414
|
+
return found ? found.providerName ?? "the cache provider" : null;
|
|
415
|
+
} finally {
|
|
416
|
+
removeTemporaryEntry(destinationDir);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
async function expoRemoteHit(lookup, deps) {
|
|
420
|
+
if (!lookup.expoRemote) return null;
|
|
421
|
+
const { root, platform, isExpo, fingerprint } = lookup;
|
|
422
|
+
const loaded = await deps.loadProjectProvider(root, { isExpo });
|
|
423
|
+
if (loaded?.unavailable) {
|
|
424
|
+
deps.note(chalk.yellow(phaseLine("cache", `provider not usable: ${loaded.unavailable}`)));
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
if (!loaded?.provider) return null;
|
|
428
|
+
const name = loaded.name ?? "the build cache provider";
|
|
429
|
+
if (name === "eas") {
|
|
430
|
+
const auth = deps.checkEasAuth({
|
|
431
|
+
projectRoot: root,
|
|
432
|
+
owner: loaded.owner || null
|
|
433
|
+
});
|
|
434
|
+
const authNote = easAuthNote(auth);
|
|
435
|
+
if (authNote) deps.note(chalk.yellow(phaseLine("cache", authNote)));
|
|
436
|
+
if (auth?.code === "logged-out") return null;
|
|
437
|
+
}
|
|
438
|
+
const hit = await deps.resolveRemote({
|
|
439
|
+
provider: loaded.provider,
|
|
440
|
+
platform,
|
|
441
|
+
projectRoot: root,
|
|
442
|
+
fingerprintHash: fingerprint,
|
|
443
|
+
runOptions: lookup.expoRemote.runOptions,
|
|
444
|
+
logWriter: DISCARD
|
|
445
|
+
});
|
|
446
|
+
if (hit?.timedOut) deps.note(chalk.yellow(phaseLine("cache", `${name} did not answer; counted as a miss`)));
|
|
447
|
+
else if (hit?.failed) deps.note(chalk.yellow(phaseLine("cache", `${name} could not be used: ${hit.failed}`)));
|
|
448
|
+
return hit?.appPath ? name : null;
|
|
449
|
+
}
|
|
450
|
+
async function planCachedBuild(lookup, deps) {
|
|
451
|
+
const { root, platform, isExpo, fingerprint, sources, cacheKey, cachePolicy } = lookup;
|
|
452
|
+
let cacheHit = false;
|
|
453
|
+
let provider = null;
|
|
454
|
+
if (cachePolicy.read) {
|
|
455
|
+
if (artifactIn(entryDir(platform, cacheKey))) cacheHit = "local";
|
|
456
|
+
else {
|
|
457
|
+
provider = (cachePolicy.remote ? await providerHit(lookup, deps) : null) ?? await expoRemoteHit(lookup, deps);
|
|
458
|
+
if (provider) cacheHit = "remote";
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
let prebuild = null;
|
|
462
|
+
let refusal = null;
|
|
463
|
+
let missReason;
|
|
464
|
+
if (!cacheHit) {
|
|
465
|
+
prebuild = deps.planPrebuild(root, platform, {
|
|
466
|
+
isExpo,
|
|
467
|
+
fingerprint,
|
|
468
|
+
sources
|
|
469
|
+
});
|
|
470
|
+
if (prebuild === "refuse") refusal = staleNativeDirRefusal(platform);
|
|
471
|
+
else if (cachePolicy.read) missReason = predictBuildMiss({
|
|
472
|
+
root,
|
|
473
|
+
platform,
|
|
474
|
+
current: {
|
|
475
|
+
hash: fingerprint,
|
|
476
|
+
sources
|
|
477
|
+
},
|
|
478
|
+
prebuild: prebuild === "generate" || prebuild === "regenerate" ? prebuild : null
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
return planPayload(lookup, {
|
|
482
|
+
fingerprint,
|
|
483
|
+
cacheKey,
|
|
484
|
+
cacheHit,
|
|
485
|
+
provider,
|
|
486
|
+
cacheSkipped: !cachePolicy.read,
|
|
487
|
+
prebuild,
|
|
488
|
+
...missReason ? { missReason } : {},
|
|
489
|
+
refusal
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
function planPayload({ platform, slot, projectKey }, found) {
|
|
493
|
+
const { refusal, missReason, ...rest } = found;
|
|
494
|
+
const outcome = refusal ? null : found.cacheHit ? "hit" : "cold";
|
|
495
|
+
const estimate = outcome ? estimateBuild(readStats$1().record?.history?.[projectKey], platform, outcome) : {
|
|
496
|
+
expectedMs: null,
|
|
497
|
+
basis: 0
|
|
498
|
+
};
|
|
499
|
+
return {
|
|
500
|
+
platform,
|
|
501
|
+
...slot === "default" ? {} : { slot },
|
|
502
|
+
...rest,
|
|
503
|
+
outcome,
|
|
504
|
+
expectedMs: estimate.expectedMs,
|
|
505
|
+
basis: estimate.basis,
|
|
506
|
+
...missReason ? { missReason } : {},
|
|
507
|
+
...refusal ? { refusal } : {}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
function cacheLine(plan) {
|
|
511
|
+
if (plan.refusal) return `the build would refuse with ${plan.refusal.code}`;
|
|
512
|
+
if (plan.cacheHit === "local") return "local cache hit";
|
|
513
|
+
if (plan.cacheHit === "remote") return `remote cache hit (${plan.provider})`;
|
|
514
|
+
return `${plan.cacheSkipped ? "cache reads are off" : "cache miss"}: compiles${plan.prebuild === "generate" || plan.prebuild === "regenerate" ? `, ${plan.prebuild}s the native dir` : ""}`;
|
|
515
|
+
}
|
|
516
|
+
function printPlan(plan, json) {
|
|
517
|
+
if (json) {
|
|
518
|
+
console.log(JSON.stringify(plan));
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const slot = plan.slot ? ` [${plan.slot}]` : "";
|
|
522
|
+
console.log(phaseLine("plan", `${plan.platform}${slot} ${shortHash(plan.fingerprint)} -> ${cacheLine(plan)}`));
|
|
523
|
+
if (plan.placement) console.log(phaseLine("placement", plan.placement));
|
|
524
|
+
if (plan.missReason) console.log(phaseLine("cache", `miss: ${plan.missReason.summary}`));
|
|
525
|
+
if (plan.refusal) {
|
|
526
|
+
console.log(phaseLine("error", plan.refusal.message));
|
|
527
|
+
console.log(phaseLine("remedy", plan.refusal.remedy));
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
console.log(phaseLine("expect", plan.expectedMs === null ? `unknown: no ${plan.outcome} run of this project is recorded yet` : `~${formatDuration(plan.expectedMs)} (median of ${plural(plan.basis, `${plan.outcome} run`)})`));
|
|
531
|
+
}
|
|
532
|
+
function refusePlan({ code, message, remedy }, json, lines = []) {
|
|
533
|
+
console.error(chalk.red(phaseLine("error", message)));
|
|
534
|
+
for (const line of lines) console.error(chalk.dim(phaseLine("", line)));
|
|
535
|
+
console.error(chalk.dim(phaseLine("remedy", remedy)));
|
|
536
|
+
console.error(chalk.red(phaseLine("failed", code)));
|
|
537
|
+
if (json) console.log(JSON.stringify({
|
|
538
|
+
code,
|
|
539
|
+
message,
|
|
540
|
+
remedy
|
|
541
|
+
}));
|
|
542
|
+
process.exitCode = 1;
|
|
543
|
+
}
|
|
544
|
+
const PLAN_ONLY_REMEDY = "Drop the flag to plan the owned simulator or emulator build, or run the command without --plan.";
|
|
545
|
+
function planFlagRefusal(flag) {
|
|
546
|
+
return {
|
|
547
|
+
code: "STIM_BAD_ARG",
|
|
548
|
+
message: `${flag} does not apply to --plan, which predicts the next local build without choosing a device.`,
|
|
549
|
+
remedy: PLAN_ONLY_REMEDY
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
//#endregion
|
|
553
|
+
export { refusePlan as a, devicePlacementLine as c, printPlan as i, probeHost as l, planFlagRefusal as n, checkEasFallback as o, planPayload as r, automaticDevicePlacement as s, planCachedBuild as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as getConfigDir } from "./config-
|
|
1
|
+
import { d as getConfigDir } from "./config-D0LhTY3S.mjs";
|
|
2
2
|
import { isAbsolute, join, resolve } from "path";
|
|
3
3
|
import { existsSync } from "fs";
|
|
4
4
|
import { readCacheManifest, updateCacheManifest } from "@stim-cli/core";
|
package/dist/cache-manifest.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as unregister, i as registeredCaches, n as readManifest, r as register, t as manifestPath } from "./cache-manifest-
|
|
1
|
+
import { a as unregister, i as registeredCaches, n as readManifest, r as register, t as manifestPath } from "./cache-manifest-qA3dT2x2.mjs";
|
|
2
2
|
export { manifestPath, readManifest, register, registeredCaches, unregister };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { _ as loadConfig } from "./config-D0LhTY3S.mjs";
|
|
3
|
+
import { r as register } from "./cache-manifest-qA3dT2x2.mjs";
|
|
4
|
+
import { m as defaultAndroidLayout } from "./settings-Bbztm4oV.mjs";
|
|
5
|
+
import { h as sharedCcache, w as workspaceLogsDir } from "./workspace-state-CSIFuuDa.mjs";
|
|
6
|
+
import { l as phaseLine } from "./command-output-BjPN99ZB.mjs";
|
|
7
|
+
import { o as machineNumber } from "./budget-BONq9vXY.mjs";
|
|
7
8
|
import { readFileSync, realpathSync } from "node:fs";
|
|
8
|
-
import { isAbsolute, join } from "node:path";
|
|
9
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
9
10
|
import chalk from "chalk";
|
|
10
|
-
import { createHash } from "node:crypto";
|
|
11
11
|
const CCACHE_SLOPPINESS = "pch_defines,time_macros";
|
|
12
12
|
const STATS_LOG_FILE = "ccache-stats.log";
|
|
13
13
|
const CCACHE_UNAVAILABLE = {
|
|
@@ -106,15 +106,16 @@ function canonical(root) {
|
|
|
106
106
|
return root;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
function resolveCcache({ root, dir = sharedCcache(), lookup = lookupCcache, onNote = (line) => console.error(line) }) {
|
|
109
|
+
function resolveCcache({ root, layout = defaultAndroidLayout(root), dir = sharedCcache(), lookup = lookupCcache, onNote = (line) => console.error(line) }) {
|
|
110
110
|
const binary = lookup();
|
|
111
111
|
if (!binary) {
|
|
112
112
|
onNote(chalk.dim(phaseLine("cache", "ccache off (not installed; brew install ccache)")));
|
|
113
113
|
return null;
|
|
114
114
|
}
|
|
115
|
-
const
|
|
115
|
+
const { moduleDir } = layout;
|
|
116
|
+
const declared = projectCmakeLauncher(readOrNull(join(moduleDir, "build.gradle")) ?? readOrNull(join(moduleDir, "build.gradle.kts")));
|
|
116
117
|
if (declared) {
|
|
117
|
-
onNote(chalk.dim(phaseLine("cache", `ccache off (
|
|
118
|
+
onNote(chalk.dim(phaseLine("cache", `ccache off (${join(relative(root, moduleDir), "build.gradle")} sets ${declared} itself)`)));
|
|
118
119
|
return null;
|
|
119
120
|
}
|
|
120
121
|
const statsLog = ccacheStatsLog(root);
|
|
@@ -138,11 +139,4 @@ function resolveCcache({ root, dir = sharedCcache(), lookup = lookupCcache, onNo
|
|
|
138
139
|
};
|
|
139
140
|
}
|
|
140
141
|
//#endregion
|
|
141
|
-
|
|
142
|
-
function manifestDigest(entries) {
|
|
143
|
-
const hash = createHash("sha256");
|
|
144
|
-
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`);
|
|
145
|
-
return hash.digest("hex");
|
|
146
|
-
}
|
|
147
|
-
//#endregion
|
|
148
|
-
export { projectCmakeLauncher as a, ccacheActivityLine as i, CCACHE_NOT_RUN as n, readCcacheActivity as o, CCACHE_UNAVAILABLE as r, resolveCcache as s, manifestDigest as t };
|
|
142
|
+
export { readCcacheActivity as a, projectCmakeLauncher as i, CCACHE_UNAVAILABLE as n, resolveCcache as o, ccacheActivityLine as r, CCACHE_NOT_RUN as t };
|