stim 1.2.0 → 1.3.1
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 +34 -3
- package/dist/{android-Bcmev2s2.mjs → android-CT-PkXUh.mjs} +157 -62
- package/dist/{android-cas-D6HPZ6UQ.mjs → android-cas-DXorPCi_.mjs} +5 -5
- package/dist/android-hMj83VpN.mjs +1374 -0
- package/dist/{app-install-NFxUahnH.mjs → app-install-DIp9riNx.mjs} +6 -6
- package/dist/{build-slots-D0b6sJyo.mjs → build-slots-C4AouyNz.mjs} +2 -2
- package/dist/{cache-manifest-Cu4_Znw9.mjs → cache-manifest-CXR-Y8pH.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +13 -13
- package/dist/collector-run.d.mts +3 -1
- package/dist/collector-run.mjs +33 -8
- package/dist/{config-CMtIaTk9.mjs → config-CcefMY2Q.mjs} +93 -12
- package/dist/{deps-BLBsTNDS.mjs → deps-0Yt0Inly.mjs} +1 -1
- package/dist/{dev-client-RpvXxCXV.mjs → dev-client-VfSZNLT4.mjs} +186 -9
- package/dist/{device-CoCPmazS.mjs → device-Bbv45Z9Z.mjs} +19 -11
- package/dist/{device-lease-Dpik41RY.mjs → device-lease-CJwK7OZr.mjs} +107 -83
- package/dist/{device-pool-B5pEVa3t.mjs → device-pool-CcBNTvM7.mjs} +18 -12
- package/dist/{device-remote-E81KAdXf.mjs → device-remote-DAA0Zm6Z.mjs} +7 -7
- package/dist/{doctor-CqPeMsSm.mjs → doctor-B4EITgQB.mjs} +11 -12
- package/dist/{doctor-D_CX7ib5.mjs → doctor-BueDfLYG.mjs} +4 -4
- package/dist/{error-diagnostics-Dw8Gn3yw.mjs → error-diagnostics-DwhNBFDU.mjs} +62 -52
- package/dist/{gc-B7KkDinF.mjs → gc-BRu62v4o.mjs} +66 -57
- package/dist/{guide-BS2Xc24o.mjs → guide-D95E0u3i.mjs} +307 -74
- package/dist/{ios-B7KLgIp5.mjs → ios-DAju3TVy.mjs} +183 -54
- package/dist/{ios-D1h1Di39.mjs → ios-Deh5js5V.mjs} +78 -40
- package/dist/{ios-device-xNt0Lg6v.mjs → ios-device-CWOM_S44.mjs} +1 -1
- package/dist/{logs-DcX9AvRF.mjs → logs-CAdwW6c2.mjs} +34 -6
- package/dist/{logs-query-oqn47Ffx.mjs → logs-query-Cdp5aaCH.mjs} +23 -6
- package/dist/{metro-COslRK_F.mjs → metro-CORqXyTL.mjs} +2 -2
- package/dist/{ndjson-DcAtEx_K.mjs → ndjson-BZwI1NBv.mjs} +5 -2
- package/dist/{ownership-CGPart6T.mjs → ownership-8O073GIC.mjs} +3 -3
- package/dist/{ownership-CYOyqxUo.mjs → ownership-DXcol4oU.mjs} +3 -3
- package/dist/{ownership-claim-7zRxxTfZ.mjs → ownership-claim-BtPtJVmq.mjs} +38 -23
- package/dist/{project-BBTVABUz.mjs → project-fKmuIaMI.mjs} +2 -2
- package/dist/{reclaim-C5Jmuahx.mjs → reclaim-CUmwucWG.mjs} +80 -74
- package/dist/{reload-Z8nKifAk.mjs → reload-CWpXoOgN.mjs} +32 -24
- package/dist/{server-bare-DEk37Mz2.mjs → server-bare-DEzPZLvf.mjs} +2 -2
- package/dist/server-expo-44em5Pmg.mjs +2 -0
- package/dist/{server-expo-C3ktAwUG.mjs → server-expo-DizT4OMk.mjs} +4 -4
- package/dist/{settings-DwU1_U_q.mjs → settings-DEJf6_kJ.mjs} +2 -2
- package/dist/slot-launch-CZklomj6.mjs +19 -0
- package/dist/{start-BrY4EuIg.mjs → start-B5G4NjiA.mjs} +11 -11
- package/dist/{state-CZ-ER-8d.mjs → state-B3XA2wp2.mjs} +9 -9
- package/dist/{stats-BCWEVLrM.mjs → stats-BR-kwj0B.mjs} +1 -1
- package/dist/{stats-BsF15Bti.mjs → stats-CaaQr4yN.mjs} +3 -3
- package/dist/{status-DFI1Hfpg.mjs → status-CI9clRSb.mjs} +55 -24
- package/dist/{stop-B7DR4awK.mjs → stop-CQhffpmX.mjs} +2 -2
- package/dist/{stop-Btg770vV.mjs → stop-CjlgDk0a.mjs} +93 -42
- package/dist/supervisor-run.d.mts +1 -2
- package/dist/supervisor-run.mjs +5 -5
- package/dist/{remote-cache-DDmJ1Roq.mjs → teardown--gESs9ck.mjs} +985 -887
- package/dist/{workspace-process-lock-BKfdys1q.mjs → workspace-process-lock-IBj1Towr.mjs} +1 -1
- package/dist/{worktree-BPTbI-LN.mjs → worktree-DtQGO9-s.mjs} +121 -111
- package/dist/{worktree-C79xx_kM.mjs → worktree-Eq6TLH8N.mjs} +1 -1
- package/dist/{xcode-DeKCribl.mjs → xcode-xnxyvJkD.mjs} +159 -96
- package/package.json +5 -5
- package/dist/android-K63_0UfF.mjs +0 -727
- package/dist/build-lock-BsVoLDaq.mjs +0 -645
- package/dist/server-expo-Drd7ksHu.mjs +0 -2
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { S as upsertProject, f as getProject, l as getConcurrencyLimits } from "./config-
|
|
3
|
-
import { r as createNdjsonWriter } from "./ndjson-
|
|
4
|
-
import { D as workspaceLogsDir, T as workspaceDir, _ as writeWorkspaceState, g as writeWorkspaceLaunch, n as MODE_EXPO, p as readWorkspaceState, t as MODE_BARE } from "./state-
|
|
5
|
-
import { C as removeTemporaryEntry, S as makeTemporaryDirectory, g as repoRoot, s as gitCommonDir } from "./worktree-
|
|
6
|
-
import { a as findProjectRoot, c as projectShortcut, i as detectIsExpo, r as detectBundleId, t as appProjectProblem } from "./project-
|
|
7
|
-
import { i as resolveProjectMetro, r as pidExists } from "./metro-
|
|
8
|
-
import { n as verifyCollectorOwnership } from "./ownership-
|
|
9
|
-
import { a as easAuthNote, c as loadProjectProvider, d as resolveEasCliBin, f as resolveRemote, i as checkEasAuth, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as uploadRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS, v as POOL_SETTING_REMEDY, x as parkedMaxSetting } from "./remote-cache-DDmJ1Roq.mjs";
|
|
10
|
-
import { A as resolveSettings, B as artifactCachePolicy, D as remoteDeviceSettingError, F as tunnelModeSetting, H as optimizationBuildProfile, I as unknownSettingKeys, N as settingShapeErrors, O as remoteIosSetting, R as detectProviders, T as publicUrlSetting, U as resolveOptimizations, _ as iosSigningIdentitySha1SettingError, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, f as iosLanHostSetting, g as iosSigningIdentitySha1Setting, h as iosSigningIdentitySettingError, k as resolveCacheProviderConfig, m as iosSigningIdentitySetting, p as iosLanHostSettingError, r as REMOTE_DEVICE_BACKENDS, x as metroWarmupUrlSetting } from "./settings-DwU1_U_q.mjs";
|
|
2
|
+
import { I as deviceSlotKey, S as upsertProject, V as validateDeviceSlot, f as getProject, l as getConcurrencyLimits } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { r as createNdjsonWriter } from "./ndjson-BZwI1NBv.mjs";
|
|
4
|
+
import { D as workspaceLogsDir, T as workspaceDir, _ as writeWorkspaceState, g as writeWorkspaceLaunch, n as MODE_EXPO, p as readWorkspaceState, t as MODE_BARE } from "./state-B3XA2wp2.mjs";
|
|
5
|
+
import { C as removeTemporaryEntry, S as makeTemporaryDirectory, g as repoRoot, s as gitCommonDir } from "./worktree-Eq6TLH8N.mjs";
|
|
6
|
+
import { a as findProjectRoot, c as projectShortcut, i as detectIsExpo, r as detectBundleId, t as appProjectProblem } from "./project-fKmuIaMI.mjs";
|
|
7
|
+
import { i as resolveProjectMetro, r as pidExists } from "./metro-CORqXyTL.mjs";
|
|
8
|
+
import { n as verifyCollectorOwnership } from "./ownership-8O073GIC.mjs";
|
|
11
9
|
import { _ as launchErrorPreview, c as launchErrorReport, g as stepTimer, h as stepClock, i as formatDuration, l as phaseLine, m as shortUdid, n as appReadinessMessage, p as shortHash } from "./command-output-8wHMEde0.mjs";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { a as
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
10
|
+
import { r as claimFailure } from "./ownership-claim-BtPtJVmq.mjs";
|
|
11
|
+
import { $ as providerDownloadPath, G as buildCacheKey, J as filesystemBuildCapability, K as describeFingerprintMiss, Q as prepareProviderDownloadDir, R as WAIT_CEILING_MS, U as takeoverLine, V as releaseBuildLock, W as waitForBuild, X as fingerprintDiffSuffix, Y as fingerprintDiffRecord, Z as fingerprintProject, at as untrackedMissLine, et as providerUploadOutcome, nt as resolveBuild, ot as untrackedNativeFiles, rt as storeBuild, tt as refingerprintAfterMutation, z as acquireBuildLock } from "./android-hMj83VpN.mjs";
|
|
12
|
+
import { A as resolveSettings, B as artifactCachePolicy, D as remoteDeviceSettingError, F as tunnelModeSetting, H as optimizationBuildProfile, I as unknownSettingKeys, N as settingShapeErrors, O as remoteIosSetting, R as detectProviders, T as publicUrlSetting, U as resolveOptimizations, _ as iosSigningIdentitySha1SettingError, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, f as iosLanHostSetting, g as iosSigningIdentitySha1Setting, h as iosSigningIdentitySettingError, k as resolveCacheProviderConfig, m as iosSigningIdentitySetting, p as iosLanHostSettingError, r as REMOTE_DEVICE_BACKENDS, x as metroWarmupUrlSetting } from "./settings-DEJf6_kJ.mjs";
|
|
13
|
+
import { C as uploadRemote, S as resolveRemote, _ as isEasAuthFailureText, a as POOL_SETTING_REMEDY, c as parkedMaxSetting, d as RESOLVE_TIMEOUT_MS, f as UPLOAD_TIMEOUT_MS, g as exitAfterFlush, h as easAuthNote, m as checkEasAuth, p as cacheLevel, v as loadProjectProvider, x as resolveEasCliBin } from "./teardown--gESs9ck.mjs";
|
|
14
|
+
import { _ as easDeviceBuildRemedy, a as swapJsBundle, c as ensureWorkspaceStorageSafely, d as launchOutcomeRecord, f as noMetroMessage, g as warmMetro, h as sleep, l as gateShouldRetry, m as resolveMetroWithRetry, n as pickDevClientScheme, o as needsPrebuild, p as noMetroRemedy, r as schemesFromInfoPlist, s as runPrebuild, t as devClientScheme, u as isPhysicalDeviceRequest, v as isEasBuildFailure, y as resolveEasDevelopmentBuild } from "./dev-client-VfSZNLT4.mjs";
|
|
15
|
+
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-IBj1Towr.mjs";
|
|
16
|
+
import { C as launchIosApp, E as unverifiedLaunchLines, O as verifyLaunch, T as readMetroRecords, b as isBundleProof, c as RELEASE_VERIFY_WAIT_MS, f as clearOtherUserApps, i as LAUNCH_BUNDLING, k as verifyReleaseLaunch, m as devClientUrl, n as DEFAULT_METRO_PORT, o as LAUNCH_FATAL, s as LAUNCH_UNVERIFIED, v as installIosApp, w as readCollectorRecords, y as iosAppProcess } from "./app-install-DIp9riNx.mjs";
|
|
17
|
+
import { f as listIosRuntimes } from "./ios-Deh5js5V.mjs";
|
|
18
|
+
import { a as lostLine, c as releaseLeaseOnSignal, i as leaseExpiryText, l as runLease, n as DEBUG_VERIFY_STEP_MS, o as lostRefusal, r as acquireRunLease, s as parseDeviceWait, t as selectFromPool, u as waitFlagConflict } from "./device-pool-CcBNTvM7.mjs";
|
|
19
|
+
import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-C4AouyNz.mjs";
|
|
20
|
+
import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-BR-kwj0B.mjs";
|
|
21
|
+
import { E as unknownIosRuntimeRefusal, S as ensureOwnedDevice, T as unknownIosDeviceTypeRefusal, b as clearIosAdoptionPending, c as discoverXcodeProject, d as resolveScheme, i as buildIos, l as readBundleExecutable, m as describeDiagnostic, n as COMPILATION_CACHE_UNAVAILABLE, o as compilationCacheActivityLine, t as COMPILATION_CACHE_NOT_RUN, u as readBundleId, x as ensureBooted, y as checkDeviceCapacity } from "./xcode-xnxyvJkD.mjs";
|
|
22
|
+
import { a as ensureMetroReachable, b as ownedSessionName, c as remoteIosDeps, l as resolveRemoteContext, n as binOnPath, o as ensureRemoteBootOwned, r as bundleEntryPoint, w as gateMetroOrigin } from "./device-remote-DAA0Zm6Z.mjs";
|
|
23
|
+
import { n as nativeRunCommand, t as launchSlotScope } from "./slot-launch-CZklomj6.mjs";
|
|
22
24
|
import { t as spawnEntry } from "./spawn-entry-nCE6m770.mjs";
|
|
23
|
-
import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-
|
|
24
|
-
import { a as iosDeviceProcess, c as listIosDevices, d as verifyIosDeviceReleaseLaunch, i as installIosDeviceApp, l as localNetworkPending, n as LAUNCH_PROBE_TIMEOUT_MS, o as iosPoolCandidates, r as awaitIosDeviceLaunch, s as iosPoolNoCandidatesRefusal, t as DEVICECTL_INSTALL_TIMEOUT_MS, u as resolveIosPhysicalDevice } from "./ios-device-
|
|
25
|
-
import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-
|
|
25
|
+
import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-DwhNBFDU.mjs";
|
|
26
|
+
import { a as iosDeviceProcess, c as listIosDevices, d as verifyIosDeviceReleaseLaunch, i as installIosDeviceApp, l as localNetworkPending, n as LAUNCH_PROBE_TIMEOUT_MS, o as iosPoolCandidates, r as awaitIosDeviceLaunch, s as iosPoolNoCandidatesRefusal, t as DEVICECTL_INSTALL_TIMEOUT_MS, u as resolveIosPhysicalDevice } from "./ios-device-CWOM_S44.mjs";
|
|
27
|
+
import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-0Yt0Inly.mjs";
|
|
26
28
|
import { existsSync, mkdirSync, mkdtempSync, openSync, rmSync, writeFileSync } from "node:fs";
|
|
27
29
|
import { InvalidArgumentError } from "commander";
|
|
28
30
|
import { X509Certificate } from "node:crypto";
|
|
29
31
|
import { basename, join } from "node:path";
|
|
30
32
|
import { networkInterfaces, tmpdir } from "node:os";
|
|
31
|
-
import chalk from "chalk";
|
|
32
33
|
import { createWarnOnce, loadCacheProvider, resolveTieredBuild, storeTieredBuild } from "@stim-cli/cache";
|
|
34
|
+
import chalk from "chalk";
|
|
33
35
|
//#region src/engine/ios-profile.ts
|
|
34
36
|
const TAG = /<(\/?)\s*([A-Za-z0-9_]+)(?:\s[^>]*?)?(\/?)>/g;
|
|
35
37
|
const ENTITIES = {
|
|
@@ -633,7 +635,12 @@ function resolveDeviceType(flag, settings) {
|
|
|
633
635
|
function resolveRuntime(flag, settings) {
|
|
634
636
|
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || iosStringSetting(settings, "runtime");
|
|
635
637
|
}
|
|
636
|
-
function deviceModelRefusal({ deviceTypeFlag, runtimeFlag, deviceType, runtime, physical, remoteBackend, listRuntimes }) {
|
|
638
|
+
function deviceModelRefusal({ slot, deviceTypeFlag, runtimeFlag, deviceType, runtime, physical, remoteBackend, listRuntimes }) {
|
|
639
|
+
if (slot && slot !== "default" && remoteBackend) return {
|
|
640
|
+
code: "STIM_BAD_ARG",
|
|
641
|
+
message: "Named slots currently support local simulators and physical devices.",
|
|
642
|
+
remedy: "Use the default slot for a remote session."
|
|
643
|
+
};
|
|
637
644
|
if (typeof deviceTypeFlag === "string" && deviceTypeFlag.trim() === "") return {
|
|
638
645
|
code: "STIM_BAD_ARG",
|
|
639
646
|
message: "--device-type was given an empty name.",
|
|
@@ -699,22 +706,22 @@ function printDiagnostics(note, result) {
|
|
|
699
706
|
}
|
|
700
707
|
//#endregion
|
|
701
708
|
//#region src/commands/ios/collector.ts
|
|
702
|
-
function collectorLogFile(root) {
|
|
703
|
-
return join(workspaceLogsDir(root), `collector
|
|
709
|
+
function collectorLogFile(root, slot) {
|
|
710
|
+
return join(workspaceLogsDir(root), `collector-${deviceSlotKey("ios", slot)}.log`);
|
|
704
711
|
}
|
|
705
712
|
function collectorEntry() {
|
|
706
713
|
return spawnEntry("collector-run");
|
|
707
714
|
}
|
|
708
715
|
const COLLECTOR_EXIT_WAIT_MS = 2e3;
|
|
709
716
|
const COLLECTOR_POLL_MS = 25;
|
|
710
|
-
async function stopPreviousCollector({ root, kill = (pid, signal) => process.kill(pid, signal), alive = pidExists, readState = readWorkspaceState, verify = verifyCollectorOwnership, waitMs = COLLECTOR_EXIT_WAIT_MS, note = (_line) => {} }) {
|
|
711
|
-
const previous = (readState(root)?.collectors)?.["ios"] || null;
|
|
717
|
+
async function stopPreviousCollector({ root, slot = "default", kill = (pid, signal) => process.kill(pid, signal), alive = pidExists, readState = readWorkspaceState, verify = verifyCollectorOwnership, waitMs = COLLECTOR_EXIT_WAIT_MS, note = (_line) => {} }) {
|
|
718
|
+
const previous = (readState(root)?.collectors)?.[deviceSlotKey("ios", slot)] || null;
|
|
712
719
|
const previousPid = Number(previous?.pid) || null;
|
|
713
720
|
let killed = null;
|
|
714
721
|
if (previousPid) {
|
|
715
722
|
const ownership = verify({
|
|
716
723
|
pid: previousPid,
|
|
717
|
-
platform: "ios",
|
|
724
|
+
platform: deviceSlotKey("ios", slot),
|
|
718
725
|
root,
|
|
719
726
|
isAlive: alive,
|
|
720
727
|
expected: previous
|
|
@@ -732,9 +739,10 @@ async function stopPreviousCollector({ root, kill = (pid, signal) => process.kil
|
|
|
732
739
|
}
|
|
733
740
|
return { killed };
|
|
734
741
|
}
|
|
735
|
-
async function replaceCollector({ root, udid, bundleId, appName, appExecutable, physical = false, payloadUrl = null, spawn = (cmd, args, opts) => getExecutor().spawn(cmd, args, opts), kill = (pid, signal) => process.kill(pid, signal), alive = pidExists, readState = readWorkspaceState, verify = verifyCollectorOwnership, waitMs = COLLECTOR_EXIT_WAIT_MS, note = (_line) => {} }) {
|
|
742
|
+
async function replaceCollector({ root, slot = "default", udid, bundleId, appName, appExecutable, physical = false, payloadUrl = null, spawn = (cmd, args, opts) => getExecutor().spawn(cmd, args, opts), kill = (pid, signal) => process.kill(pid, signal), alive = pidExists, readState = readWorkspaceState, verify = verifyCollectorOwnership, waitMs = COLLECTOR_EXIT_WAIT_MS, note = (_line) => {} }) {
|
|
736
743
|
const { killed } = await stopPreviousCollector({
|
|
737
744
|
root,
|
|
745
|
+
slot,
|
|
738
746
|
kill,
|
|
739
747
|
alive,
|
|
740
748
|
readState,
|
|
@@ -753,6 +761,7 @@ async function replaceCollector({ root, udid, bundleId, appName, appExecutable,
|
|
|
753
761
|
"--bundle",
|
|
754
762
|
bundleId
|
|
755
763
|
];
|
|
764
|
+
if (slot !== "default") args.push("--slot", slot);
|
|
756
765
|
if (appName) args.push("--app-name", appName);
|
|
757
766
|
if (appExecutable) args.push("--app-executable", appExecutable);
|
|
758
767
|
if (physical) args.push("--physical");
|
|
@@ -760,7 +769,7 @@ async function replaceCollector({ root, udid, bundleId, appName, appExecutable,
|
|
|
760
769
|
let stdio = "ignore";
|
|
761
770
|
try {
|
|
762
771
|
mkdirSync(workspaceLogsDir(root), { recursive: true });
|
|
763
|
-
const fd = openSync(collectorLogFile(root), "a");
|
|
772
|
+
const fd = openSync(collectorLogFile(root, slot), "a");
|
|
764
773
|
stdio = [
|
|
765
774
|
"ignore",
|
|
766
775
|
fd,
|
|
@@ -791,6 +800,7 @@ async function replaceCollector({ root, udid, bundleId, appName, appExecutable,
|
|
|
791
800
|
//#endregion
|
|
792
801
|
//#region src/commands/ios/dependencies.ts
|
|
793
802
|
const DEFAULT_DEPS = {
|
|
803
|
+
resolveEasDevelopmentBuild,
|
|
794
804
|
findProjectRoot,
|
|
795
805
|
resolveSettings,
|
|
796
806
|
gitCommonDir,
|
|
@@ -890,9 +900,10 @@ function lastBuildRecord({ fingerprint = null, cacheKey = null, cacheHit = false
|
|
|
890
900
|
if (errorCode) record.errorCode = errorCode;
|
|
891
901
|
return record;
|
|
892
902
|
}
|
|
893
|
-
function iosFacts({ udid, deviceName, deviceType = null, runtime = null, fingerprint, configuration = null, scheme = null, cacheKey, cacheHit, cacheSkipped = false, compilationCache = COMPILATION_CACHE_NOT_RUN, waitedForBuild = null, appPath, bundleId, installSkipped = false, metroPort, logsDir, durationMs, launched = true, webPreviewUrl = null, lease }) {
|
|
903
|
+
function iosFacts({ slot, udid, deviceName, deviceType = null, runtime = null, fingerprint, configuration = null, scheme = null, cacheKey, cacheHit, cacheSkipped = false, compilationCache = COMPILATION_CACHE_NOT_RUN, waitedForBuild = null, appPath, bundleId, installSkipped = false, metroPort, logsDir, durationMs, launched = true, webPreviewUrl = null, lease }) {
|
|
894
904
|
return {
|
|
895
905
|
platform: "ios",
|
|
906
|
+
...slot && slot !== "default" ? { slot } : {},
|
|
896
907
|
udid,
|
|
897
908
|
deviceName: deviceName ?? null,
|
|
898
909
|
deviceType: deviceType ?? null,
|
|
@@ -942,7 +953,7 @@ async function finishIosUpload(uploadPending, remote, phase, note) {
|
|
|
942
953
|
}
|
|
943
954
|
return false;
|
|
944
955
|
}
|
|
945
|
-
function reportIosResult({ d, root, json, release, configuration, buildScheme = null, metroCheck, metroPort, logsDir, device, udid, appPath, bundleId, installSkipped, elapsed, startedAt, storeHash, storeKey, cacheHit, compilationCache, useBuildCache, waitedForBuild, launchState, launchWarning, remote, providerName, closeWriter, webPreviewUrl, lease, recordRun }) {
|
|
956
|
+
function reportIosResult({ slot, d, root, json, release, configuration, buildScheme = null, metroCheck, metroPort, logsDir, device, udid, appPath, bundleId, installSkipped, elapsed, startedAt, storeHash, storeKey, cacheHit, compilationCache, useBuildCache, waitedForBuild, launchState, launchWarning, remote, providerName, closeWriter, webPreviewUrl, lease, recordRun }) {
|
|
946
957
|
const durationMs = elapsed();
|
|
947
958
|
recordRun({
|
|
948
959
|
failed: false,
|
|
@@ -963,6 +974,7 @@ function reportIosResult({ d, root, json, release, configuration, buildScheme =
|
|
|
963
974
|
}), { write: d.writeWorkspaceState });
|
|
964
975
|
closeWriter();
|
|
965
976
|
const facts = iosFacts({
|
|
977
|
+
slot,
|
|
966
978
|
udid,
|
|
967
979
|
deviceName: device?.deviceName ?? null,
|
|
968
980
|
deviceType: device?.deviceType,
|
|
@@ -1015,9 +1027,14 @@ function cacheDescription(cacheHit, providerName = null) {
|
|
|
1015
1027
|
function missingCrashReportHint({ physical, remote, crashed }) {
|
|
1016
1028
|
return crashed && !physical && !remote ? `No attributable native crash report captured yet. ${IOS_CRASH_REPORT_RETRY}` : "No attributable native crash report captured. Read `stim logs --source device` for available output.";
|
|
1017
1029
|
}
|
|
1018
|
-
async function verifyIosRun({ root, appPath, d, release, launched, configuration, phase, note, metroCheck, logsDir, launchedAt, metroPort, isExpo, bundleId, udid, scheme, physical, appName, lanAddress, lanOrigin, remoteDevice, metroOrigin }) {
|
|
1030
|
+
async function verifyIosRun({ root, slot, appPath, d, release, launched, configuration, phase, note, metroCheck, logsDir, launchedAt, metroPort, isExpo, bundleId, udid, scheme, physical, appName, lanAddress, lanOrigin, remoteDevice, metroOrigin }) {
|
|
1031
|
+
const runCommand = nativeRunCommand("ios", slot, {
|
|
1032
|
+
physical,
|
|
1033
|
+
deviceId: udid
|
|
1034
|
+
});
|
|
1019
1035
|
const readNativeCrashes = () => remoteDevice ? [] : captureNativeCrashes({
|
|
1020
1036
|
root,
|
|
1037
|
+
slot,
|
|
1021
1038
|
platform: "ios",
|
|
1022
1039
|
deviceId: udid,
|
|
1023
1040
|
appId: bundleId,
|
|
@@ -1054,6 +1071,7 @@ async function verifyIosRun({ root, appPath, d, release, launched, configuration
|
|
|
1054
1071
|
}
|
|
1055
1072
|
const verification = metroCheck ? await d.verifyLaunch({
|
|
1056
1073
|
requireBundleResponse: true,
|
|
1074
|
+
slot: launchSlotScope(root, slot),
|
|
1057
1075
|
onReadinessPending: () => phase("readiness", "waiting for app readiness (up to 30s after bundle load)"),
|
|
1058
1076
|
logsDir,
|
|
1059
1077
|
since: launchedAt,
|
|
@@ -1090,10 +1108,10 @@ async function verifyIosRun({ root, appPath, d, release, launched, configuration
|
|
|
1090
1108
|
remote: Boolean(remoteDevice),
|
|
1091
1109
|
crashed: true
|
|
1092
1110
|
})));
|
|
1093
|
-
if (nativeFatal || verification.processAlive === false) note(chalk.yellow(phaseLine("remedy",
|
|
1111
|
+
if (nativeFatal || verification.processAlive === false) note(chalk.yellow(phaseLine("remedy", `Fix the crash, then run \`${runCommand}\` again. A Metro reload cannot restart an exited app.`)));
|
|
1094
1112
|
else if (verification.processAlive === true && metroPort !== null) {
|
|
1095
1113
|
const reloadRemedy = `press Reload on the app's own error screen -- run \`agent-device snapshot -i --platform ios --udid ${udid}\` in your existing automation session to reach it. Neither \`stim reload ios\` nor \`agent-device metro reload\` can: this app never connected to Metro.`;
|
|
1096
|
-
note(chalk.yellow(phaseLine("remedy", `The native app is still running. ${deliveryFailed ? "Check the Metro logs and device connection, then" : "Fix the JavaScript or TypeScript error, then"} ${reloadRemedy} Do not run \`
|
|
1114
|
+
note(chalk.yellow(phaseLine("remedy", `The native app is still running. ${deliveryFailed ? "Check the Metro logs and device connection, then" : "Fix the JavaScript or TypeScript error, then"} ${reloadRemedy} Do not run \`${runCommand}\` unless native inputs changed or the app process exits.`)));
|
|
1097
1115
|
}
|
|
1098
1116
|
return { state: LAUNCH_FATAL };
|
|
1099
1117
|
}
|
|
@@ -1102,7 +1120,7 @@ async function verifyIosRun({ root, appPath, d, release, launched, configuration
|
|
|
1102
1120
|
const hasAppErrors = reportLaunchErrors(verification.errors ?? [], note, root);
|
|
1103
1121
|
if (hasAppErrors && verification.processAlive === true && metroPort !== null) {
|
|
1104
1122
|
const reloadRemedy = physical || remoteDevice ? `run \`agent-device metro reload --metro-port ${metroPort}\`.` : "run `stim reload ios`.";
|
|
1105
|
-
note(chalk.yellow(phaseLine("remedy", `The native app is still running. Fix the JavaScript or TypeScript error; Fast Refresh should apply the edit. If the error screen remains, ${reloadRemedy} Do not run \`
|
|
1123
|
+
note(chalk.yellow(phaseLine("remedy", `The native app is still running. Fix the JavaScript or TypeScript error; Fast Refresh should apply the edit. If the error screen remains, ${reloadRemedy} Do not run \`${runCommand}\` unless native inputs changed or the app process exits.`)));
|
|
1106
1124
|
}
|
|
1107
1125
|
return {
|
|
1108
1126
|
state: true,
|
|
@@ -1146,14 +1164,14 @@ function reportLaunchErrors(errors, note, root) {
|
|
|
1146
1164
|
for (const line of report.lines) note(chalk.yellow(phaseLine("launch", line)));
|
|
1147
1165
|
return report.lines.length > 0;
|
|
1148
1166
|
}
|
|
1149
|
-
function cleanAdoptedIosApps({ d, root, udid, bundleId, phase, note }) {
|
|
1167
|
+
function cleanAdoptedIosApps({ d, root, slot, udid, bundleId, phase, note }) {
|
|
1150
1168
|
const swept = d.clearOtherUserApps({
|
|
1151
1169
|
udid,
|
|
1152
1170
|
keep: bundleId
|
|
1153
1171
|
});
|
|
1154
1172
|
if (swept.removed.length) phase("install", `removed ${swept.removed.join(", ")}, left by the previous workspace`);
|
|
1155
1173
|
if (swept.listed && swept.failed.length === 0) {
|
|
1156
|
-
d.clearIosAdoptionPending(root);
|
|
1174
|
+
d.clearIosAdoptionPending(root, slot);
|
|
1157
1175
|
return null;
|
|
1158
1176
|
}
|
|
1159
1177
|
if (!swept.listed) return "Could not list apps left by the previous workspace.";
|
|
@@ -1195,7 +1213,11 @@ function recordIosReloadTarget({ d, root, physical, remoteDevice, bundleId, udid
|
|
|
1195
1213
|
function simulatorLaunchFailureRemedy(remote, udid, bundleId, logFile) {
|
|
1196
1214
|
return `${remote ? "Run" : "If the simulator timed out, run `stim doctor --platform ios` and resolve any reported host memory pressure before retrying. Otherwise run"} \`xcrun simctl launch --console ${udid} ${bundleId}\` to see what the app reports, and check ${logFile}.`;
|
|
1197
1215
|
}
|
|
1198
|
-
async function finishIosRun({ d, root, json, release, configuration, buildScheme, isExpo, metroCheck, metroPort, logsDir, logFile, device, udid, physical, lanAddress, lanOriginUrl, remoteDevice, bootPromise, bootDuration, appPath, bundleId: initialBundleId, swapDir, buildFailure, fail, phase, note, logWriter, uploadPending, providerUpload, providerName, remote, abandonedRemote: remoteWasAbandoned, elapsed, startedAt, storeHash, storeKey, cacheHit, compilationCache, useBuildCache, waitedForBuild, closeWriter, lease, releaseLease, recordRun }) {
|
|
1216
|
+
async function finishIosRun({ d, root, slot, json, release, configuration, buildScheme, isExpo, metroCheck, metroPort, logsDir, logFile, device, udid, physical, lanAddress, lanOriginUrl, remoteDevice, bootPromise, bootDuration, appPath, bundleId: initialBundleId, swapDir, buildFailure, fail, phase, note, logWriter, uploadPending, providerUpload, providerName, remote, abandonedRemote: remoteWasAbandoned, elapsed, startedAt, storeHash, storeKey, cacheHit, compilationCache, useBuildCache, waitedForBuild, closeWriter, lease, releaseLease, recordRun }) {
|
|
1217
|
+
const runCommand = nativeRunCommand("ios", slot, {
|
|
1218
|
+
physical,
|
|
1219
|
+
deviceId: udid
|
|
1220
|
+
});
|
|
1199
1221
|
let bundleId = initialBundleId;
|
|
1200
1222
|
let leaseWarned = false;
|
|
1201
1223
|
const raiseLeaseFor = (boundMs, beforeInstall) => {
|
|
@@ -1231,7 +1253,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1231
1253
|
if (!booted?.ok) return fail({
|
|
1232
1254
|
code: booted?.code || "STIM_NO_DEVICE",
|
|
1233
1255
|
message: booted?.reason || "The owned simulator could not be booted.",
|
|
1234
|
-
remedy: booted?.remedy ||
|
|
1256
|
+
remedy: booted?.remedy || `Run \`${runCommand}\` again to re-establish an owned simulator for this workspace.`
|
|
1235
1257
|
});
|
|
1236
1258
|
const deviceOutcome = physical ? "connected" : `${device?.adopted ? "adopted" : "booted"} ${bootDuration()}`;
|
|
1237
1259
|
phase("device", `${deviceLabel(device, udid)} ${deviceOutcome}`);
|
|
@@ -1298,6 +1320,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1298
1320
|
});
|
|
1299
1321
|
const collector = await d.replaceCollector({
|
|
1300
1322
|
root,
|
|
1323
|
+
slot,
|
|
1301
1324
|
udid,
|
|
1302
1325
|
bundleId,
|
|
1303
1326
|
appName,
|
|
@@ -1320,7 +1343,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1320
1343
|
bundleId,
|
|
1321
1344
|
appName: appName ?? bundleId,
|
|
1322
1345
|
collectorPid: collector.pid,
|
|
1323
|
-
readRecords: () => readCollectorRecords(logsDir).filter((entry) => Number(entry.ts) >= launchedAt)
|
|
1346
|
+
readRecords: () => readCollectorRecords(logsDir).filter((entry) => Number(entry.ts) >= launchedAt && (entry.slot ?? "default") === (slot ?? "default"))
|
|
1324
1347
|
});
|
|
1325
1348
|
if (started.failed || !started.pid) return fail({
|
|
1326
1349
|
code: "STIM_LAUNCH_FAILED",
|
|
@@ -1356,7 +1379,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1356
1379
|
if (cleanupFailure) return fail({
|
|
1357
1380
|
code: "STIM_INSTALL_FAILED",
|
|
1358
1381
|
message: `${cleanupFailure} Stim kept the adoption cleanup pending and did not install or launch the app.`,
|
|
1359
|
-
remedy:
|
|
1382
|
+
remedy: `Run \`${runCommand}\` again after simulator tooling is responsive.`,
|
|
1360
1383
|
build: {
|
|
1361
1384
|
...buildFailure,
|
|
1362
1385
|
appPath,
|
|
@@ -1389,6 +1412,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1389
1412
|
dropSwapDir();
|
|
1390
1413
|
if (!remoteDevice) await d.replaceCollector({
|
|
1391
1414
|
root,
|
|
1415
|
+
slot,
|
|
1392
1416
|
udid,
|
|
1393
1417
|
bundleId,
|
|
1394
1418
|
appName,
|
|
@@ -1424,6 +1448,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1424
1448
|
if (launched?.failed) {
|
|
1425
1449
|
printNativeCrashReport({
|
|
1426
1450
|
root,
|
|
1451
|
+
slot,
|
|
1427
1452
|
platform: "ios",
|
|
1428
1453
|
deviceId: udid,
|
|
1429
1454
|
appId: bundleId,
|
|
@@ -1446,6 +1471,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1446
1471
|
recordIosReloadTarget({
|
|
1447
1472
|
d,
|
|
1448
1473
|
root,
|
|
1474
|
+
slot,
|
|
1449
1475
|
physical,
|
|
1450
1476
|
remoteDevice: Boolean(remoteDevice),
|
|
1451
1477
|
bundleId,
|
|
@@ -1463,6 +1489,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1463
1489
|
});
|
|
1464
1490
|
if (remoteDevice) await d.replaceCollector({
|
|
1465
1491
|
root,
|
|
1492
|
+
slot,
|
|
1466
1493
|
udid,
|
|
1467
1494
|
bundleId,
|
|
1468
1495
|
appName,
|
|
@@ -1472,6 +1499,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1472
1499
|
if (physical) raiseLeaseFor(release ? RELEASE_VERIFY_WAIT_MS : DEBUG_VERIFY_STEP_MS, false);
|
|
1473
1500
|
const { state: launchState, warning: launchWarning } = await verifyIosRun({
|
|
1474
1501
|
root,
|
|
1502
|
+
slot,
|
|
1475
1503
|
appPath,
|
|
1476
1504
|
d,
|
|
1477
1505
|
release,
|
|
@@ -1523,6 +1551,7 @@ async function finishIosRun({ d, root, json, release, configuration, buildScheme
|
|
|
1523
1551
|
const facts = reportIosResult({
|
|
1524
1552
|
d,
|
|
1525
1553
|
root,
|
|
1554
|
+
slot,
|
|
1526
1555
|
json,
|
|
1527
1556
|
release,
|
|
1528
1557
|
configuration,
|
|
@@ -1570,14 +1599,20 @@ function iosCommand(program) {
|
|
|
1570
1599
|
registerIos(program);
|
|
1571
1600
|
}
|
|
1572
1601
|
function registerIos(program, deps = {}) {
|
|
1573
|
-
program.command("ios").description("Build (or restore from the fingerprint cache), install and launch this workspace's app on its owned simulator, wired to the reserved Metro port. Requires a running dev server (`stim start`).").option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--scheme <name>", "Shared Xcode app scheme to build; overrides automatic scheme selection, not the app URL scheme").option("--no-metro-check", "Skip the \"is this workspace's dev server running?\" gate and build anyway").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--configuration <name>", "Xcode configuration to build (e.g. Release). A non-Debug configuration embeds the JS bundle and skips Metro entirely. Overrides the ios.configuration setting. Default: Debug").option("--device-type <name>", "Simulator model to create this workspace's owned sim as, exactly as `xcrun simctl list devicetypes` names it (e.g. \"iPad Pro 13-inch (M4)\"). Overrides the ios.deviceType setting for this invocation. A model no installed runtime can create refuses with STIM_BAD_ARG and prints the models they do offer.").option("--runtime <version>", "Simulator runtime to create this workspace's owned sim on, as a version (\"18.5\") or a runtime's full name (\"iOS 18.5\"); nothing else matches. Overrides the ios.runtime setting for this invocation. An unknown version refuses with STIM_BAD_ARG and prints the installed runtimes.").option("--device [udid]", "Build the iphoneos slice for a connected iPhone, install it, and launch it, instead of using this workspace's owned simulator. With no UDID, the first connected device this workspace can lease is used. In Debug the app is wired to this workspace's Metro over the LAN. Stim never creates, boots, or deletes a physical device.").option("--remote <backend>", "Install and launch on a remote device with proxy or EAS.
|
|
1602
|
+
program.command("ios").description("Build (or restore from the fingerprint cache), install and launch this workspace's app on its owned simulator, wired to the reserved Metro port. Requires a running dev server (`stim start`).").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", validateDeviceSlot).option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--scheme <name>", "Shared Xcode app scheme to build; overrides automatic scheme selection, not the app URL scheme").option("--no-metro-check", "Skip the \"is this workspace's dev server running?\" gate and build anyway").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--configuration <name>", "Xcode configuration to build (e.g. Release). A non-Debug configuration embeds the JS bundle and skips Metro entirely. Overrides the ios.configuration setting. Default: Debug").option("--device-type <name>", "Simulator model to create this workspace's owned sim as, exactly as `xcrun simctl list devicetypes` names it (e.g. \"iPad Pro 13-inch (M4)\"). Overrides the ios.deviceType setting for this invocation. A model no installed runtime can create refuses with STIM_BAD_ARG and prints the models they do offer.").option("--runtime <version>", "Simulator runtime to create this workspace's owned sim on, as a version (\"18.5\") or a runtime's full name (\"iOS 18.5\"); nothing else matches. Overrides the ios.runtime setting for this invocation. An unknown version refuses with STIM_BAD_ARG and prints the installed runtimes.").option("--device [udid]", "Build the iphoneos slice for a connected iPhone, install it, and launch it, instead of using this workspace's owned simulator. With no UDID, the first connected device this workspace can lease is used. In Debug the app is wired to this workspace's Metro over the LAN. Stim never creates, boots, or deletes a physical device.").option("--remote <backend>", "Install and launch on a remote device with proxy or EAS. Builds are local unless --eas-profile selects an existing EAS build.", (value) => {
|
|
1574
1603
|
if (REMOTE_DEVICE_BACKENDS.includes(value)) return value;
|
|
1575
1604
|
throw new InvalidArgumentError(`expected one of: ${REMOTE_DEVICE_BACKENDS.join(", ")}`);
|
|
1576
1605
|
}).option("--wait <seconds>", "How long to wait for another workspace to release the phone it leases, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once). Only with --device.").option("--no-wait", "Install on a phone another workspace leases instead of waiting: this run takes no lease and, when both workspaces build the same app id, the install terminates the holder's running app. Only with --device.").action(async (opts) => {
|
|
1577
|
-
|
|
1606
|
+
const root = (deps.findProjectRoot ?? DEFAULT_DEPS.findProjectRoot)(process.cwd());
|
|
1607
|
+
const run = () => runIos({
|
|
1578
1608
|
...opts,
|
|
1579
1609
|
waitConflict: waitFlagConflict(process.argv)
|
|
1580
1610
|
}, deps);
|
|
1611
|
+
if (!root) await run();
|
|
1612
|
+
else await withWorkspaceProcessLock(workspaceDir(root), "native-run", run, {
|
|
1613
|
+
external: true,
|
|
1614
|
+
waitMs: 18e5
|
|
1615
|
+
});
|
|
1581
1616
|
});
|
|
1582
1617
|
}
|
|
1583
1618
|
function explicitSchemeRefusal(root, scheme, isExpo, d) {
|
|
@@ -1592,11 +1627,58 @@ function explicitSchemeRefusal(root, scheme, isExpo, d) {
|
|
|
1592
1627
|
if (project.error) return project.error;
|
|
1593
1628
|
return d.resolveScheme(project, { scheme }).error ?? null;
|
|
1594
1629
|
}
|
|
1630
|
+
function iosSlotLogFile(root, slot) {
|
|
1631
|
+
return slot === "default" ? buildLogFile(root) : join(workspaceLogsDir(root), `build-${deviceSlotKey("ios", slot)}.ndjson`);
|
|
1632
|
+
}
|
|
1633
|
+
function iosSlotDeps(d, slot) {
|
|
1634
|
+
if (slot !== "default") {
|
|
1635
|
+
const base = d;
|
|
1636
|
+
d = {
|
|
1637
|
+
...base,
|
|
1638
|
+
ensureOwnedDevice: (args) => base.ensureOwnedDevice({
|
|
1639
|
+
...args,
|
|
1640
|
+
slot
|
|
1641
|
+
}),
|
|
1642
|
+
checkDeviceCapacity: (args) => base.checkDeviceCapacity({
|
|
1643
|
+
...args,
|
|
1644
|
+
slot
|
|
1645
|
+
}),
|
|
1646
|
+
selectFromPool: (args) => base.selectFromPool({
|
|
1647
|
+
...args,
|
|
1648
|
+
slot
|
|
1649
|
+
}),
|
|
1650
|
+
acquireRunLease: (args) => base.acquireRunLease({
|
|
1651
|
+
...args,
|
|
1652
|
+
slot
|
|
1653
|
+
}),
|
|
1654
|
+
runLease: (args) => base.runLease({
|
|
1655
|
+
...args,
|
|
1656
|
+
slot
|
|
1657
|
+
}),
|
|
1658
|
+
replaceCollector: (args) => base.replaceCollector({
|
|
1659
|
+
...args,
|
|
1660
|
+
slot
|
|
1661
|
+
}),
|
|
1662
|
+
stopPreviousCollector: (args) => base.stopPreviousCollector({
|
|
1663
|
+
...args,
|
|
1664
|
+
slot
|
|
1665
|
+
}),
|
|
1666
|
+
clearIosAdoptionPending: (root) => base.clearIosAdoptionPending(root, slot),
|
|
1667
|
+
writeWorkspaceLaunch: (root, platform, record) => base.writeWorkspaceLaunch(root, platform, record, slot),
|
|
1668
|
+
createWriter: (file, options) => base.createWriter(file, {
|
|
1669
|
+
...options,
|
|
1670
|
+
fields: { slot }
|
|
1671
|
+
})
|
|
1672
|
+
};
|
|
1673
|
+
}
|
|
1674
|
+
return d;
|
|
1675
|
+
}
|
|
1595
1676
|
async function runIos(opts = {}, overrides = {}) {
|
|
1596
|
-
|
|
1677
|
+
const slot = validateDeviceSlot(opts.slot);
|
|
1678
|
+
let d = iosSlotDeps({
|
|
1597
1679
|
...DEFAULT_DEPS,
|
|
1598
1680
|
...overrides
|
|
1599
|
-
};
|
|
1681
|
+
}, slot);
|
|
1600
1682
|
const json = Boolean(opts.json);
|
|
1601
1683
|
const metroCheck = opts.metroCheck !== false;
|
|
1602
1684
|
let useBuildCache = opts.buildCache !== false;
|
|
@@ -1642,7 +1724,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
1642
1724
|
return null;
|
|
1643
1725
|
}
|
|
1644
1726
|
const logsDir = workspaceLogsDir(root);
|
|
1645
|
-
const logFile =
|
|
1727
|
+
const logFile = iosSlotLogFile(root, slot);
|
|
1646
1728
|
let writer = null;
|
|
1647
1729
|
const logWriter = () => writer ||= d.createWriter(logFile, { truncate: true });
|
|
1648
1730
|
let buildLock = null;
|
|
@@ -1781,7 +1863,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
1781
1863
|
message: settingError,
|
|
1782
1864
|
remedy: SETTING_SHAPE_REMEDY
|
|
1783
1865
|
});
|
|
1784
|
-
const configuration = resolveConfiguration(opts.configuration, settings);
|
|
1866
|
+
const configuration = opts.easProfile !== void 0 ? null : resolveConfiguration(opts.configuration, settings);
|
|
1785
1867
|
const buildScheme = opts.scheme;
|
|
1786
1868
|
const release = isReleaseConfiguration(configuration);
|
|
1787
1869
|
const cachePolicy = artifactCachePolicy(optimizations, useBuildCache, release);
|
|
@@ -1789,7 +1871,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
1789
1871
|
const deviceType = resolveDeviceType(opts.deviceType, settings);
|
|
1790
1872
|
const runtime = resolveRuntime(opts.runtime, settings);
|
|
1791
1873
|
const deviceFlag = opts.device;
|
|
1792
|
-
const physical = deviceFlag
|
|
1874
|
+
const physical = isPhysicalDeviceRequest(deviceFlag);
|
|
1793
1875
|
if (physical && deviceFlag === "") return fail({
|
|
1794
1876
|
code: "STIM_BAD_ARG",
|
|
1795
1877
|
message: "--device was given an empty UDID.",
|
|
@@ -1824,6 +1906,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
1824
1906
|
if (schemeRefusal) return fail(schemeRefusal);
|
|
1825
1907
|
const remoteBackend = physical ? null : opts.remote ?? remoteIosSetting(settings);
|
|
1826
1908
|
const modelRefusal = deviceModelRefusal({
|
|
1909
|
+
slot,
|
|
1827
1910
|
deviceTypeFlag: opts.deviceType,
|
|
1828
1911
|
runtimeFlag: opts.runtime,
|
|
1829
1912
|
deviceType,
|
|
@@ -1833,6 +1916,17 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
1833
1916
|
listRuntimes: d.listIosRuntimes
|
|
1834
1917
|
});
|
|
1835
1918
|
if (modelRefusal) return fail(modelRefusal);
|
|
1919
|
+
const easBuild = await d.resolveEasDevelopmentBuild({
|
|
1920
|
+
root,
|
|
1921
|
+
platform: "ios",
|
|
1922
|
+
profile: opts.easProfile,
|
|
1923
|
+
note,
|
|
1924
|
+
isExpo,
|
|
1925
|
+
physical,
|
|
1926
|
+
selectors: [opts.scheme, opts.configuration],
|
|
1927
|
+
buildCache: opts.buildCache
|
|
1928
|
+
});
|
|
1929
|
+
if (isEasBuildFailure(easBuild)) return fail(easBuild);
|
|
1836
1930
|
const registerProject = () => d.upsertProject(root, {
|
|
1837
1931
|
bundleId: d.detectBundleId(root) ?? void 0,
|
|
1838
1932
|
isExpo
|
|
@@ -2112,6 +2206,38 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2112
2206
|
return result;
|
|
2113
2207
|
});
|
|
2114
2208
|
udid = device.deviceUdid ?? (await bootPromise)?.udid ?? "";
|
|
2209
|
+
if (easBuild?.ok) {
|
|
2210
|
+
fingerprint = storeHash = easBuild.fingerprint;
|
|
2211
|
+
cacheKey = storeKey = easBuild.cacheKey;
|
|
2212
|
+
appPath = easBuild.path;
|
|
2213
|
+
cacheHit = easBuild.cacheHit;
|
|
2214
|
+
providerName = "eas";
|
|
2215
|
+
stats.setCacheKey(cacheKey);
|
|
2216
|
+
if (physical) {
|
|
2217
|
+
const gate = d.gateProfileForDevice({
|
|
2218
|
+
appPath,
|
|
2219
|
+
udid,
|
|
2220
|
+
configuration
|
|
2221
|
+
});
|
|
2222
|
+
if (!gate.ok) {
|
|
2223
|
+
fail({
|
|
2224
|
+
code: gate.code,
|
|
2225
|
+
message: gate.reason,
|
|
2226
|
+
remedy: easDeviceBuildRemedy(opts.easProfile)
|
|
2227
|
+
});
|
|
2228
|
+
return false;
|
|
2229
|
+
}
|
|
2230
|
+
if (!d.devClientScheme(root, appPath)) {
|
|
2231
|
+
fail({
|
|
2232
|
+
code: "STIM_BAD_ARG",
|
|
2233
|
+
message: "The EAS device app has no development-client URL scheme.",
|
|
2234
|
+
remedy: "Install expo-dev-client with npx expo install expo-dev-client, then rebuild the EAS profile and retry."
|
|
2235
|
+
});
|
|
2236
|
+
return false;
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
return true;
|
|
2240
|
+
}
|
|
2115
2241
|
const fingerprintTimer = stepTimer(d.now);
|
|
2116
2242
|
let computedFingerprint;
|
|
2117
2243
|
try {
|
|
@@ -2635,10 +2761,12 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2635
2761
|
}
|
|
2636
2762
|
try {
|
|
2637
2763
|
if (!await resolveInitialFingerprint()) return null;
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2764
|
+
if (!easBuild) {
|
|
2765
|
+
await resolveRemoteArtifact();
|
|
2766
|
+
if (!await waitForSharedBuild()) return null;
|
|
2767
|
+
await prepareCachedArtifact();
|
|
2768
|
+
if (!await buildArtifact()) return null;
|
|
2769
|
+
}
|
|
2642
2770
|
if (physicalDevice) {
|
|
2643
2771
|
const acquired = await d.acquireRunLease({
|
|
2644
2772
|
root,
|
|
@@ -2673,6 +2801,7 @@ async function runIos(opts = {}, overrides = {}) {
|
|
|
2673
2801
|
}
|
|
2674
2802
|
try {
|
|
2675
2803
|
return await finishIosRun({
|
|
2804
|
+
slot,
|
|
2676
2805
|
d,
|
|
2677
2806
|
root,
|
|
2678
2807
|
json,
|