stim 1.3.0 → 1.4.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 +17 -3
- package/dist/{android-CqcW1hrP.mjs → android-BTR1KTMP.mjs} +206 -120
- package/dist/{android-BqVIJoG7.mjs → android-BkM4qTaN.mjs} +76 -77
- package/dist/{android-cas-BR5YJBYv.mjs → android-cas-BjLRZyks.mjs} +15 -12
- package/dist/{app-install-DIp9riNx.mjs → app-install--PAocWvq.mjs} +2 -2
- package/dist/{build-slots-C3-R4XQr.mjs → build-slots-D6sDzOe-.mjs} +7 -8
- package/dist/{cache-manifest-CXR-Y8pH.mjs → cache-manifest-D02TpYjA.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +14 -13
- package/dist/collector-run.mjs +4 -4
- package/dist/{command-output-8wHMEde0.mjs → command-output-BuIb_ZOI.mjs} +1 -4
- package/dist/{config-CcefMY2Q.mjs → config-6vdGngKa.mjs} +51 -51
- package/dist/dependency-state-BMirHEPD.mjs +76 -0
- package/dist/{deps-Spz8ozgo.mjs → deps-Ck4wuTwa.mjs} +1 -1
- package/dist/{dev-client-BjisHDB5.mjs → dev-client-Cd0v7iZk.mjs} +12 -12
- package/dist/{device-BkiW-gkk.mjs → device-CKXLnRRb.mjs} +7 -7
- package/dist/device-CMDFzx7C.mjs +1136 -0
- package/dist/{device-lease-BJYybF-2.mjs → device-lease-DDJr85OK.mjs} +3 -3
- package/dist/{device-pool-CPbLGfrB.mjs → device-pool-DJvbIBGW.mjs} +4 -4
- package/dist/{device-remote-AkYCKS8U.mjs → device-remote-CMfHhoc8.mjs} +7 -6
- package/dist/{doctor-Bmv86UUW.mjs → doctor-B_mfURdt.mjs} +536 -114
- package/dist/{error-diagnostics-DHC31rXA.mjs → error-diagnostics-_VmkqRZo.mjs} +8 -7
- package/dist/{gc-GGu-8ULN.mjs → gc-0AyxmECv.mjs} +61 -27
- package/dist/{guide-92CPA21s.mjs → guide-CGxdmQ0K.mjs} +236 -67
- package/dist/{ios-BSXFeO5H.mjs → ios-CtmGLx3X.mjs} +2667 -2607
- package/dist/{ios-device-CWOM_S44.mjs → ios-device-DJOi9FR5.mjs} +1 -1
- package/dist/{logs-DPNF4C9s.mjs → logs-BF3qPA7w.mjs} +32 -7
- package/dist/{logs-query-R-Cqc6Qv.mjs → logs-query-Cdp5aaCH.mjs} +1 -1
- package/dist/metro-DFLmaVz8.mjs +99 -0
- package/dist/named-ports-BO7Zpjp0.mjs +137 -0
- package/dist/{ownership-8O073GIC.mjs → ownership-BvSpZVBk.mjs} +5 -5
- package/dist/{ownership-BpCKiRlQ.mjs → ownership-C08Yzrp7.mjs} +6 -6
- package/dist/ports-BiKqP92J.mjs +39 -0
- package/dist/ports-ClqG8GPt.mjs +90 -0
- package/dist/{project-fKmuIaMI.mjs → project-CBFCwnN5.mjs} +2 -2
- package/dist/{reclaim-iW9Cad7k.mjs → reclaim-DpDVo-AP.mjs} +20 -13
- package/dist/{reload-DazHDSFA.mjs → reload-ByTqg6ZI.mjs} +8 -8
- package/dist/rolldown-runtime-BsOwBuO_.mjs +30 -0
- package/dist/{server-bare-DEzPZLvf.mjs → server-bare-Buk-k8tI.mjs} +3 -6
- package/dist/{server-expo-DizT4OMk.mjs → server-expo-D4P7iTvf.mjs} +3 -3
- package/dist/server-expo-Dho5Raiw.mjs +2 -0
- package/dist/{settings-DEJf6_kJ.mjs → settings-DwfltIXQ.mjs} +2 -2
- package/dist/{slot-launch-cci0xvmC.mjs → slot-launch-DeKen9e5.mjs} +4 -4
- package/dist/{start-mObjQH2W.mjs → start-BpKUHcU_.mjs} +16 -14
- package/dist/state-CDbvmZdt.mjs +131 -0
- package/dist/{stats-BR-kwj0B.mjs → stats-C59QLKm2.mjs} +1 -1
- package/dist/{stats-CaaQr4yN.mjs → stats-k5qMjyxo.mjs} +4 -4
- package/dist/{status-BxQNqu9t.mjs → status-Y2ij3dm6.mjs} +13 -12
- package/dist/{stop-DimGXEKY.mjs → stop-_P2OQwmZ.mjs} +15 -14
- package/dist/{stop-CrHGcjrV.mjs → stop-vKmmxhea.mjs} +2 -2
- package/dist/supervisor-run.d.mts +3 -27
- package/dist/supervisor-run.mjs +7 -6
- package/dist/{teardown-ClFp1Aax.mjs → teardown-KsPpvldq.mjs} +248 -110
- package/dist/{workspace-process-lock-3NcQnZ0X.mjs → workspace-process-lock-UEIrvZMJ.mjs} +4 -4
- package/dist/workspace-state-Do1e2mOH.mjs +146 -0
- package/dist/{worktree-DxTgN1CJ.mjs → worktree-BvcAIMdJ.mjs} +132 -123
- package/dist/{worktree-Eq6TLH8N.mjs → worktree-DWNx4tUg.mjs} +32 -2
- package/dist/xcode-D9tVItl-.mjs +860 -0
- package/package.json +7 -7
- package/dist/doctor-fAMXC4vl.mjs +0 -530
- package/dist/metro-CORqXyTL.mjs +0 -184
- package/dist/ownership-claim-Bf2CAfw3.mjs +0 -570
- package/dist/server-expo-44em5Pmg.mjs +0 -2
- package/dist/state-B3XA2wp2.mjs +0 -268
- package/dist/xcode-D7sAp-Zy.mjs +0 -1858
package/README.md
CHANGED
|
@@ -44,8 +44,9 @@ stim stop
|
|
|
44
44
|
|
|
45
45
|
For `stim logs --errors`, a clean check requires exit code 0 and no matching
|
|
46
46
|
errors in the captured logs. Exit code 0 alone means the query succeeded, even
|
|
47
|
-
when it prints errors
|
|
48
|
-
|
|
47
|
+
when it prints errors. A workspace that has never produced a log timeline
|
|
48
|
+
refuses with `STIM_NO_PROJECT`; in a monorepo, the error names the nearest
|
|
49
|
+
registered descendant app with logs when one exists.
|
|
49
50
|
|
|
50
51
|
Use `stim start --reset-cache` to recover from stale Metro transforms or file-map
|
|
51
52
|
state. It restarts only this app's verified owned Metro, keeping its port and
|
|
@@ -128,7 +129,7 @@ eligible `.env` and local configuration files. Existing entries are preserved;
|
|
|
128
129
|
existing ignored directories such as `node_modules` are skipped whole.
|
|
129
130
|
|
|
130
131
|
`stim worktree warm --refresh` brings the source checkout up to date first: it
|
|
131
|
-
fetches, fast-forwards whatever branch is checked out there, and installs what
|
|
132
|
+
checks the upstream, fetches changes when needed, fast-forwards whatever branch is checked out there, and installs what
|
|
132
133
|
the new commits moved before copying. It refuses a source checkout it cannot
|
|
133
134
|
move (uncommitted tracked changes, a rebase or merge in progress, a detached
|
|
134
135
|
HEAD, a diverged branch) and never switches branches. One lock per repository
|
|
@@ -197,3 +198,16 @@ stim stop --slot tablet
|
|
|
197
198
|
`--slot` preserves the shared server and other devices. `stim reload ios` or
|
|
198
199
|
`stim reload android` can reload multiple connected devices. Read
|
|
199
200
|
`stim guide lifecycle options` for launch verification and recycling behavior.
|
|
201
|
+
|
|
202
|
+
### Named server ports
|
|
203
|
+
|
|
204
|
+
Use `stim ports get web` to reserve a workspace port for a server Stim does not
|
|
205
|
+
manage, then pass that number to the server, for example
|
|
206
|
+
`pnpm exec vite --port "$(stim ports get web)" --strictPort`.
|
|
207
|
+
`stim ports` lists named allocations and managed Metro. `stim ports stop web`
|
|
208
|
+
stops the TCP listener and releases its port; `--dry-run` previews the action.
|
|
209
|
+
`stim ports release web` releases without stopping. Omitting the label selects
|
|
210
|
+
all named ports. These commands leave Metro alone, and `stim stop` leaves
|
|
211
|
+
named ports alone. Worktree removal and `gc --delete` stop and release named
|
|
212
|
+
ports for removed workspaces. Read `stim guide ports` for the reserved band,
|
|
213
|
+
listener ownership, and allocation limits.
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { C as withConfigLock,
|
|
2
|
+
import { C as withConfigLock, E as ownership_claim_exports, F as deviceSlotPlatforms, P as deviceSlotKey, S as upsertProject, b as setDevice, f as getProject, g as loadConfig, l as getConcurrencyLimits, y as saveConfig, z as validateDeviceSlot } from "./config-6vdGngKa.mjs";
|
|
3
3
|
import { r as createNdjsonWriter } from "./ndjson-BZwI1NBv.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { C as
|
|
6
|
-
import { a as findProjectRoot, c as projectShortcut, i as detectIsExpo, n as detectAndroidPackage, r as detectBundleId, t as appProjectProblem } from "./project-
|
|
4
|
+
import { _ as workspaceLogsDir, h as workspaceDir, o as writeWorkspaceState, r as readWorkspaceState, s as emulatorLogFile } from "./workspace-state-Do1e2mOH.mjs";
|
|
5
|
+
import { C as makeTemporaryDirectory, _ as repoRoot, s as gitCommonDir, w as removeTemporaryEntry } from "./worktree-DWNx4tUg.mjs";
|
|
6
|
+
import { a as findProjectRoot, c as projectShortcut, i as detectIsExpo, n as detectAndroidPackage, r as detectBundleId, t as appProjectProblem } from "./project-CBFCwnN5.mjs";
|
|
7
|
+
import { n as MODE_EXPO, p as writeWorkspaceLaunch, t as MODE_BARE } from "./state-CDbvmZdt.mjs";
|
|
7
8
|
import { r as waitForChild, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
|
|
8
|
-
import { i as resolveProjectMetro, r as pidExists } from "./metro-
|
|
9
|
-
import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-
|
|
10
|
-
import { _ as launchErrorPreview, c as launchErrorReport, g as stepTimer, h as stepClock, i as formatDuration, l as phaseLine, n as appReadinessMessage, p as shortHash } from "./command-output-
|
|
11
|
-
import { r as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { t as
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { a as
|
|
24
|
-
import {
|
|
25
|
-
import { n as nativeRunCommand, t as launchSlotScope } from "./slot-launch-
|
|
9
|
+
import { i as resolveProjectMetro, r as pidExists } from "./metro-DFLmaVz8.mjs";
|
|
10
|
+
import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-BvSpZVBk.mjs";
|
|
11
|
+
import { _ as launchErrorPreview, c as launchErrorReport, g as stepTimer, h as stepClock, i as formatDuration, l as phaseLine, n as appReadinessMessage, p as shortHash } from "./command-output-BuIb_ZOI.mjs";
|
|
12
|
+
import { $ as providerDownloadPath, C as memoizeEmulatorProbe, G as buildCacheKey, J as filesystemBuildCapability, K as describeFingerprintMiss, L as waitForBoot, M as resetAdoptedAvd, N as resolveOwnedAvdSerial, P as resolvePhysicalDevice, 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, _ as findBuildTool, a as androidSystemImageAbi, at as untrackedMissLine, ct as captureAssetManifest, et as providerUploadOutcome, g as extractEmulatorFailure, h as emulatorFailureRemedy, i as androidPoolNoCandidatesRefusal, it as storedAssetManifest, j as probeEmulatorSerial, k as physicalDeviceModel, lt as compareAssetManifests, m as emulatorDiskSpaceRemedy, n as androidHome, nt as resolveBuild, ot as untrackedNativeFiles, r as androidPoolCandidates, rt as storeBuild, st as assetDiffReason, t as androidDeviceAbi, tt as refingerprintAfterMutation, ut as readAssetManifest, x as listInstalledSystemImages, y as listAdbDevices, z as acquireBuildLock } from "./android-BkM4qTaN.mjs";
|
|
13
|
+
import { A as resolveSettings, B as artifactCachePolicy, D as remoteDeviceSettingError, E as remoteAndroidSetting, F as tunnelModeSetting, H as optimizationBuildProfile, I as unknownSettingKeys, N as settingShapeErrors, R as detectProviders, T as publicUrlSetting, U as resolveOptimizations, V as compilerCacheFallbackMessage, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, j as settingFile, k as resolveCacheProviderConfig, r as REMOTE_DEVICE_BACKENDS, s as androidAvdConfigSettingError, u as androidDataPartitionSizeGbSettingError, x as metroWarmupUrlSetting } from "./settings-DwfltIXQ.mjs";
|
|
14
|
+
import { t as cleanLine } from "./server-expo-D4P7iTvf.mjs";
|
|
15
|
+
import { C as resolveRemote, S as resolveEasCliBin, _ as exitAfterFlush, f as RESOLVE_TIMEOUT_MS, g as easAuthNote, h as checkEasAuth, l as parkedMaxSetting, m as cacheLevel, p as UPLOAD_TIMEOUT_MS, v as isEasAuthFailureText, w as uploadRemote, y as loadProjectProvider } from "./teardown-KsPpvldq.mjs";
|
|
16
|
+
import { c as ensureWorkspaceStorageSafely, d as launchOutcomeRecord, f as noMetroMessage, g as warmMetro, i as detectEntryFile, m as resolveMetroWithRetry, n as pickDevClientScheme, o as needsPrebuild, p as noMetroRemedy, s as runPrebuild, t as devClientScheme, u as isPhysicalDeviceRequest, v as isEasBuildFailure, y as resolveEasDevelopmentBuild } from "./dev-client-Cd0v7iZk.mjs";
|
|
17
|
+
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-UEIrvZMJ.mjs";
|
|
18
|
+
import { D as verifyAndroidReleaseLaunch, E as unverifiedLaunchLines, O as verifyLaunch, S as launchAndroidReleaseApp, _ as installConflictKind, c as RELEASE_VERIFY_WAIT_MS, d as androidDevClientUrl, g as installAndroidApp, h as deviceShellArg, i as LAUNCH_BUNDLING, l as VERIFY_TIMEOUT_MS, n as DEFAULT_METRO_PORT, o as LAUNCH_FATAL, s as LAUNCH_UNVERIFIED, t as ADB_INSTALL_TIMEOUT_MS, u as androidAppProcess, x as launchAndroidApp } from "./app-install--PAocWvq.mjs";
|
|
19
|
+
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-DJvbIBGW.mjs";
|
|
20
|
+
import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-D6sDzOe-.mjs";
|
|
21
|
+
import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-C59QLKm2.mjs";
|
|
22
|
+
import { i as ensureOwnedDevice, l as AvdBootError, o as unknownAndroidSystemImageRefusal, r as ensureBooted, t as checkDeviceCapacity, u as AvdRecoveryError } from "./device-CMDFzx7C.mjs";
|
|
23
|
+
import { a as ensureMetroReachable, b as ownedSessionName, l as resolveRemoteContext, n as binOnPath, o as ensureRemoteBootOwned, s as remoteAndroidDeps } from "./device-remote-CMfHhoc8.mjs";
|
|
24
|
+
import { a as buildAndroid, c as CCACHE_NOT_RUN, f as resolveCcache, l as CCACHE_UNAVAILABLE, n as resolveAndroidCas, o as productFlavorRefusal, p as formatDiagnostic, r as resolveAndroidCompilerCache, s as readProductFlavors, u as ccacheActivityLine } from "./android-cas-BjLRZyks.mjs";
|
|
25
|
+
import { d as startBuildHeartbeat, f as tailLines, n as HEARTBEAT_INTERVAL_MS } from "./xcode-D9tVItl-.mjs";
|
|
26
|
+
import { n as nativeRunCommand, t as launchSlotScope } from "./slot-launch-DeKen9e5.mjs";
|
|
26
27
|
import { t as spawnEntry } from "./spawn-entry-nCE6m770.mjs";
|
|
27
|
-
import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-
|
|
28
|
+
import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-_VmkqRZo.mjs";
|
|
28
29
|
import { existsSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
29
30
|
import { InvalidArgumentError } from "commander";
|
|
30
31
|
import { basename, dirname, join, relative } from "node:path";
|
|
@@ -1012,12 +1013,7 @@ async function finishAndroidRun({ lease, releaseLease, root, slot, json, metroCh
|
|
|
1012
1013
|
deviceId: booted.serial
|
|
1013
1014
|
});
|
|
1014
1015
|
if (booted.failed) {
|
|
1015
|
-
const diag =
|
|
1016
|
-
reason: booted.reason ?? "The emulator did not boot.",
|
|
1017
|
-
logFile: emuLog,
|
|
1018
|
-
remedy: `Run \`stim status\` to see what Stim thinks it owns; re-running \`${runCommand}\` creates a fresh owned AVD.`,
|
|
1019
|
-
localEmulator: !physical
|
|
1020
|
-
});
|
|
1016
|
+
const diag = diagnoseBootFailure(booted, emuLog, runCommand, physical);
|
|
1021
1017
|
return fail(NO_DEVICE, diag.message, diag.remedy, {
|
|
1022
1018
|
lines: diag.lines,
|
|
1023
1019
|
logPath: diag.logPath ? displayPath(root, diag.logPath) : null
|
|
@@ -1275,9 +1271,25 @@ async function finishAndroidRun({ lease, releaseLease, root, slot, json, metroCh
|
|
|
1275
1271
|
facts
|
|
1276
1272
|
};
|
|
1277
1273
|
}
|
|
1274
|
+
function diagnoseBootFailure(booted, logFile, runCommand, physical) {
|
|
1275
|
+
return noDeviceDiagnostic({
|
|
1276
|
+
reason: booted.reason ?? "The emulator did not boot.",
|
|
1277
|
+
logFile,
|
|
1278
|
+
remedy: booted.remedy ?? `Run \`stim status\` to see what Stim thinks it owns; re-running \`${runCommand}\` creates a fresh owned AVD.`,
|
|
1279
|
+
localEmulator: !physical
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1278
1282
|
//#endregion
|
|
1279
|
-
//#region src/commands/android.ts
|
|
1280
|
-
|
|
1283
|
+
//#region src/commands/android/plan.ts
|
|
1284
|
+
function fail(code, message, remedy, { lines = [] } = {}) {
|
|
1285
|
+
return {
|
|
1286
|
+
ok: false,
|
|
1287
|
+
code,
|
|
1288
|
+
message,
|
|
1289
|
+
remedy,
|
|
1290
|
+
lines
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1281
1293
|
function androidCompilerCache({ root, optimizations, settingsContext }) {
|
|
1282
1294
|
const { cas, optimizations: resolved } = resolveAndroidCompilerCache({
|
|
1283
1295
|
optimizations,
|
|
@@ -1302,6 +1314,104 @@ function androidCompilerCache({ root, optimizations, settingsContext }) {
|
|
|
1302
1314
|
})}`
|
|
1303
1315
|
};
|
|
1304
1316
|
}
|
|
1317
|
+
function resolveAndroidRunPlan({ settings, settingsContext, slot, easProfile, variant: variantFlag, systemImage: systemImageFlag, device: deviceFlag, wait: waitFlag, waitConflict, remote: commandRemoteBackend, buildCache: requestedBuildCache }, { warn, resolveCompilerCache = androidCompilerCache, resolveCacheProvider = resolveCacheProviderConfig, validateAvdConfig = androidAvdConfigSettingError, readFlavors = readProductFlavors, detectExpo = detectIsExpo, listSystemImages = listInstalledSystemImages, parkedLimit = parkedMaxSetting }) {
|
|
1318
|
+
const root = settingsContext.projectPath;
|
|
1319
|
+
const [shapeError, ...moreShapeErrors] = [parkedLimit("android").error, ...settingShapeErrors(settings)].filter((error) => Boolean(error));
|
|
1320
|
+
if (shapeError) return fail("STIM_BAD_ARG", shapeError, SETTING_SHAPE_REMEDY, { lines: moreShapeErrors });
|
|
1321
|
+
for (const key of unknownSettingKeys(settings)) warn("setting", `Warning: setting "${key}" is not read by Stim and will be ignored.`);
|
|
1322
|
+
let optimizations;
|
|
1323
|
+
try {
|
|
1324
|
+
optimizations = resolveOptimizations(settings);
|
|
1325
|
+
} catch (error) {
|
|
1326
|
+
return fail("STIM_BAD_ARG", `Could not configure Android build: ${error.message}`, SETTING_SHAPE_REMEDY);
|
|
1327
|
+
}
|
|
1328
|
+
const compilerCache = resolveCompilerCache({
|
|
1329
|
+
root,
|
|
1330
|
+
optimizations,
|
|
1331
|
+
settingsContext
|
|
1332
|
+
});
|
|
1333
|
+
const cas = compilerCache.cas;
|
|
1334
|
+
optimizations = compilerCache.optimizations;
|
|
1335
|
+
if (compilerCache.warning) warn("cache", compilerCache.warning);
|
|
1336
|
+
const buildProfile = optimizationBuildProfile("android", optimizations);
|
|
1337
|
+
const cacheProviderConfig = resolveCacheProvider(settingsContext);
|
|
1338
|
+
const cacheProviderError = cacheProviderSettingError(settings);
|
|
1339
|
+
if (cacheProviderError) warn("cache", `${cacheProviderError} Using the local cache.`);
|
|
1340
|
+
const dataPartitionSizeError = androidDataPartitionSizeGbSettingError(settings);
|
|
1341
|
+
if (dataPartitionSizeError) return fail("STIM_BAD_ARG", dataPartitionSizeError, "Set android.dataPartitionSizeGb to a whole number of GiB from 6 through 16384.");
|
|
1342
|
+
const avdConfigError = validateAvdConfig(settings, root);
|
|
1343
|
+
if (avdConfigError) return fail("STIM_BAD_ARG", avdConfigError, "Use only documented android.avdConfig keys, or an android.avdConfigFile fragment contained by the app directory.");
|
|
1344
|
+
const remoteSettingError = remoteDeviceSettingError(settings);
|
|
1345
|
+
if (remoteSettingError) return fail("STIM_BAD_ARG", remoteSettingError, `Set ios.remote and android.remote to one of: ${REMOTE_DEVICE_BACKENDS.join(", ")}.`);
|
|
1346
|
+
const systemImage = resolveSystemImage(systemImageFlag, settings);
|
|
1347
|
+
const variant = easProfile !== void 0 ? "debug" : resolveVariant(variantFlag, settings);
|
|
1348
|
+
const flavorRefusal = productFlavorRefusal({
|
|
1349
|
+
flavors: readFlavors(root),
|
|
1350
|
+
variant
|
|
1351
|
+
});
|
|
1352
|
+
if (flavorRefusal) return fail(flavorRefusal.code, flavorRefusal.reason, flavorRefusal.remedy);
|
|
1353
|
+
const release = isReleaseVariant(variant);
|
|
1354
|
+
const cachePolicy = artifactCachePolicy(optimizations, requestedBuildCache, release);
|
|
1355
|
+
const isExpo = detectExpo(root);
|
|
1356
|
+
const physical = isPhysicalDeviceRequest(deviceFlag);
|
|
1357
|
+
if (physical && deviceFlag === "") return fail("STIM_BAD_ARG", "--device was given an empty serial.", "Pass `--device` on its own to take the first connected device this workspace can lease, or `--device <serial>` to name one.");
|
|
1358
|
+
if (physical && commandRemoteBackend) return fail("STIM_BAD_ARG", "--device installs on a device connected to this machine, and --remote installs on a remote one.", "Pass only one of --device and --remote.");
|
|
1359
|
+
const noWait = waitFlag === false;
|
|
1360
|
+
const waitFlagged = waitFlag !== void 0;
|
|
1361
|
+
if (waitConflict) return fail("STIM_BAD_ARG", "--wait and --no-wait ask for opposite things.", "Pass `--wait <seconds>` to wait for the lease, or `--no-wait` to install without one.");
|
|
1362
|
+
if (waitFlagged && !physical) return fail("STIM_BAD_ARG", "--wait and --no-wait only apply to a `--device` run.", "This workspace owns its emulator, so nothing contends for it. Drop the flag, or pass `--device`.");
|
|
1363
|
+
const waitParsed = parseDeviceWait(noWait ? void 0 : waitFlag);
|
|
1364
|
+
if ("error" in waitParsed) return fail("STIM_BAD_ARG", waitParsed.error, "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a leased device at once.");
|
|
1365
|
+
const waitSeconds = waitParsed.seconds;
|
|
1366
|
+
const remoteBackend = physical ? null : commandRemoteBackend ?? remoteAndroidSetting(settings);
|
|
1367
|
+
const imageRefusal = systemImageRefusal({
|
|
1368
|
+
slot,
|
|
1369
|
+
flag: systemImageFlag,
|
|
1370
|
+
resolved: systemImage,
|
|
1371
|
+
physical,
|
|
1372
|
+
remoteBackend,
|
|
1373
|
+
listImages: listSystemImages
|
|
1374
|
+
});
|
|
1375
|
+
if (imageRefusal) return fail(imageRefusal.code, imageRefusal.message, imageRefusal.remedy);
|
|
1376
|
+
const target = physical ? {
|
|
1377
|
+
kind: "physical",
|
|
1378
|
+
serial: typeof deviceFlag === "string" ? deviceFlag : null,
|
|
1379
|
+
lease: {
|
|
1380
|
+
waitSeconds,
|
|
1381
|
+
noWait
|
|
1382
|
+
}
|
|
1383
|
+
} : remoteBackend ? {
|
|
1384
|
+
kind: "remote",
|
|
1385
|
+
backend: remoteBackend,
|
|
1386
|
+
systemImage
|
|
1387
|
+
} : {
|
|
1388
|
+
kind: "emulator",
|
|
1389
|
+
systemImage
|
|
1390
|
+
};
|
|
1391
|
+
return {
|
|
1392
|
+
ok: true,
|
|
1393
|
+
plan: {
|
|
1394
|
+
build: {
|
|
1395
|
+
variant,
|
|
1396
|
+
release,
|
|
1397
|
+
profile: buildProfile,
|
|
1398
|
+
cas,
|
|
1399
|
+
cache: cachePolicy,
|
|
1400
|
+
compilerCache: optimizations.android.compilerCache,
|
|
1401
|
+
gradleBuildCache: optimizations.android.gradleBuildCache,
|
|
1402
|
+
pch: optimizations.android.pch,
|
|
1403
|
+
targetAbiOnly: optimizations.android.targetAbiOnly
|
|
1404
|
+
},
|
|
1405
|
+
target,
|
|
1406
|
+
isExpo,
|
|
1407
|
+
metroWarmup: optimizations.metroWarmup,
|
|
1408
|
+
cacheProviderConfig
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
//#endregion
|
|
1413
|
+
//#region src/commands/android.ts
|
|
1414
|
+
const FALLBACK_LINES = 5;
|
|
1305
1415
|
function androidCommand(program) {
|
|
1306
1416
|
registerAndroid(program);
|
|
1307
1417
|
}
|
|
@@ -1448,6 +1558,25 @@ function androidSlotOptions(options) {
|
|
|
1448
1558
|
writeLaunch: ((projectRoot, platform, record) => base.writeLaunch(projectRoot, platform, record, slot))
|
|
1449
1559
|
};
|
|
1450
1560
|
}
|
|
1561
|
+
function avdSetupFailure(error, root, logFile) {
|
|
1562
|
+
const refusal = (0, ownership_claim_exports.claimFailure)(error, "stim android");
|
|
1563
|
+
if (refusal) return refusal;
|
|
1564
|
+
const diag = noDeviceDiagnostic({
|
|
1565
|
+
reason: `Could not ensure an owned Android emulator: ${error?.message || error}`,
|
|
1566
|
+
logFile,
|
|
1567
|
+
localEmulator: !(error instanceof AvdRecoveryError),
|
|
1568
|
+
remedy: error instanceof AvdBootError ? error.remedy : "Check that JAVA_HOME and ANDROID_HOME are set correctly, and that an arm64 system image is installed (`sdkmanager \"system-images;android-36;google_apis;arm64-v8a\"`)."
|
|
1569
|
+
});
|
|
1570
|
+
return {
|
|
1571
|
+
code: NO_DEVICE,
|
|
1572
|
+
message: diag.message,
|
|
1573
|
+
remedy: diag.remedy,
|
|
1574
|
+
extra: {
|
|
1575
|
+
lines: diag.lines,
|
|
1576
|
+
logPath: diag.logPath ? displayPath(root, diag.logPath) : null
|
|
1577
|
+
}
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1451
1580
|
async function runAndroid(options = {}) {
|
|
1452
1581
|
let { root, json, commandRemoteBackend, resolveSettingsFor, resolveRemoteDeviceContext, makeRemoteDeviceDeps, resolveEasBin, ensureRemoteMetro, ensureRemoteOwned, detectRemoteProviders, metroCheck, useBuildCache: requestedBuildCache, easProfile, resolveEasBuild, variantFlag, systemImageFlag, deviceFlag, waitFlag, waitConflict, acquireLease, makeRunLease, selectPool, onLeaseSignal, listDevices, deviceModel, deviceAbi, isEmulatorDevice, readApkPackage, getLimits, checkCapacity, acquireSlot, releaseSlot, ensureDevice, listSystemImages, ensureDeviceBooted, resolveAvdSerial, waitForDeviceBoot, resolveMetro, prewarmMetro, resolveMetroRetrying, readState, pidAlive, verifyCollector, verifyLaunched, ensureStorage, fingerprint, untracked, resolveCached, storeCached, storedAssets, captureAssets, acquireLock, releaseLock, waitForBuild, loadProvider, easAuth, resolveRemoteBuild, uploadRemoteBuild, resolveCacheProvider, loadCacheProviderModule, needsPrebuildFor, prebuild, build, ccacheFor, install, launch, launchRelease, verifyReleaseLaunched, swapApk, resolveDevClientScheme, spawn, kill, createWriter, writeLaunch, writeState, recordStats, readEstimates, now, out, emit } = androidSlotOptions(options);
|
|
1453
1582
|
const slot = validateDeviceSlot(options.slot);
|
|
@@ -1596,64 +1725,30 @@ async function runAndroid(options = {}) {
|
|
|
1596
1725
|
platform: PLATFORM
|
|
1597
1726
|
});
|
|
1598
1727
|
const settings = resolveSettingsFor(settingsContext);
|
|
1599
|
-
const
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
let optimizations;
|
|
1603
|
-
try {
|
|
1604
|
-
optimizations = resolveOptimizations(settings);
|
|
1605
|
-
} catch (error) {
|
|
1606
|
-
return fail("STIM_BAD_ARG", `Could not configure Android build: ${error.message}`, SETTING_SHAPE_REMEDY);
|
|
1607
|
-
}
|
|
1608
|
-
const compilerCache = androidCompilerCache({
|
|
1609
|
-
root,
|
|
1610
|
-
optimizations,
|
|
1611
|
-
settingsContext
|
|
1612
|
-
});
|
|
1613
|
-
const cas = compilerCache.cas;
|
|
1614
|
-
optimizations = compilerCache.optimizations;
|
|
1615
|
-
if (compilerCache.warning) out(phaseLine("cache", chalk.yellow(compilerCache.warning)));
|
|
1616
|
-
const buildProfile = optimizationBuildProfile("android", optimizations);
|
|
1617
|
-
const cacheProviderConfig = resolveCacheProvider(settingsContext);
|
|
1618
|
-
const cacheProviderError = cacheProviderSettingError(settings);
|
|
1619
|
-
if (cacheProviderError) out(phaseLine("cache", chalk.yellow(`${cacheProviderError} Using the local cache.`)));
|
|
1620
|
-
const dataPartitionSizeError = androidDataPartitionSizeGbSettingError(settings);
|
|
1621
|
-
if (dataPartitionSizeError) return fail("STIM_BAD_ARG", dataPartitionSizeError, "Set android.dataPartitionSizeGb to a whole number of GiB from 6 through 16384.");
|
|
1622
|
-
const avdConfigError = androidAvdConfigSettingError(settings, settingsRoot);
|
|
1623
|
-
if (avdConfigError) return fail("STIM_BAD_ARG", avdConfigError, "Use only documented android.avdConfig keys, or an android.avdConfigFile fragment contained by the app directory.");
|
|
1624
|
-
const remoteSettingError = remoteDeviceSettingError(settings);
|
|
1625
|
-
if (remoteSettingError) return fail("STIM_BAD_ARG", remoteSettingError, `Set ios.remote and android.remote to one of: ${REMOTE_DEVICE_BACKENDS.join(", ")}.`);
|
|
1626
|
-
const systemImage = resolveSystemImage(systemImageFlag, settings);
|
|
1627
|
-
const variant = easProfile !== void 0 ? "debug" : resolveVariant(variantFlag, settings);
|
|
1628
|
-
const flavorRefusal = productFlavorRefusal({
|
|
1629
|
-
flavors: readProductFlavors(root),
|
|
1630
|
-
variant
|
|
1631
|
-
});
|
|
1632
|
-
if (flavorRefusal) return fail(flavorRefusal.code, flavorRefusal.reason, flavorRefusal.remedy);
|
|
1633
|
-
const release = isReleaseVariant(variant);
|
|
1634
|
-
const cachePolicy = artifactCachePolicy(optimizations, requestedBuildCache, release);
|
|
1635
|
-
const useBuildCache = cachePolicy.read;
|
|
1636
|
-
const isExpo = detectIsExpo(root);
|
|
1637
|
-
const physical = isPhysicalDeviceRequest(deviceFlag);
|
|
1638
|
-
if (physical && deviceFlag === "") return fail("STIM_BAD_ARG", "--device was given an empty serial.", "Pass `--device` on its own to take the first connected device this workspace can lease, or `--device <serial>` to name one.");
|
|
1639
|
-
if (physical && commandRemoteBackend) return fail("STIM_BAD_ARG", "--device installs on a device connected to this machine, and --remote installs on a remote one.", "Pass only one of --device and --remote.");
|
|
1640
|
-
const noWait = waitFlag === false;
|
|
1641
|
-
const waitFlagged = waitFlag !== void 0;
|
|
1642
|
-
if (waitConflict) return fail("STIM_BAD_ARG", "--wait and --no-wait ask for opposite things.", "Pass `--wait <seconds>` to wait for the lease, or `--no-wait` to install without one.");
|
|
1643
|
-
if (waitFlagged && !physical) return fail("STIM_BAD_ARG", "--wait and --no-wait only apply to a `--device` run.", "This workspace owns its emulator, so nothing contends for it. Drop the flag, or pass `--device`.");
|
|
1644
|
-
const waitParsed = parseDeviceWait(noWait ? void 0 : waitFlag);
|
|
1645
|
-
if ("error" in waitParsed) return fail("STIM_BAD_ARG", waitParsed.error, "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a leased device at once.");
|
|
1646
|
-
const waitSeconds = waitParsed.seconds;
|
|
1647
|
-
const remoteBackend = physical ? null : commandRemoteBackend ?? remoteAndroidSetting(settings);
|
|
1648
|
-
const imageRefusal = systemImageRefusal({
|
|
1728
|
+
const planned = resolveAndroidRunPlan({
|
|
1729
|
+
settings,
|
|
1730
|
+
settingsContext,
|
|
1649
1731
|
slot,
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1732
|
+
easProfile,
|
|
1733
|
+
variant: variantFlag,
|
|
1734
|
+
systemImage: systemImageFlag,
|
|
1735
|
+
device: deviceFlag,
|
|
1736
|
+
wait: waitFlag,
|
|
1737
|
+
waitConflict,
|
|
1738
|
+
remote: commandRemoteBackend,
|
|
1739
|
+
buildCache: requestedBuildCache
|
|
1740
|
+
}, {
|
|
1741
|
+
resolveCacheProvider,
|
|
1742
|
+
listSystemImages,
|
|
1743
|
+
warn: (label, message) => out(phaseLine(label, chalk.yellow(message)))
|
|
1655
1744
|
});
|
|
1656
|
-
if (
|
|
1745
|
+
if (!planned.ok) return fail(planned.code, planned.message, planned.remedy, { lines: planned.lines });
|
|
1746
|
+
const { plan } = planned;
|
|
1747
|
+
const { build: buildPlan, target, isExpo, cacheProviderConfig } = plan;
|
|
1748
|
+
const { variant, release, profile: buildProfile, cas, cache: cachePolicy } = buildPlan;
|
|
1749
|
+
const useBuildCache = cachePolicy.read;
|
|
1750
|
+
const physical = target.kind === "physical";
|
|
1751
|
+
const remoteBackend = target.kind === "remote" ? target.backend : null;
|
|
1657
1752
|
const easBuild = await resolveEasBuild({
|
|
1658
1753
|
root,
|
|
1659
1754
|
platform: PLATFORM,
|
|
@@ -1665,7 +1760,6 @@ async function runAndroid(options = {}) {
|
|
|
1665
1760
|
buildCache: requestedBuildCache
|
|
1666
1761
|
});
|
|
1667
1762
|
if (isEasBuildFailure(easBuild)) return fail(easBuild.code, easBuild.message, easBuild.remedy);
|
|
1668
|
-
const requestedSerial = typeof deviceFlag === "string" ? deviceFlag : null;
|
|
1669
1763
|
let androidPackage = detectAndroidPackage(root);
|
|
1670
1764
|
record.bundleId = androidPackage;
|
|
1671
1765
|
const registerProject = () => upsertProject(root, {
|
|
@@ -1741,15 +1835,15 @@ async function runAndroid(options = {}) {
|
|
|
1741
1835
|
let device;
|
|
1742
1836
|
let bootDuration = "";
|
|
1743
1837
|
let bootPromise;
|
|
1744
|
-
if (physical && !
|
|
1838
|
+
if (target.kind === "physical" && !target.serial) {
|
|
1745
1839
|
const pooled = await pooledAndroidDevice({
|
|
1746
1840
|
root,
|
|
1747
1841
|
selectPool,
|
|
1748
1842
|
listDevices,
|
|
1749
1843
|
isEmulatorDevice,
|
|
1750
1844
|
deviceModel,
|
|
1751
|
-
waitSeconds,
|
|
1752
|
-
noWait,
|
|
1845
|
+
waitSeconds: target.lease.waitSeconds,
|
|
1846
|
+
noWait: target.lease.noWait,
|
|
1753
1847
|
now,
|
|
1754
1848
|
warn: (line) => out(phaseLine("lease", chalk.yellow(line)))
|
|
1755
1849
|
});
|
|
@@ -1759,8 +1853,8 @@ async function runAndroid(options = {}) {
|
|
|
1759
1853
|
ok: true,
|
|
1760
1854
|
serial: pooled.device.serial
|
|
1761
1855
|
});
|
|
1762
|
-
} else if (physical) {
|
|
1763
|
-
const resolved = resolvePhysicalDevice(
|
|
1856
|
+
} else if (target.kind === "physical") {
|
|
1857
|
+
const resolved = resolvePhysicalDevice(target.serial, listDevices(), isEmulatorDevice);
|
|
1764
1858
|
if (!resolved.serial) return fail(NO_DEVICE, resolved.error, resolved.remedy);
|
|
1765
1859
|
device = {
|
|
1766
1860
|
serial: resolved.serial,
|
|
@@ -1786,22 +1880,14 @@ async function runAndroid(options = {}) {
|
|
|
1786
1880
|
projectPath: root,
|
|
1787
1881
|
settingsRoot,
|
|
1788
1882
|
settings,
|
|
1789
|
-
flags: { systemImage },
|
|
1883
|
+
flags: { systemImage: target.systemImage },
|
|
1790
1884
|
note: out,
|
|
1791
1885
|
out,
|
|
1792
1886
|
logFile: emuLog
|
|
1793
1887
|
});
|
|
1794
1888
|
} catch (err) {
|
|
1795
|
-
const
|
|
1796
|
-
|
|
1797
|
-
logFile: emuLog,
|
|
1798
|
-
localEmulator: !(err instanceof AvdRecoveryError),
|
|
1799
|
-
remedy: err instanceof AvdRecoveryError ? err.remedy : "Check that JAVA_HOME and ANDROID_HOME are set correctly, and that an arm64 system image is installed (`sdkmanager \"system-images;android-36;google_apis;arm64-v8a\"`)."
|
|
1800
|
-
});
|
|
1801
|
-
return fail(NO_DEVICE, diag.message, diag.remedy, {
|
|
1802
|
-
lines: diag.lines,
|
|
1803
|
-
logPath: diag.logPath ? displayPath(root, diag.logPath) : null
|
|
1804
|
-
});
|
|
1889
|
+
const failure = avdSetupFailure(err, root, emuLog);
|
|
1890
|
+
return fail(failure.code, failure.message, failure.remedy, failure.extra);
|
|
1805
1891
|
}
|
|
1806
1892
|
const prepareMs = prepare();
|
|
1807
1893
|
if (device.created || prepareMs >= 2e3) phase("device", `${device.avdName || device.deviceName || label} ${device.created ? "created" : "prepared"} (${formatDuration(prepareMs)})`);
|
|
@@ -1858,7 +1944,7 @@ async function runAndroid(options = {}) {
|
|
|
1858
1944
|
deviceAbi,
|
|
1859
1945
|
compiler: cas?.id,
|
|
1860
1946
|
buildProfile,
|
|
1861
|
-
targetAbiOnly:
|
|
1947
|
+
targetAbiOnly: buildPlan.targetAbiOnly
|
|
1862
1948
|
});
|
|
1863
1949
|
let hash = "";
|
|
1864
1950
|
let providerUpload = null;
|
|
@@ -1960,7 +2046,7 @@ async function runAndroid(options = {}) {
|
|
|
1960
2046
|
return true;
|
|
1961
2047
|
}
|
|
1962
2048
|
const runFromFingerprint = async () => {
|
|
1963
|
-
if (metroCheck && metroPort !== null &&
|
|
2049
|
+
if (metroCheck && metroPort !== null && plan.metroWarmup) prewarmMetro({
|
|
1964
2050
|
port: metroPort,
|
|
1965
2051
|
platform: "android",
|
|
1966
2052
|
isExpo,
|
|
@@ -2036,7 +2122,7 @@ async function runAndroid(options = {}) {
|
|
|
2036
2122
|
logFile: buildLog
|
|
2037
2123
|
});
|
|
2038
2124
|
} catch (err) {
|
|
2039
|
-
const refusal = claimFailure(err, "stim android");
|
|
2125
|
+
const refusal = (0, ownership_claim_exports.claimFailure)(err, "stim android");
|
|
2040
2126
|
if (refusal) {
|
|
2041
2127
|
phaseFailure = fail(refusal.code, refusal.message, refusal.remedy, { lastBuildStatus: true });
|
|
2042
2128
|
return false;
|
|
@@ -2067,7 +2153,7 @@ async function runAndroid(options = {}) {
|
|
|
2067
2153
|
ceilingMs
|
|
2068
2154
|
});
|
|
2069
2155
|
} catch (err) {
|
|
2070
|
-
const refusal = claimFailure(err, "stim android");
|
|
2156
|
+
const refusal = (0, ownership_claim_exports.claimFailure)(err, "stim android");
|
|
2071
2157
|
if (refusal) {
|
|
2072
2158
|
phaseFailure = fail(refusal.code, refusal.message, refusal.remedy, { lastBuildStatus: true });
|
|
2073
2159
|
return false;
|
|
@@ -2149,7 +2235,7 @@ async function runAndroid(options = {}) {
|
|
|
2149
2235
|
out
|
|
2150
2236
|
});
|
|
2151
2237
|
} catch (err) {
|
|
2152
|
-
const refusal = claimFailure(err, "stim android");
|
|
2238
|
+
const refusal = (0, ownership_claim_exports.claimFailure)(err, "stim android");
|
|
2153
2239
|
if (refusal) {
|
|
2154
2240
|
phaseFailure = fail(refusal.code, refusal.message, refusal.remedy, { lastBuildStatus: true });
|
|
2155
2241
|
return false;
|
|
@@ -2206,19 +2292,19 @@ async function runAndroid(options = {}) {
|
|
|
2206
2292
|
abi: buildAbi
|
|
2207
2293
|
}, {
|
|
2208
2294
|
estimateMs: estimates().coldBuildMs,
|
|
2209
|
-
ccache:
|
|
2295
|
+
ccache: buildPlan.compilerCache === "ccache" ? ccacheFor({
|
|
2210
2296
|
root,
|
|
2211
2297
|
onNote: out
|
|
2212
2298
|
}) : null,
|
|
2213
2299
|
cas,
|
|
2214
|
-
buildCache:
|
|
2215
|
-
pch:
|
|
2216
|
-
compilerCacheDisabled:
|
|
2300
|
+
buildCache: buildPlan.gradleBuildCache,
|
|
2301
|
+
pch: buildPlan.pch,
|
|
2302
|
+
compilerCacheDisabled: buildPlan.compilerCache === "none"
|
|
2217
2303
|
});
|
|
2218
2304
|
ccacheActivity = built.ccache ?? CCACHE_UNAVAILABLE;
|
|
2219
2305
|
phase("cache", `compilation cache ${ccacheActivityLine(ccacheActivity)}`);
|
|
2220
|
-
if (built.
|
|
2221
|
-
const diagnostics = built.diagnostics
|
|
2306
|
+
if (!built.ok) {
|
|
2307
|
+
const diagnostics = built.diagnostics;
|
|
2222
2308
|
for (const diag of diagnostics) writer.write({
|
|
2223
2309
|
src: "build",
|
|
2224
2310
|
level: "error",
|
|
@@ -2227,7 +2313,7 @@ async function runAndroid(options = {}) {
|
|
|
2227
2313
|
});
|
|
2228
2314
|
phase("build", chalk.red(`FAILED after ${formatDuration(built.durationMs)}`));
|
|
2229
2315
|
const extracted = diagnostics.map(formatDiagnostic);
|
|
2230
|
-
if (
|
|
2316
|
+
if (built.truncated > 0) extracted.push(`... and ${built.truncated} more diagnostic(s) in the log`);
|
|
2231
2317
|
phaseFailure = fail(built.code, built.reason, diagnostics.find((d) => d.remedy)?.remedy || built.remedy || null, {
|
|
2232
2318
|
lastBuildStatus: true,
|
|
2233
2319
|
diagnostics: extracted,
|
|
@@ -2236,8 +2322,8 @@ async function runAndroid(options = {}) {
|
|
|
2236
2322
|
});
|
|
2237
2323
|
return false;
|
|
2238
2324
|
}
|
|
2239
|
-
apkPath = built.apkPath
|
|
2240
|
-
stats.setBuildMs(built.durationMs
|
|
2325
|
+
apkPath = built.apkPath;
|
|
2326
|
+
stats.setBuildMs(built.durationMs);
|
|
2241
2327
|
phase("build", `ok (${formatDuration(built.durationMs)})`);
|
|
2242
2328
|
if (built.apkNote) phase("build", chalk.yellow(built.apkNote));
|
|
2243
2329
|
const beforeBuildHash = storeHash;
|
|
@@ -2329,8 +2415,8 @@ async function runAndroid(options = {}) {
|
|
|
2329
2415
|
id: device.serial,
|
|
2330
2416
|
deviceName: device.deviceName ?? null,
|
|
2331
2417
|
idLabel: "serial",
|
|
2332
|
-
waitSeconds,
|
|
2333
|
-
noWait,
|
|
2418
|
+
waitSeconds: target.lease.waitSeconds,
|
|
2419
|
+
noWait: target.lease.noWait,
|
|
2334
2420
|
installBoundMs: ADB_INSTALL_TIMEOUT_MS,
|
|
2335
2421
|
appId: androidPackage,
|
|
2336
2422
|
holderAppId: (holder) => getProject(holder)?.androidPackage ?? null,
|