stim 1.21.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -7
- package/dist/{acquire-artifact-CD4lbiWE.mjs → acquire-artifact-Co2k4f7O.mjs} +21 -3
- package/dist/{act-DHAw2A2S.mjs → act-DsuqEkiM.mjs} +298 -164
- package/dist/{activity-BzVfHSrY.mjs → activity-CMLmzp7o.mjs} +33 -12
- package/dist/{agent-device-usage-output-zh1vhbLp.mjs → agent-device-usage-output-DUFaTMdd.mjs} +7 -7
- package/dist/{android-BLgbNqox.mjs → android-ByRMUoiJ.mjs} +66 -52
- package/dist/{android-DUYkNF4u.mjs → android-C7sVmyI9.mjs} +160 -59
- package/dist/{android-CV_GCELZ.mjs → android-DGkNqa_c.mjs} +5 -5
- package/dist/{android-BEJ8Jpl7.mjs → android-DR5lZ2Az.mjs} +2 -2
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{android-cas-Ct5b1xCK.mjs → android-cas-ngferVq2.mjs} +3 -3
- package/dist/{client-B7QVOlCr.d.mts → android-project-DVWyCbWU.d.mts} +145 -7
- package/dist/api.d.mts +132 -118
- package/dist/api.mjs +239 -42
- package/dist/{artifact-B8T3S5gi.mjs → artifact-8EY8SAPw.mjs} +40 -35
- package/dist/{artifact-DAuZ-FNU.mjs → artifact-DJPy518Y.mjs} +69 -40
- package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
- package/dist/{browser-web-QQzVjz3O.mjs → browser-web-Bcv99PBM.mjs} +187 -59
- package/dist/{budget-Bs6SxxzO.mjs → budget-Cvwn54qV.mjs} +830 -699
- package/dist/{build-CoPzQRNw.mjs → build-CabC3G23.mjs} +34 -27
- package/dist/{build-cache-DmyR9Zzc.mjs → build-cache-Dv7RN200.mjs} +4 -4
- package/dist/{build-plan-CaFskB7_.mjs → build-plan-DUC8Ka9y.mjs} +74 -14
- package/dist/{cache-manifest-DkkqguoK.mjs → cache-manifest-DSeQjt-Q.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-BJRZ9pG3.mjs → ccache-Btwc36-I.mjs} +6 -6
- package/dist/{cdp-CWmIUMbw.mjs → cdp-3fwICjzi.mjs} +1 -1
- package/dist/{chrome-B6tfCta1.mjs → chrome-Bbw689-6.mjs} +1 -1
- package/dist/{cli-0DYf8QhQ.mjs → cli-CHZa9Lvk.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-UXD70ZbM.mjs → client-OyRoEuSr.mjs} +218 -47
- package/dist/collector-run.d.mts +1 -1
- package/dist/collector-run.mjs +6 -6
- package/dist/{command-output-B1UrjZHL.mjs → command-output-gwpm28fu.mjs} +1 -1
- package/dist/{config-CYcBF478.mjs → config-DlrsduwG.mjs} +17 -11
- package/dist/{created-devices-CqeBlrEn.mjs → created-devices-x9rN6bhs.mjs} +13 -3
- package/dist/{dependency-state-BbKQW83h.mjs → dependency-state-1I9KZT1Y.mjs} +2 -2
- package/dist/{detached-entry-DFRyG1_o.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
- package/dist/{dev-client-UOeESKm6.mjs → dev-client-BSDR5h3F.mjs} +2 -2
- package/dist/{device-ExJq8Ei7.mjs → device-B-L3Fbxy.mjs} +71 -14
- package/dist/{device-DCxH7_By.mjs → device-DklWZLqb.mjs} +16 -16
- package/dist/{device-capacity-CMlqEcvw.mjs → device-capacity-DK5_EwRS.mjs} +9 -10
- package/dist/device-host-worker.mjs +25 -32
- package/dist/{device-ios-DRUeKaFV.mjs → device-ios-DoB6KFCO.mjs} +39 -16
- package/dist/{device-lease-run-C8raGFoP.mjs → device-lease-run-xJPQ_QQG.mjs} +5 -5
- package/dist/{device-pool-DMRpVX9a.mjs → device-pool-BMkdsefq.mjs} +3 -3
- package/dist/{doctor-DTvaDOda.mjs → doctor-Bo7BXLux.mjs} +24 -37
- package/dist/{doctor-Dhqebm0q.mjs → doctor-D5_EzwfA.mjs} +19 -16
- package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-BLHCYxzi.mjs → doctor-thjWAV0z.mjs} +1 -1
- package/dist/{doctor-watchman-Cv1F10Kj.mjs → doctor-watchman-N2wDotwQ.mjs} +5 -5
- package/dist/{eas-build-BomfRnFT.mjs → eas-build-CwknaQYj.mjs} +4 -4
- package/dist/{eas-fallback-DJwZpy0c.mjs → eas-fallback-CSgAulr5.mjs} +27 -18
- package/dist/{eas-session-ledger-op6A54yi.mjs → eas-session-ledger-DlY_serQ.mjs} +8 -7
- package/dist/{error-diagnostics-Bf0rZvG9.mjs → error-diagnostics-DBWO2rxE.mjs} +10 -10
- package/dist/{exec-_UbtCQcG.mjs → exec-DEoAhcze.mjs} +155 -47
- package/dist/{exec-H20xSg2T.d.mts → exec-DnYc4HGH.d.mts} +17 -4
- package/dist/{gc-_-dCXdyL.mjs → gc-CXxN-4SE.mjs} +587 -313
- package/dist/gc-DnNDQyaP.mjs +3 -0
- package/dist/{guide-Yqwt2bd6.mjs → guide-Br0LEfKy.mjs} +239 -43
- package/dist/{hosted-android-Bw-honsd.mjs → hosted-android-B-9f-jkd.mjs} +6 -6
- package/dist/{hosted-client-DB_gBPfY.mjs → hosted-client-DZAPrcro.mjs} +4 -4
- package/dist/{hosted-ios-CUvOf4Vr.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
- package/dist/{hosted-logs-DL_P5AdN.mjs → hosted-logs-FIRx9X2f.mjs} +5 -5
- package/dist/{hosted-macos-QI141yKk.mjs → hosted-macos-_awYSpfv.mjs} +21 -12
- package/dist/{hosted-native-Ksyjgzq-.mjs → hosted-native-BdzE668-.mjs} +27 -14
- package/dist/{idle-BVeRGroT.d.mts → idle-C4cZ757K.d.mts} +3 -3
- package/dist/{idle-shutdown-DaKmZi0z.mjs → idle-shutdown-DDg3SdvY.mjs} +7 -7
- package/dist/ios-CDvlmUs7.d.mts +24 -0
- package/dist/{ios-CQ68hG9s.mjs → ios-Ds1clbIt.mjs} +8 -8
- package/dist/{ios-device-CwFMehUS.mjs → ios-device--h_-8ENa.mjs} +3 -3
- package/dist/{ios-device-CXGP1bsD.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
- package/dist/{ios-CpByZy12.mjs → ios-hcBpnEGk.mjs} +81 -34
- package/dist/{ios-ubFsBzwq.mjs → ios-pm4nL6By.mjs} +59 -50
- package/dist/{ios-project-WuwwBdvW.mjs → ios-project-CZhKODF3.mjs} +5 -5
- package/dist/{ios-signing-DTTIChGs.mjs → ios-signing-BtAffm0A.mjs} +2 -2
- package/dist/{ios-state-DvFX-K_l.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
- package/dist/{ios-qNJt4dFm.mjs → ios-xtlRHaeB.mjs} +1 -1
- package/dist/{js-swap-Cc1dttps.mjs → js-swap-Bwhh4S7V.mjs} +7 -29
- package/dist/{launch-Zq2mOSDy.mjs → launch-BjxemNpK.mjs} +40 -39
- package/dist/{launch-CD1yVc7U.mjs → launch-CCzXlc8r.mjs} +16 -16
- package/dist/{logs-BS00Anxf.mjs → logs-BfwwadsZ.mjs} +151 -24
- package/dist/{logs-CMm05HxN.mjs → logs-jTS_lHSo.mjs} +10 -17
- package/dist/{macos-B65--pPd.mjs → macos-DVlSSyUg.mjs} +1 -1
- package/dist/{macos-C-0qJ6zq.mjs → macos-NfV2D7dO.mjs} +143 -46
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +8 -8
- package/dist/{metro-DEXpIhHC.mjs → metro-DiXtA3Ty.mjs} +59 -37
- package/dist/{metro-gateway-BMJNlj3E.mjs → metro-gateway-CKZqKqx7.mjs} +120 -22
- package/dist/{named-ports-BWTzt6mu.mjs → named-ports-DkEzOfzO.mjs} +40 -33
- package/dist/{native-android-JACyjTZs.mjs → native-android-CqgnOgsT.mjs} +43 -242
- package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
- package/dist/{native-gradle-inputs-Bep9JcSF.mjs → native-gradle-inputs-Dnh84Zbd.mjs} +3 -129
- package/dist/{native-run-DY_RLx3C.mjs → native-run-NwUuxbkg.mjs} +4 -5
- package/dist/{native-runtime-Dg1Q7tfF.mjs → native-runtime-B7KIafpM.mjs} +8 -7
- package/dist/native-source-Y0yLhFyQ.mjs +133 -0
- package/dist/{native-xcode-inputs-CB2iQeWq.mjs → native-xcode-inputs-D_VOfFL7.mjs} +2 -3
- package/dist/{native-xcode-ios-CXX39F7o.mjs → native-xcode-ios-BYDOHWLN.mjs} +27 -32
- package/dist/offload-worker.d.mts +65 -2
- package/dist/offload-worker.mjs +305 -73
- package/dist/operation-exec-BW0em61G.mjs +171 -0
- package/dist/{ownership-DEmM5vhh.mjs → ownership-C5fo5Edb.mjs} +3 -3
- package/dist/{page-CPaHeYqj.mjs → page-DBL2PiUU.mjs} +8 -4
- package/dist/{placement-log-BqGbTa61.mjs → placement-log-BnGgJRRZ.mjs} +1 -1
- package/dist/{plan-placement-Bwj-IjY1.mjs → plan-placement-DIsMtN-d.mjs} +12 -8
- package/dist/{ports-D-MmCTdv.mjs → ports-Cy1RkmuQ.mjs} +3 -3
- package/dist/{prebuild-uD_ipCxF.mjs → prebuild-D4JoEAEs.mjs} +49 -14
- package/dist/{project-BZNjmW_8.mjs → project-wM_XFTvE.mjs} +16 -16
- package/dist/{pull-request-Lfetn8Kr.mjs → pull-request-W1IuLXDt.mjs} +102 -20
- package/dist/{pull-request-zjCSAryH.d.mts → pull-request-eODyIqZF.d.mts} +6 -2
- package/dist/pull-requests.d.mts +2 -2
- package/dist/pull-requests.mjs +2 -2
- package/dist/{react-native-android-DuzH0cn3.mjs → react-native-android-6OZ7MSM7.mjs} +71 -48
- package/dist/{react-native-build-rhk4smwQ.mjs → react-native-build-Dvd8hC21.mjs} +8 -8
- package/dist/{react-native-doctor-CQpuIMso.mjs → react-native-doctor-DsoSF1Y9.mjs} +7 -7
- package/dist/{react-native-ios-Bhq1rJeV.mjs → react-native-ios-4u1Rn-GR.mjs} +40 -26
- package/dist/{recordings-DYteQSu4.mjs → recordings-CQmfzAh7.mjs} +1 -1
- package/dist/registration-BcRgF6Ox.mjs +51 -0
- package/dist/{reload-CmTRFJaX.mjs → reload-BzkYabB-.mjs} +16 -15
- package/dist/{reload-DzjSl5P_.mjs → reload-D7AVlb8N.mjs} +1 -1
- package/dist/{remote-ByYkXdGD.mjs → remote-DjGDmlTZ.mjs} +18 -15
- package/dist/{result-DNiS-tTP.mjs → result-D2Ykz_iD.mjs} +24 -23
- package/dist/{run-D23HmJMs.mjs → run-DidHghD1.mjs} +3 -2
- package/dist/{selection-CSl9i5qU.mjs → selection-DSMbWEX2.mjs} +6 -5
- package/dist/{server-bare-CxTrvDg8.mjs → server-bare-CafzuyFB.mjs} +2 -2
- package/dist/{server-command-CtzloH3v.mjs → server-command-C6QjeupS.mjs} +5 -5
- package/dist/{server-expo-DT_F_uVI.mjs → server-expo-CrjB29pq.mjs} +7 -5
- package/dist/server-expo-D58c9L0M.mjs +2 -0
- package/dist/{settings-CsJDEXgK.mjs → settings-C7O8A6ZI.mjs} +223 -243
- package/dist/{settings-T1gtc3bf.mjs → settings-DpR-1Wnn.mjs} +1 -1
- package/dist/{settings-write-HyVZ8eQ8.mjs → settings-write-CzD60rOD.mjs} +7 -6
- package/dist/settings.schema.json +13 -0
- package/dist/{simslim-Cgk17SXV.mjs → simslim-BNckWpXi.mjs} +2 -2
- package/dist/{slot-launch-DF8VfT64.mjs → slot-launch-CbfmNgM6.mjs} +6 -6
- package/dist/{stage-BIS0ydsV.mjs → stage-Bps5oius.mjs} +21 -4
- package/dist/{start-RChynRDp.mjs → start-Br-oxqMD.mjs} +1 -1
- package/dist/{start-7lpH7hmN.mjs → start-EojN4WFz.mjs} +622 -393
- package/dist/{state-C4ZtUisW.mjs → state--smjFSTL.mjs} +22 -7
- package/dist/{state-XMziexv2.mjs → state-08I3hw3_.mjs} +2 -2
- package/dist/{stats-53T7OTb9.mjs → stats-D3GerlFW.mjs} +5 -5
- package/dist/{stats-report-BFfMpWWF.mjs → stats-report-BzaPrRm6.mjs} +1 -1
- package/dist/{status-DqEUSSxs.mjs → status-BRROykC8.mjs} +2 -2
- package/dist/{status-CSi6tlRq.mjs → status-EvrK72L2.mjs} +1 -1
- package/dist/{status-BL7jVyAB.mjs → status-WBDajew2.mjs} +43 -29
- package/dist/{status-watch-GDCfqpTE.mjs → status-watch-Bg_u-pwR.mjs} +48 -16
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-C12we7lz.mjs → stim-desktop-D5OGpYZM.mjs} +2 -2
- package/dist/{stop-Bk_1qiV6.mjs → stop-DTZ9uTw3.mjs} +2 -2
- package/dist/{stop-D7h6jAXQ.mjs → stop-Dky10AEJ.mjs} +31 -22
- package/dist/{stop-CPzlM1L-.mjs → stop-Mv6W9FAk.mjs} +15 -16
- package/dist/supervisor-run.d.mts +3 -3
- package/dist/supervisor-run.mjs +28 -36
- package/dist/{support-Dlu37g6H.mjs → support-CNioewsd.mjs} +10 -10
- package/dist/{support-67vraa1Q.mjs → support-yUiOjnVY.mjs} +8 -8
- package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
- package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
- package/dist/toolchain-BY8X8HXx.mjs +2 -0
- package/dist/{toolchain-Hp9sCpK4.mjs → toolchain-DpJMHq0n.mjs} +9 -6
- package/dist/{trigger-BAahxUPq.mjs → trigger-Cbyc41d_.mjs} +3 -3
- package/dist/trigger-yb_nFzPF.mjs +2 -0
- package/dist/{warm-progress-BHX5r0Ei.mjs → warm-progress-CA3TgT3-.mjs} +29 -16
- package/dist/web-CZ07gd77.mjs +2 -0
- package/dist/{web-CJmIj6AI.mjs → web-DKx6yoFA.mjs} +11 -10
- package/dist/web-run.mjs +11 -9
- package/dist/windows-report.mjs +1 -1
- package/dist/{workspace-state-Cjuigeeu.mjs → workspace-state-U08dEzhG.mjs} +3 -3
- package/dist/{workspaces-BccMFmGQ.mjs → workspaces-CpANmBlq.mjs} +594 -266
- package/dist/{worktree-DQ6Zi2Mv.mjs → worktree-CHecZ4Oq.mjs} +850 -551
- package/dist/worktree-ZqZVjD9K.mjs +2 -0
- package/dist/{xcode-Zlx3qjEs.mjs → xcode-BXn9-xYx.mjs} +5 -5
- package/package.json +7 -7
- package/shim/android-audio/Main.java +24 -0
- package/shim/android-audio/README.md +17 -0
- package/shim/android-audio.jar +0 -0
- package/dist/gc-C-WwL0yi.mjs +0 -3
- package/dist/git-C3iTsJaZ.mjs +0 -73
- package/dist/server-expo-C-90EhcG.mjs +0 -2
- package/dist/settings-DkdmlelE.d.mts +0 -15
- package/dist/swiftpm-macos-p8WZbxKU.mjs +0 -130
- package/dist/toolchain-DhKwp9iI.mjs +0 -2
- package/dist/trigger-Bf3uDcpv.mjs +0 -2
- package/dist/web-DknQETPs.mjs +0 -2
- package/dist/workspace-process-lock-1_1OoVW5.mjs +0 -57
- package/dist/worktree-CK2MpJW5.mjs +0 -2
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
1
|
+
import { t as getExecutor } from "./exec-DEoAhcze.mjs";
|
|
2
2
|
import { d as workspaceDir, i as sharedBuildCache } from "./paths-DQtTgsBf.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { r as register } from "./cache-manifest-
|
|
6
|
-
import { Y as statsProjectKey } from "./budget-
|
|
7
|
-
import { d as runCancellationSignal } from "./native-run-
|
|
8
|
-
import { h as resolveBuild,
|
|
9
|
-
import {
|
|
10
|
-
import { o as resolveCcache } from "./ccache-
|
|
11
|
-
import { r as androidToolchainAsync } from "./toolchain-
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { n as
|
|
18
|
-
import { n as
|
|
3
|
+
import { H as deviceSlotPlatforms, p as getProject, q as validateDeviceSlot } from "./config-DlrsduwG.mjs";
|
|
4
|
+
import { tt as settingValueAt } from "./settings-C7O8A6ZI.mjs";
|
|
5
|
+
import { r as register } from "./cache-manifest-DSeQjt-Q.mjs";
|
|
6
|
+
import { Y as statsProjectKey } from "./budget-Cvwn54qV.mjs";
|
|
7
|
+
import { d as runCancellationSignal } from "./native-run-NwUuxbkg.mjs";
|
|
8
|
+
import { h as resolveBuild, o as entryDir, t as artifactIn } from "./build-cache-Dv7RN200.mjs";
|
|
9
|
+
import { B as ownedAvdDeviceProfile, E as findBuildTool, I as listInstalledSystemImages, K as ownedAvdSystemImage, V as ownedAvdDirectory, X as pickDefaultSystemImage, l as androidSystemImageAbi, o as androidHome } from "./android-C7sVmyI9.mjs";
|
|
10
|
+
import { o as resolveCcache } from "./ccache-Btwc36-I.mjs";
|
|
11
|
+
import { r as androidToolchainAsync } from "./toolchain-DpJMHq0n.mjs";
|
|
12
|
+
import { a as nativeGradleTransfer, t as gradleOffloadInputs } from "./native-gradle-inputs-Dnh84Zbd.mjs";
|
|
13
|
+
import { d as buildGradle, l as androidSdkRefusal } from "./react-native-build-Dvd8hC21.mjs";
|
|
14
|
+
import { l as skippedMissReason, o as explainBuildMiss } from "./prebuild-D4JoEAEs.mjs";
|
|
15
|
+
import { c as resolveAndroidRunPlan } from "./result-D2Ykz_iD.mjs";
|
|
16
|
+
import { n as androidProcessRuntime } from "./launch-CCzXlc8r.mjs";
|
|
17
|
+
import { n as planFlagRefusal, r as planPayload } from "./build-plan-DUC8Ka9y.mjs";
|
|
18
|
+
import { a as nativeGradleWorkerArtifactIdentity, n as gradleArtifactInputs, r as nativeGradleArtifactSnapshot, t as NATIVE_GRADLE_CACHE_LIMIT } from "./native-gradle-artifact-inputs-DHFnmrVf.mjs";
|
|
19
19
|
import { createHash } from "node:crypto";
|
|
20
20
|
import { createReadStream, createWriteStream, existsSync, readFileSync, statSync } from "node:fs";
|
|
21
|
-
import {
|
|
22
|
-
import { basename, dirname, isAbsolute, join, relative,
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
import { basename, dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
23
23
|
import { storeArtifactAsync } from "@stim-cli/core";
|
|
24
24
|
import { fileURLToPath } from "node:url";
|
|
25
|
-
import { mkdtemp, open, readFile,
|
|
25
|
+
import { mkdtemp, open, readFile, realpath, rm, stat, writeFile } from "node:fs/promises";
|
|
26
26
|
import { pipeline } from "node:stream/promises";
|
|
27
27
|
import { Readable } from "node:stream";
|
|
28
28
|
//#region src/integrations/native-android-cache.ts
|
|
@@ -246,218 +246,6 @@ function nativeAndroidFileCache(files, sdk, abi, operation) {
|
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
248
|
//#endregion
|
|
249
|
-
//#region src/integrations/native-gradle-artifact-inputs.ts
|
|
250
|
-
const NATIVE_GRADLE_CACHE_LIMIT = "Native APK caching requires android.artifactInputs with complete: true and a complete declaration of repeatable pinned inputs. Gradle incremental and task-cache reuse remain available without it.";
|
|
251
|
-
function gradleArtifactInputs(value) {
|
|
252
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(NATIVE_GRADLE_CACHE_LIMIT);
|
|
253
|
-
const localFiles = "localFiles" in value ? value.localFiles : [];
|
|
254
|
-
const environment = "environment" in value ? value.environment : [];
|
|
255
|
-
if (Object.keys(value).some((key) => ![
|
|
256
|
-
"complete",
|
|
257
|
-
"ignored",
|
|
258
|
-
"outputs",
|
|
259
|
-
"localFiles",
|
|
260
|
-
"environment"
|
|
261
|
-
].includes(key)) || !Array.isArray(localFiles) || !localFiles.every((path) => typeof path === "string" && path.length > 0 && !path.includes("\0")) || !Array.isArray(environment) || !environment.every((name) => typeof name === "string" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(name))) throw new Error(NATIVE_GRADLE_CACHE_LIMIT);
|
|
262
|
-
let inventory;
|
|
263
|
-
try {
|
|
264
|
-
inventory = gradleOffloadInputs({
|
|
265
|
-
complete: "complete" in value ? value.complete : void 0,
|
|
266
|
-
ignored: "ignored" in value ? value.ignored : void 0,
|
|
267
|
-
outputs: "outputs" in value ? value.outputs : void 0
|
|
268
|
-
});
|
|
269
|
-
} catch (error) {
|
|
270
|
-
throw new Error(String(error).replaceAll("android.offloadInputs", "android.artifactInputs"), { cause: error });
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
...inventory,
|
|
274
|
-
localFiles: [...new Set(localFiles)].toSorted(),
|
|
275
|
-
environment: [...new Set(environment)].toSorted()
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
async function optionalText(path, signal, encoding = "utf8") {
|
|
279
|
-
try {
|
|
280
|
-
return await readFile(path, {
|
|
281
|
-
encoding,
|
|
282
|
-
signal
|
|
283
|
-
});
|
|
284
|
-
} catch (error) {
|
|
285
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
286
|
-
throw error;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
async function javaRelease(env, signal) {
|
|
290
|
-
let home = env.JAVA_HOME;
|
|
291
|
-
if (!home) {
|
|
292
|
-
const java = getExecutor().findExecutable("java");
|
|
293
|
-
if (java) {
|
|
294
|
-
const selected = dirname(dirname(await realpath(java)));
|
|
295
|
-
if ((await optionalText(join(selected, "release"), signal))?.includes("JAVA_VERSION=")) home = selected;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (!home && process.platform === "darwin") {
|
|
299
|
-
const child = childEnvironment(env);
|
|
300
|
-
home = (await getExecutor().runFileAsync("/usr/libexec/java_home", [], {
|
|
301
|
-
timeoutMs: 1e4,
|
|
302
|
-
signal,
|
|
303
|
-
...child
|
|
304
|
-
})).trim();
|
|
305
|
-
}
|
|
306
|
-
if (!home || !(await optionalText(join(home, "release"), signal))?.includes("JAVA_VERSION=")) throw new Error("The Gradle wrapper JDK release identity is unavailable.");
|
|
307
|
-
return join(home, "release");
|
|
308
|
-
}
|
|
309
|
-
async function localPropertiesIdentity(properties, sdk, root, signal) {
|
|
310
|
-
const content = await optionalText(properties, signal, "latin1");
|
|
311
|
-
if (content === null) return null;
|
|
312
|
-
const retained = [];
|
|
313
|
-
let selected = null;
|
|
314
|
-
for (const [, line = "", ending = ""] of content.matchAll(/([^\r\n]*)(\r\n|\r|\n|$)/g)) {
|
|
315
|
-
if (/^[ \t\f]*$/.test(line) || /^[ \t\f]*[#!]/.test(line)) {
|
|
316
|
-
retained.push(line + ending);
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
if ((line.match(/\\+$/)?.[0].length ?? 0) % 2 !== 0) throw new Error("Native APK caching requires single-line local.properties values.");
|
|
320
|
-
const entry = /^[ \t\f]*([A-Za-z0-9_.-]+)(?:[ \t\f]*[:=][ \t\f]*|[ \t\f]+)(.*)$/.exec(line);
|
|
321
|
-
if (!entry) {
|
|
322
|
-
if (/^[ \t\f]*[A-Za-z0-9_.-]+[ \t\f]*$/.test(line) && line.trim() !== "sdk.dir") {
|
|
323
|
-
retained.push(line + ending);
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
throw new Error("Native APK caching requires plain, unescaped local.properties keys.");
|
|
327
|
-
}
|
|
328
|
-
if (entry[1] !== "sdk.dir") {
|
|
329
|
-
retained.push(line + ending);
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
const value = entry[2] ?? "";
|
|
333
|
-
if (!value || [...value].some((character) => character.charCodeAt(0) > 127)) throw new Error("Native APK caching cannot resolve the local.properties SDK.");
|
|
334
|
-
selected = value.replace(/\\u([a-fA-F\d]{4})|\\(.)/g, (full, hex, escaped) => {
|
|
335
|
-
if (hex) return String.fromCharCode(parseInt(hex, 16));
|
|
336
|
-
if (escaped === "u") throw new Error("Native APK caching cannot resolve the local.properties SDK.");
|
|
337
|
-
if (escaped === "t") return " ";
|
|
338
|
-
if (escaped === "r") return "\r";
|
|
339
|
-
if (escaped === "n") return "\n";
|
|
340
|
-
if (escaped === "f") return "\f";
|
|
341
|
-
return escaped ?? full;
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
if (selected !== null && await realpath(resolve(root, selected)) !== sdk) throw new Error("Native APK caching requires the local.properties SDK to match ANDROID_HOME.");
|
|
345
|
-
return retained.join("");
|
|
346
|
-
}
|
|
347
|
-
async function nativeGradleArtifactSnapshot(root, value, build, abi, env, signal) {
|
|
348
|
-
signal?.throwIfAborted();
|
|
349
|
-
const declaration = gradleArtifactInputs(value);
|
|
350
|
-
const localFiles = declaration.localFiles.map((file) => resolve(root, file));
|
|
351
|
-
for (const path of localFiles) {
|
|
352
|
-
const info = await stat(path).catch((error) => {
|
|
353
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
354
|
-
throw error;
|
|
355
|
-
});
|
|
356
|
-
if (info && !info.isFile()) throw new Error("android.artifactInputs.localFiles must name exact regular files.");
|
|
357
|
-
}
|
|
358
|
-
const { complete, ignored, outputs } = declaration;
|
|
359
|
-
const properties = join(root, "local.properties");
|
|
360
|
-
const source = await nativeGradleLocalSourceDigest(root, {
|
|
361
|
-
complete,
|
|
362
|
-
ignored,
|
|
363
|
-
outputs
|
|
364
|
-
}, [properties, ...localFiles], signal);
|
|
365
|
-
const sdkDirectory = await realpath(androidHome(env));
|
|
366
|
-
const home = env.HOME ?? env.USERPROFILE ?? homedir();
|
|
367
|
-
const gradleHome = env.GRADLE_USER_HOME ?? join(home, ".gradle");
|
|
368
|
-
const inputs = [{
|
|
369
|
-
name: "jdk-release",
|
|
370
|
-
path: await javaRelease(env, signal),
|
|
371
|
-
optional: false
|
|
372
|
-
}, ...[
|
|
373
|
-
"gradle.properties",
|
|
374
|
-
"init.gradle",
|
|
375
|
-
"init.gradle.kts",
|
|
376
|
-
"init.d"
|
|
377
|
-
].map((name) => ({
|
|
378
|
-
name: `gradle-user/${name}`,
|
|
379
|
-
path: join(gradleHome, name),
|
|
380
|
-
optional: true
|
|
381
|
-
}))];
|
|
382
|
-
for (const group of [
|
|
383
|
-
"build-tools",
|
|
384
|
-
"platforms",
|
|
385
|
-
"ndk",
|
|
386
|
-
"cmake"
|
|
387
|
-
]) {
|
|
388
|
-
const directory = join(sdkDirectory, group);
|
|
389
|
-
const versions = await readdir(directory).catch((error) => {
|
|
390
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
|
|
391
|
-
throw error;
|
|
392
|
-
});
|
|
393
|
-
for (const version of versions.toSorted()) {
|
|
394
|
-
if (!(await stat(join(directory, version))).isDirectory()) continue;
|
|
395
|
-
const path = join(directory, version, "source.properties");
|
|
396
|
-
if (await optionalText(path, signal) !== null) inputs.push({
|
|
397
|
-
name: `sdk/${group}/${version}`,
|
|
398
|
-
path,
|
|
399
|
-
optional: false
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (!inputs.some((input) => input.name.startsWith("sdk/build-tools/"))) throw new Error("Android SDK build-tools version metadata is unavailable.");
|
|
404
|
-
const preferences = [
|
|
405
|
-
join(home, ".android"),
|
|
406
|
-
...env.ANDROID_USER_HOME ? [env.ANDROID_USER_HOME] : [],
|
|
407
|
-
...[
|
|
408
|
-
"ANDROID_PREFS_ROOT",
|
|
409
|
-
"ANDROID_SDK_HOME",
|
|
410
|
-
"TEST_TMPDIR"
|
|
411
|
-
].flatMap((name) => env[name] ? [join(env[name], ".android")] : [])
|
|
412
|
-
];
|
|
413
|
-
for (const [index, directory] of [...new Set(preferences)].entries()) inputs.push({
|
|
414
|
-
name: `debug-keystore/${index}`,
|
|
415
|
-
path: join(directory, "debug.keystore"),
|
|
416
|
-
optional: true
|
|
417
|
-
});
|
|
418
|
-
for (const [index, path] of localFiles.entries()) inputs.push({
|
|
419
|
-
name: `local/${index}`,
|
|
420
|
-
path,
|
|
421
|
-
optional: true
|
|
422
|
-
});
|
|
423
|
-
const environment = Object.fromEntries([.../* @__PURE__ */ new Set([
|
|
424
|
-
...declaration.environment,
|
|
425
|
-
"JAVA_OPTS",
|
|
426
|
-
"JAVA_TOOL_OPTIONS",
|
|
427
|
-
"_JAVA_OPTIONS",
|
|
428
|
-
"GRADLE_OPTS"
|
|
429
|
-
])].toSorted().map((name) => [name, env[name] ?? null]));
|
|
430
|
-
const localProperties = await localPropertiesIdentity(properties, sdkDirectory, root, signal);
|
|
431
|
-
const local = await fingerprintNativeInputs(inputs, {
|
|
432
|
-
parameters: {
|
|
433
|
-
declaration,
|
|
434
|
-
environment,
|
|
435
|
-
localProperties: createHash("sha256").update(JSON.stringify(localProperties)).digest("hex")
|
|
436
|
-
},
|
|
437
|
-
signal
|
|
438
|
-
});
|
|
439
|
-
const hash = createHash("sha256").update("stim-native-gradle-artifact-v1\0").update(JSON.stringify({
|
|
440
|
-
source,
|
|
441
|
-
local: local.hash,
|
|
442
|
-
platform: process.platform,
|
|
443
|
-
arch: process.arch,
|
|
444
|
-
variant: build.variant ?? "debug",
|
|
445
|
-
compilerCache: build.compilerCache,
|
|
446
|
-
gradleBuildCache: build.gradleBuildCache,
|
|
447
|
-
pch: build.pch,
|
|
448
|
-
cas: build.cas,
|
|
449
|
-
abi
|
|
450
|
-
})).digest("hex");
|
|
451
|
-
return {
|
|
452
|
-
hash,
|
|
453
|
-
key: buildCacheKey("android", hash, {
|
|
454
|
-
variant: build.variant ?? "debug",
|
|
455
|
-
...abi ? { abi } : {}
|
|
456
|
-
}),
|
|
457
|
-
sdkDirectory
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
//#endregion
|
|
461
249
|
//#region src/integrations/native-android-plan.ts
|
|
462
250
|
async function planNativeAndroid(root, options, resolved, operation) {
|
|
463
251
|
if (options.easProfile !== void 0) return { refusal: planFlagRefusal("--eas-profile") };
|
|
@@ -467,10 +255,11 @@ async function planNativeAndroid(root, options, resolved, operation) {
|
|
|
467
255
|
const { env, signal } = operation;
|
|
468
256
|
const declared = settingValueAt(settings, "android.artifactInputs");
|
|
469
257
|
gradleArtifactInputs(declared);
|
|
470
|
-
const planned = resolveAndroidRunPlan({
|
|
258
|
+
const planned = await resolveAndroidRunPlan({
|
|
471
259
|
settings,
|
|
472
260
|
settingsContext: context,
|
|
473
261
|
env,
|
|
262
|
+
signal,
|
|
474
263
|
slot,
|
|
475
264
|
variant: options.variant ?? null,
|
|
476
265
|
systemImage: options.systemImage ?? null,
|
|
@@ -558,7 +347,7 @@ async function planNativeAndroid(root, options, resolved, operation) {
|
|
|
558
347
|
}
|
|
559
348
|
//#endregion
|
|
560
349
|
//#region src/integrations/native-android.ts
|
|
561
|
-
const CACHE_LIMIT = `${NATIVE_GRADLE_CACHE_LIMIT} Offload requires a separate complete android.offloadInputs declaration
|
|
350
|
+
const CACHE_LIMIT = `${NATIVE_GRADLE_CACHE_LIMIT} Offload requires a separate complete android.offloadInputs declaration.`;
|
|
562
351
|
const MODEL_LIMIT = "Native Android requires AGP with androidComponents, one application module and configuration-on-demand disabled. Gradle resolves the exact variant and APK outputs during the build.";
|
|
563
352
|
function refusal(reason) {
|
|
564
353
|
return {
|
|
@@ -625,7 +414,7 @@ function nativeAndroidProject(root) {
|
|
|
625
414
|
prepared: { metroPort: null }
|
|
626
415
|
};
|
|
627
416
|
}),
|
|
628
|
-
artifact: ({ operation,
|
|
417
|
+
artifact: ({ operation, artifactScope, writer, buildPlan, target, out, estimates, settings }) => {
|
|
629
418
|
const variant = buildPlan.variant ?? "debug";
|
|
630
419
|
const inputs = settingValueAt(settings, "android.offloadInputs");
|
|
631
420
|
const artifactInputs = settingValueAt(settings, "android.artifactInputs");
|
|
@@ -634,9 +423,19 @@ function nativeAndroidProject(root) {
|
|
|
634
423
|
let compiledPackage = null;
|
|
635
424
|
let compiledSdk = null;
|
|
636
425
|
const signal = runCancellationSignal(operation) ?? operation?.signal;
|
|
637
|
-
const read = () => {
|
|
426
|
+
const read = async () => {
|
|
638
427
|
if (!operation) throw new Error("Native APK caching requires an operation context.");
|
|
639
|
-
|
|
428
|
+
const identity = await nativeGradleArtifactSnapshot(root, artifactInputs, buildPlan, target.abi, operation.env, signal);
|
|
429
|
+
if (!artifactScope) return identity;
|
|
430
|
+
const scoped = {
|
|
431
|
+
...identity,
|
|
432
|
+
...nativeGradleWorkerArtifactIdentity(identity.hash, artifactScope.key, variant, target.abi)
|
|
433
|
+
};
|
|
434
|
+
artifactScope.record?.({
|
|
435
|
+
hash: scoped.hash,
|
|
436
|
+
key: scoped.key
|
|
437
|
+
}, identity.receipt);
|
|
438
|
+
return scoped;
|
|
640
439
|
};
|
|
641
440
|
let transfer = null;
|
|
642
441
|
const modelFile = join(workspaceDir(root), "gradle-build", `native-apk-${encodeURIComponent(variant)}.json`);
|
|
@@ -647,7 +446,6 @@ function nativeAndroidProject(root) {
|
|
|
647
446
|
return nativeAndroidFileCache(provider.files, snapshot.sdkDirectory, target.abi, operation);
|
|
648
447
|
},
|
|
649
448
|
identity: async () => {
|
|
650
|
-
if (cacheArtifacts === false) return { cacheIneligible: "Native Gradle worker artifacts have no reusable APK identity." };
|
|
651
449
|
try {
|
|
652
450
|
snapshot = await read();
|
|
653
451
|
cacheRefusal = null;
|
|
@@ -708,7 +506,7 @@ function nativeAndroidProject(root) {
|
|
|
708
506
|
diff: null
|
|
709
507
|
}),
|
|
710
508
|
untrackedLine: () => null,
|
|
711
|
-
|
|
509
|
+
expoCache: null,
|
|
712
510
|
offload: {
|
|
713
511
|
supportsUncachedArtifacts: true,
|
|
714
512
|
uncachedArtifacts: true,
|
|
@@ -741,7 +539,8 @@ function nativeAndroidProject(root) {
|
|
|
741
539
|
isExpo: false,
|
|
742
540
|
native: {
|
|
743
541
|
provider: "gradle",
|
|
744
|
-
transfer
|
|
542
|
+
transfer,
|
|
543
|
+
cache: buildPlan.cache
|
|
745
544
|
},
|
|
746
545
|
android: {
|
|
747
546
|
variant,
|
|
@@ -757,7 +556,7 @@ function nativeAndroidProject(root) {
|
|
|
757
556
|
compile: async () => {
|
|
758
557
|
const script = ["../shim/native-android.gradle", "../../shim/native-android.gradle"].map((path) => fileURLToPath(new URL(path, import.meta.url))).find(existsSync);
|
|
759
558
|
if (!script) throw new Error("Stim installation is missing shim/native-android.gradle.");
|
|
760
|
-
|
|
559
|
+
const result = await buildGradle({
|
|
761
560
|
root,
|
|
762
561
|
logWriter: writer,
|
|
763
562
|
variant,
|
|
@@ -796,6 +595,8 @@ function nativeAndroidProject(root) {
|
|
|
796
595
|
pch: buildPlan.pch,
|
|
797
596
|
compilerCacheDisabled: buildPlan.compilerCache === "none"
|
|
798
597
|
});
|
|
598
|
+
if (result.ok) await artifactScope?.validate();
|
|
599
|
+
return result;
|
|
799
600
|
}
|
|
800
601
|
};
|
|
801
602
|
}
|
|
@@ -806,7 +607,7 @@ function nativeAndroidDoctor(root) {
|
|
|
806
607
|
let cache = CACHE_LIMIT;
|
|
807
608
|
try {
|
|
808
609
|
gradleArtifactInputs(settingValueAt(settings, "android.artifactInputs"));
|
|
809
|
-
cache = "
|
|
610
|
+
cache = "Native APK caching uses complete inputs in the local or worker context. Build workers also need their separate android.offloadInputs declaration.";
|
|
810
611
|
} catch {}
|
|
811
612
|
const sdkPath = androidHome();
|
|
812
613
|
const sdk = androidSdkRefusal({
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { t as getExecutor } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { r as childEnvironment } from "./operation-exec-BW0em61G.mjs";
|
|
3
|
+
import { n as buildCacheKey } from "./build-cache-Dv7RN200.mjs";
|
|
4
|
+
import { o as androidHome } from "./android-C7sVmyI9.mjs";
|
|
5
|
+
import { n as fingerprintNativeInputs } from "./native-inputs-TRTTTRxt.mjs";
|
|
6
|
+
import { r as nativeGradleLocalSourceDigest, t as gradleOffloadInputs } from "./native-gradle-inputs-Dnh84Zbd.mjs";
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { dirname, join, resolve } from "node:path";
|
|
10
|
+
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
11
|
+
//#region src/integrations/native-gradle-artifact-inputs.ts
|
|
12
|
+
const NATIVE_GRADLE_CACHE_LIMIT = "Native APK caching requires android.artifactInputs with complete: true and a complete declaration of repeatable pinned inputs. Gradle incremental and task-cache reuse remain available without it.";
|
|
13
|
+
function nativeGradleWorkerScope(sourceDigest, inputs) {
|
|
14
|
+
return JSON.stringify([sourceDigest, {
|
|
15
|
+
complete: true,
|
|
16
|
+
ignored: inputs.ignored,
|
|
17
|
+
outputs: inputs.outputs
|
|
18
|
+
}]);
|
|
19
|
+
}
|
|
20
|
+
function nativeGradleWorkerArtifactIdentity(fingerprint, scope, variant, abi) {
|
|
21
|
+
const hash = createHash("sha256").update(JSON.stringify([
|
|
22
|
+
"stim-native-gradle-worker-v1",
|
|
23
|
+
fingerprint,
|
|
24
|
+
scope
|
|
25
|
+
])).digest("hex");
|
|
26
|
+
return {
|
|
27
|
+
hash,
|
|
28
|
+
key: buildCacheKey("android", hash, {
|
|
29
|
+
variant,
|
|
30
|
+
...abi ? { abi } : {}
|
|
31
|
+
})
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function gradleArtifactInputs(value) {
|
|
35
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(NATIVE_GRADLE_CACHE_LIMIT);
|
|
36
|
+
const localFiles = "localFiles" in value ? value.localFiles : [];
|
|
37
|
+
const environment = "environment" in value ? value.environment : [];
|
|
38
|
+
if (Object.keys(value).some((key) => ![
|
|
39
|
+
"complete",
|
|
40
|
+
"ignored",
|
|
41
|
+
"outputs",
|
|
42
|
+
"localFiles",
|
|
43
|
+
"environment"
|
|
44
|
+
].includes(key)) || !Array.isArray(localFiles) || !localFiles.every((path) => typeof path === "string" && path.length > 0 && !path.includes("\0")) || !Array.isArray(environment) || !environment.every((name) => typeof name === "string" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(name))) throw new Error(NATIVE_GRADLE_CACHE_LIMIT);
|
|
45
|
+
let inventory;
|
|
46
|
+
try {
|
|
47
|
+
inventory = gradleOffloadInputs({
|
|
48
|
+
complete: "complete" in value ? value.complete : void 0,
|
|
49
|
+
ignored: "ignored" in value ? value.ignored : void 0,
|
|
50
|
+
outputs: "outputs" in value ? value.outputs : void 0
|
|
51
|
+
});
|
|
52
|
+
} catch (error) {
|
|
53
|
+
throw new Error(String(error).replaceAll("android.offloadInputs", "android.artifactInputs"), { cause: error });
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
...inventory,
|
|
57
|
+
localFiles: [...new Set(localFiles)].toSorted(),
|
|
58
|
+
environment: [...new Set(environment)].toSorted()
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function optionalText(path, signal, encoding = "utf8") {
|
|
62
|
+
try {
|
|
63
|
+
return await readFile(path, {
|
|
64
|
+
encoding,
|
|
65
|
+
signal
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function javaRelease(env, signal) {
|
|
73
|
+
let home = env.JAVA_HOME;
|
|
74
|
+
if (!home) {
|
|
75
|
+
const java = getExecutor().findExecutable("java");
|
|
76
|
+
if (java) {
|
|
77
|
+
const selected = dirname(dirname(await realpath(java)));
|
|
78
|
+
if ((await optionalText(join(selected, "release"), signal))?.includes("JAVA_VERSION=")) home = selected;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!home && process.platform === "darwin") {
|
|
82
|
+
const child = childEnvironment(env);
|
|
83
|
+
home = (await getExecutor().runFileAsync("/usr/libexec/java_home", [], {
|
|
84
|
+
timeoutMs: 1e4,
|
|
85
|
+
signal,
|
|
86
|
+
...child
|
|
87
|
+
})).trim();
|
|
88
|
+
}
|
|
89
|
+
if (!home || !(await optionalText(join(home, "release"), signal))?.includes("JAVA_VERSION=")) throw new Error("The Gradle wrapper JDK release identity is unavailable.");
|
|
90
|
+
return join(home, "release");
|
|
91
|
+
}
|
|
92
|
+
async function localPropertiesIdentity(properties, sdk, root, signal) {
|
|
93
|
+
const content = await optionalText(properties, signal, "latin1");
|
|
94
|
+
if (content === null) return null;
|
|
95
|
+
const retained = [];
|
|
96
|
+
let selected = null;
|
|
97
|
+
for (const [, line = "", ending = ""] of content.matchAll(/([^\r\n]*)(\r\n|\r|\n|$)/g)) {
|
|
98
|
+
if (/^[ \t\f]*$/.test(line) || /^[ \t\f]*[#!]/.test(line)) {
|
|
99
|
+
retained.push(line + ending);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if ((line.match(/\\+$/)?.[0].length ?? 0) % 2 !== 0) throw new Error("Native APK caching requires single-line local.properties values.");
|
|
103
|
+
const entry = /^[ \t\f]*([A-Za-z0-9_.-]+)(?:[ \t\f]*[:=][ \t\f]*|[ \t\f]+)(.*)$/.exec(line);
|
|
104
|
+
if (!entry) {
|
|
105
|
+
if (/^[ \t\f]*[A-Za-z0-9_.-]+[ \t\f]*$/.test(line) && line.trim() !== "sdk.dir") {
|
|
106
|
+
retained.push(line + ending);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
throw new Error("Native APK caching requires plain, unescaped local.properties keys.");
|
|
110
|
+
}
|
|
111
|
+
if (entry[1] !== "sdk.dir") {
|
|
112
|
+
retained.push(line + ending);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const value = entry[2] ?? "";
|
|
116
|
+
if (!value || [...value].some((character) => character.charCodeAt(0) > 127)) throw new Error("Native APK caching cannot resolve the local.properties SDK.");
|
|
117
|
+
selected = value.replace(/\\u([a-fA-F\d]{4})|\\(.)/g, (full, hex, escaped) => {
|
|
118
|
+
if (hex) return String.fromCharCode(parseInt(hex, 16));
|
|
119
|
+
if (escaped === "u") throw new Error("Native APK caching cannot resolve the local.properties SDK.");
|
|
120
|
+
if (escaped === "t") return " ";
|
|
121
|
+
if (escaped === "r") return "\r";
|
|
122
|
+
if (escaped === "n") return "\n";
|
|
123
|
+
if (escaped === "f") return "\f";
|
|
124
|
+
return escaped ?? full;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (selected !== null && await realpath(resolve(root, selected)) !== sdk) throw new Error("Native APK caching requires the local.properties SDK to match ANDROID_HOME.");
|
|
128
|
+
return retained.join("");
|
|
129
|
+
}
|
|
130
|
+
async function nativeGradleArtifactSnapshot(root, value, build, abi, env, signal) {
|
|
131
|
+
signal?.throwIfAborted();
|
|
132
|
+
const declaration = gradleArtifactInputs(value);
|
|
133
|
+
const localFiles = declaration.localFiles.map((file) => resolve(root, file));
|
|
134
|
+
const properties = join(root, "local.properties");
|
|
135
|
+
const { complete, ignored, outputs } = declaration;
|
|
136
|
+
return nativeGradleArtifactSnapshotFromReceipt(root, {
|
|
137
|
+
source: await nativeGradleLocalSourceDigest(root, {
|
|
138
|
+
complete,
|
|
139
|
+
ignored,
|
|
140
|
+
outputs
|
|
141
|
+
}, [properties, ...localFiles], signal),
|
|
142
|
+
declaration,
|
|
143
|
+
build: {
|
|
144
|
+
variant: build.variant,
|
|
145
|
+
compilerCache: build.compilerCache,
|
|
146
|
+
gradleBuildCache: build.gradleBuildCache,
|
|
147
|
+
pch: build.pch,
|
|
148
|
+
cas: build.cas
|
|
149
|
+
},
|
|
150
|
+
abi
|
|
151
|
+
}, env, signal);
|
|
152
|
+
}
|
|
153
|
+
/** Revalidates private inputs; the caller must bind the receipt to a verified completed source snapshot. */
|
|
154
|
+
async function nativeGradleArtifactSnapshotFromReceipt(root, receipt, env, signal) {
|
|
155
|
+
signal?.throwIfAborted();
|
|
156
|
+
const { build, abi } = receipt;
|
|
157
|
+
if (!/^[a-f0-9]{64}$/.test(receipt.source)) throw new Error("The completed Gradle source identity is invalid.");
|
|
158
|
+
const declaration = gradleArtifactInputs(receipt.declaration);
|
|
159
|
+
const localFiles = declaration.localFiles.map((file) => resolve(root, file));
|
|
160
|
+
for (const path of localFiles) {
|
|
161
|
+
const info = await stat(path).catch((error) => {
|
|
162
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
163
|
+
throw error;
|
|
164
|
+
});
|
|
165
|
+
if (info && !info.isFile()) throw new Error("android.artifactInputs.localFiles must name exact regular files.");
|
|
166
|
+
}
|
|
167
|
+
const properties = join(root, "local.properties");
|
|
168
|
+
const sdkDirectory = await realpath(androidHome(env));
|
|
169
|
+
const home = env.HOME ?? env.USERPROFILE ?? homedir();
|
|
170
|
+
const gradleHome = env.GRADLE_USER_HOME ?? join(home, ".gradle");
|
|
171
|
+
const inputs = [{
|
|
172
|
+
name: "jdk-release",
|
|
173
|
+
path: await javaRelease(env, signal),
|
|
174
|
+
optional: false
|
|
175
|
+
}, ...[
|
|
176
|
+
"gradle.properties",
|
|
177
|
+
"init.gradle",
|
|
178
|
+
"init.gradle.kts",
|
|
179
|
+
"init.d"
|
|
180
|
+
].map((name) => ({
|
|
181
|
+
name: `gradle-user/${name}`,
|
|
182
|
+
path: join(gradleHome, name),
|
|
183
|
+
optional: true
|
|
184
|
+
}))];
|
|
185
|
+
for (const group of [
|
|
186
|
+
"build-tools",
|
|
187
|
+
"platforms",
|
|
188
|
+
"ndk",
|
|
189
|
+
"cmake"
|
|
190
|
+
]) {
|
|
191
|
+
const directory = join(sdkDirectory, group);
|
|
192
|
+
const versions = await readdir(directory).catch((error) => {
|
|
193
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
|
|
194
|
+
throw error;
|
|
195
|
+
});
|
|
196
|
+
for (const version of versions.toSorted()) {
|
|
197
|
+
if (!(await stat(join(directory, version))).isDirectory()) continue;
|
|
198
|
+
const path = join(directory, version, "source.properties");
|
|
199
|
+
if (await optionalText(path, signal) !== null) inputs.push({
|
|
200
|
+
name: `sdk/${group}/${version}`,
|
|
201
|
+
path,
|
|
202
|
+
optional: false
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (!inputs.some((input) => input.name.startsWith("sdk/build-tools/"))) throw new Error("Android SDK build-tools version metadata is unavailable.");
|
|
207
|
+
const preferences = [
|
|
208
|
+
join(home, ".android"),
|
|
209
|
+
...env.ANDROID_USER_HOME ? [env.ANDROID_USER_HOME] : [],
|
|
210
|
+
...[
|
|
211
|
+
"ANDROID_PREFS_ROOT",
|
|
212
|
+
"ANDROID_SDK_HOME",
|
|
213
|
+
"TEST_TMPDIR"
|
|
214
|
+
].flatMap((name) => env[name] ? [join(env[name], ".android")] : [])
|
|
215
|
+
];
|
|
216
|
+
for (const [index, directory] of [...new Set(preferences)].entries()) inputs.push({
|
|
217
|
+
name: `debug-keystore/${index}`,
|
|
218
|
+
path: join(directory, "debug.keystore"),
|
|
219
|
+
optional: true
|
|
220
|
+
});
|
|
221
|
+
for (const [index, path] of localFiles.entries()) inputs.push({
|
|
222
|
+
name: `local/${index}`,
|
|
223
|
+
path,
|
|
224
|
+
optional: true
|
|
225
|
+
});
|
|
226
|
+
const environment = Object.fromEntries([.../* @__PURE__ */ new Set([
|
|
227
|
+
...declaration.environment,
|
|
228
|
+
"JAVA_OPTS",
|
|
229
|
+
"JAVA_TOOL_OPTIONS",
|
|
230
|
+
"_JAVA_OPTIONS",
|
|
231
|
+
"GRADLE_OPTS"
|
|
232
|
+
])].toSorted().map((name) => [name, env[name] ?? null]));
|
|
233
|
+
const localProperties = await localPropertiesIdentity(properties, sdkDirectory, root, signal);
|
|
234
|
+
const local = await fingerprintNativeInputs(inputs, {
|
|
235
|
+
parameters: {
|
|
236
|
+
declaration,
|
|
237
|
+
environment,
|
|
238
|
+
localProperties: createHash("sha256").update(JSON.stringify(localProperties)).digest("hex")
|
|
239
|
+
},
|
|
240
|
+
signal
|
|
241
|
+
});
|
|
242
|
+
const hash = createHash("sha256").update("stim-native-gradle-artifact-v1\0").update(JSON.stringify({
|
|
243
|
+
source: receipt.source,
|
|
244
|
+
local: local.hash,
|
|
245
|
+
platform: process.platform,
|
|
246
|
+
arch: process.arch,
|
|
247
|
+
variant: build.variant ?? "debug",
|
|
248
|
+
compilerCache: build.compilerCache,
|
|
249
|
+
gradleBuildCache: build.gradleBuildCache,
|
|
250
|
+
pch: build.pch,
|
|
251
|
+
cas: build.cas,
|
|
252
|
+
abi
|
|
253
|
+
})).digest("hex");
|
|
254
|
+
return {
|
|
255
|
+
hash,
|
|
256
|
+
key: buildCacheKey("android", hash, {
|
|
257
|
+
variant: build.variant ?? "debug",
|
|
258
|
+
...abi ? { abi } : {}
|
|
259
|
+
}),
|
|
260
|
+
sdkDirectory,
|
|
261
|
+
receipt: {
|
|
262
|
+
source: receipt.source,
|
|
263
|
+
declaration,
|
|
264
|
+
build,
|
|
265
|
+
abi
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
270
|
+
export { nativeGradleWorkerArtifactIdentity as a, nativeGradleArtifactSnapshotFromReceipt as i, gradleArtifactInputs as n, nativeGradleWorkerScope as o, nativeGradleArtifactSnapshot as r, NATIVE_GRADLE_CACHE_LIMIT as t };
|