@expo/cli 1.0.0-canary-20250404-3c3b5fd → 1.0.0-canary-20250701-6a945c5
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 +33 -24
- package/build/bin/cli +1 -1
- package/build/metro-require/require.js +6 -4
- package/build/src/api/user/actions.js +25 -11
- package/build/src/api/user/actions.js.map +1 -1
- package/build/src/customize/templates.js +15 -1
- package/build/src/customize/templates.js.map +1 -1
- package/build/src/export/exportApp.js +26 -14
- package/build/src/export/exportApp.js.map +1 -1
- package/build/src/export/exportAsync.js +6 -0
- package/build/src/export/exportAsync.js.map +1 -1
- package/build/src/export/exportHermes.js +2 -2
- package/build/src/export/exportHermes.js.map +1 -1
- package/build/src/export/persistMetroAssets.js.map +1 -1
- package/build/src/install/checkPackages.js +22 -4
- package/build/src/install/checkPackages.js.map +1 -1
- package/build/src/install/index.js +3 -1
- package/build/src/install/index.js.map +1 -1
- package/build/src/install/resolveOptions.js +7 -2
- package/build/src/install/resolveOptions.js.map +1 -1
- package/build/src/install/utils/checkPackagesCompatibility.js +1 -1
- package/build/src/install/utils/checkPackagesCompatibility.js.map +1 -1
- package/build/src/lint/ESlintPrerequisite.js +32 -48
- package/build/src/lint/ESlintPrerequisite.js.map +1 -1
- package/build/src/lint/index.js +45 -47
- package/build/src/lint/index.js.map +1 -1
- package/build/src/lint/lintAsync.js +150 -4
- package/build/src/lint/lintAsync.js.map +1 -1
- package/build/src/lint/resolveOptions.js +115 -0
- package/build/src/lint/resolveOptions.js.map +1 -0
- package/build/src/prebuild/renameTemplateAppName.js +4 -1
- package/build/src/prebuild/renameTemplateAppName.js.map +1 -1
- package/build/src/prebuild/resolveTemplate.js +4 -4
- package/build/src/prebuild/resolveTemplate.js.map +1 -1
- package/build/src/prebuild/updatePackageJson.js +19 -9
- package/build/src/prebuild/updatePackageJson.js.map +1 -1
- package/build/src/run/android/resolveOptions.js +13 -1
- package/build/src/run/android/resolveOptions.js.map +1 -1
- package/build/src/run/android/runAndroidAsync.js +39 -17
- package/build/src/run/android/runAndroidAsync.js.map +1 -1
- package/build/src/run/ios/XcodeBuild.js +3 -3
- package/build/src/run/ios/XcodeBuild.js.map +1 -1
- package/build/src/run/ios/options/resolveOptions.js +13 -1
- package/build/src/run/ios/options/resolveOptions.js.map +1 -1
- package/build/src/run/ios/runIosAsync.js +38 -7
- package/build/src/run/ios/runIosAsync.js.map +1 -1
- package/build/src/start/doctor/SecurityBinPrerequisite.js +1 -1
- package/build/src/start/doctor/SecurityBinPrerequisite.js.map +1 -1
- package/build/src/start/doctor/apple/XcodePrerequisite.js +1 -1
- package/build/src/start/doctor/apple/XcodePrerequisite.js.map +1 -1
- package/build/src/start/doctor/dependencies/ensureDependenciesAsync.js +1 -1
- package/build/src/start/doctor/dependencies/ensureDependenciesAsync.js.map +1 -1
- package/build/src/start/doctor/dependencies/resolvePackages.js +1 -1
- package/build/src/start/doctor/dependencies/resolvePackages.js.map +1 -1
- package/build/src/start/doctor/ngrok/ExternalModule.js +1 -1
- package/build/src/start/doctor/ngrok/ExternalModule.js.map +1 -1
- package/build/src/start/index.js +1 -1
- package/build/src/start/index.js.map +1 -1
- package/build/src/start/platforms/PlatformManager.js +1 -1
- package/build/src/start/platforms/PlatformManager.js.map +1 -1
- package/build/src/start/platforms/android/AndroidPlatformManager.js +1 -1
- package/build/src/start/platforms/android/AndroidPlatformManager.js.map +1 -1
- package/build/src/start/platforms/android/getDevices.js +1 -1
- package/build/src/start/platforms/android/getDevices.js.map +1 -1
- package/build/src/start/platforms/ios/AppleDeviceManager.js +1 -1
- package/build/src/start/platforms/ios/AppleDeviceManager.js.map +1 -1
- package/build/src/start/platforms/ios/xcrun.js +1 -1
- package/build/src/start/platforms/ios/xcrun.js.map +1 -1
- package/build/src/start/project/dotExpo.js +5 -0
- package/build/src/start/project/dotExpo.js.map +1 -1
- package/build/src/start/resolveOptions.js +3 -0
- package/build/src/start/resolveOptions.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +38 -26
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +29 -2
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/createExpoFallbackResolver.js +6 -4
- package/build/src/start/server/metro/createExpoFallbackResolver.js.map +1 -1
- package/build/src/start/server/metro/createJResolver.js +2 -2
- package/build/src/start/server/metro/createJResolver.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +16 -5
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/debugging/createDebugMiddleware.js +19 -19
- package/build/src/start/server/metro/debugging/createDebugMiddleware.js.map +1 -1
- package/build/src/start/server/metro/externals.js +1 -1
- package/build/src/start/server/metro/externals.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +13 -8
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/log-box/LogBoxSymbolication.js +21 -2
- package/build/src/start/server/metro/log-box/LogBoxSymbolication.js.map +1 -1
- package/build/src/start/server/metro/log-box/formatProjectFilePath.js +15 -12
- package/build/src/start/server/metro/log-box/formatProjectFilePath.js.map +1 -1
- package/build/src/start/server/metro/metroErrorInterface.js +19 -8
- package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
- package/build/src/start/server/metro/runServer-fork.js +1 -1
- package/build/src/start/server/metro/runServer-fork.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +7 -12
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/CorsMiddleware.js +1 -1
- package/build/src/start/server/middleware/CorsMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ManifestMiddleware.js +4 -8
- package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/inspector/JsInspector.js +2 -25
- package/build/src/start/server/middleware/inspector/JsInspector.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +2 -26
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/utils/build-cache-providers/helpers.js +61 -0
- package/build/src/utils/build-cache-providers/helpers.js.map +1 -0
- package/build/src/utils/build-cache-providers/index.js +283 -0
- package/build/src/utils/build-cache-providers/index.js.map +1 -0
- package/build/src/utils/codesigning.js +14 -2
- package/build/src/utils/codesigning.js.map +1 -1
- package/build/src/utils/exit.js +0 -1
- package/build/src/utils/exit.js.map +1 -1
- package/build/src/utils/ip.js +7 -104
- package/build/src/utils/ip.js.map +1 -1
- package/build/src/utils/modifyConfigAsync.js +1 -1
- package/build/src/utils/modifyConfigAsync.js.map +1 -1
- package/build/src/utils/resolveArgs.js +8 -0
- package/build/src/utils/resolveArgs.js.map +1 -1
- package/build/src/utils/scheme.js +1 -1
- package/build/src/utils/scheme.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +2 -2
- package/build/src/utils/telemetry/clients/FetchClient.js.map +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/build/src/utils/tsconfig/evaluateTsConfig.js +7 -2
- package/build/src/utils/tsconfig/evaluateTsConfig.js.map +1 -1
- package/build/src/utils/variadic.js +63 -6
- package/build/src/utils/variadic.js.map +1 -1
- package/package.json +20 -20
- package/static/canary/react-is/cjs/react-is.development.js +118 -185
- package/static/canary/react-is/cjs/react-is.production.js +2 -2
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js +16582 -26565
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js +3495 -3357
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js +3929 -3801
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +16869 -27032
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +3535 -3428
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +4198 -4095
- package/static/canary/scheduler/cjs/scheduler-unstable_mock.development.js +387 -684
- package/static/canary/scheduler/cjs/scheduler-unstable_mock.production.js +0 -9
- package/static/canary/scheduler/cjs/scheduler-unstable_post_task.development.js +137 -195
- package/static/canary/scheduler/cjs/scheduler-unstable_post_task.production.js +0 -5
- package/static/canary/scheduler/cjs/scheduler.development.js +339 -600
- package/static/canary/scheduler/cjs/scheduler.native.development.js +324 -512
- package/static/canary/scheduler/cjs/scheduler.native.production.js +6 -5
- package/static/canary/scheduler/cjs/scheduler.production.js +16 -17
- package/static/canary-full/react/cjs/react-compiler-runtime.development.js +13 -68
- package/static/canary-full/react/cjs/react-jsx-dev-runtime.development.js +317 -1251
- package/static/canary-full/react/cjs/react-jsx-dev-runtime.react-server.development.js +353 -1286
- package/static/canary-full/react/cjs/react-jsx-runtime.development.js +326 -1279
- package/static/canary-full/react/cjs/react-jsx-runtime.react-server.development.js +353 -1286
- package/static/canary-full/react/cjs/react.development.js +1204 -2771
- package/static/canary-full/react/cjs/react.production.js +25 -20
- package/static/canary-full/react/cjs/react.react-server.development.js +783 -2162
- package/static/canary-full/react/cjs/react.react-server.production.js +13 -63
- package/static/canary-full/react/package.json +1 -1
- package/static/canary-full/react-dom/cjs/react-dom-client.development.js +24847 -37099
- package/static/canary-full/react-dom/cjs/react-dom-client.production.js +8261 -7475
- package/static/canary-full/react-dom/cjs/react-dom-profiling.development.js +25252 -37571
- package/static/canary-full/react-dom/cjs/react-dom-profiling.profiling.js +9442 -8662
- package/static/canary-full/react-dom/cjs/react-dom-server-legacy.browser.development.js +8944 -11568
- package/static/canary-full/react-dom/cjs/react-dom-server-legacy.browser.production.js +1378 -944
- package/static/canary-full/react-dom/cjs/react-dom-server-legacy.node.development.js +8944 -11568
- package/static/canary-full/react-dom/cjs/react-dom-server-legacy.node.production.js +1386 -954
- package/static/canary-full/react-dom/cjs/react-dom-server.browser.development.js +9344 -11600
- package/static/canary-full/react-dom/cjs/react-dom-server.browser.production.js +1545 -954
- package/static/canary-full/react-dom/cjs/react-dom-server.bun.development.js +8286 -11064
- package/static/canary-full/react-dom/cjs/react-dom-server.bun.production.js +1437 -976
- package/static/canary-full/react-dom/cjs/react-dom-server.edge.development.js +9356 -11609
- package/static/canary-full/react-dom/cjs/react-dom-server.edge.production.js +1542 -970
- package/static/canary-full/react-dom/cjs/react-dom-server.node.development.js +9227 -11571
- package/static/canary-full/react-dom/cjs/react-dom-server.node.production.js +1787 -1183
- package/static/canary-full/react-dom/cjs/react-dom-test-utils.development.js +13 -59
- package/static/canary-full/react-dom/cjs/react-dom.development.js +402 -604
- package/static/canary-full/react-dom/cjs/react-dom.production.js +4 -3
- package/static/canary-full/react-dom/cjs/react-dom.react-server.development.js +322 -382
- package/static/canary-full/react-dom/cjs/react-dom.react-server.production.js +6 -7
- package/static/canary-full/react-dom/package.json +5 -5
- package/static/canary-full/react-dom/static.browser.js +1 -0
- package/static/canary-full/react-dom/static.edge.js +1 -0
- package/static/canary-full/react-dom/static.node.js +1 -0
- package/static/template/eslint.config.js +10 -0
|
@@ -189,35 +189,45 @@ function updatePkgDependencies(projectRoot, { pkg, templatePkg, skipDependencyUp
|
|
|
189
189
|
].filter((depKey)=>!!defaultDependencies[depKey]);
|
|
190
190
|
const symlinkedPackages = [];
|
|
191
191
|
const nonRecommendedPackages = [];
|
|
192
|
-
for (const
|
|
192
|
+
for (const dependencyKey of requiredDependencies){
|
|
193
193
|
var _pkg_dependencies;
|
|
194
194
|
// If the local package.json defined the dependency that we want to overwrite...
|
|
195
|
-
if ((_pkg_dependencies = pkg.dependencies) == null ? void 0 : _pkg_dependencies[
|
|
195
|
+
if ((_pkg_dependencies = pkg.dependencies) == null ? void 0 : _pkg_dependencies[dependencyKey]) {
|
|
196
196
|
// Then ensure it isn't symlinked (i.e. the user has a custom version in their yarn workspace).
|
|
197
197
|
if ((0, _isModuleSymlinked.isModuleSymlinked)(projectRoot, {
|
|
198
|
-
moduleId:
|
|
198
|
+
moduleId: dependencyKey,
|
|
199
199
|
isSilent: true
|
|
200
200
|
})) {
|
|
201
201
|
// If the package is in the project's package.json and it's symlinked, then skip overwriting it.
|
|
202
|
-
symlinkedPackages.push(
|
|
202
|
+
symlinkedPackages.push([
|
|
203
|
+
`${dependencyKey}`,
|
|
204
|
+
`${dependencyKey}@${defaultDependencies[dependencyKey]}`
|
|
205
|
+
]);
|
|
203
206
|
continue;
|
|
204
207
|
}
|
|
205
208
|
// Do not modify manually skipped dependencies
|
|
206
|
-
if (skipDependencyUpdate.includes(
|
|
209
|
+
if (skipDependencyUpdate.includes(dependencyKey)) {
|
|
207
210
|
continue;
|
|
208
211
|
}
|
|
209
212
|
// Warn users for outdated dependencies when prebuilding
|
|
210
|
-
const hasRecommendedVersion = versionRangesIntersect(pkg.dependencies[
|
|
213
|
+
const hasRecommendedVersion = versionRangesIntersect(pkg.dependencies[dependencyKey], String(defaultDependencies[dependencyKey]));
|
|
211
214
|
if (!hasRecommendedVersion) {
|
|
212
|
-
nonRecommendedPackages.push(
|
|
215
|
+
nonRecommendedPackages.push([
|
|
216
|
+
`${dependencyKey}@${pkg.dependencies[dependencyKey]}`,
|
|
217
|
+
`${dependencyKey}@${defaultDependencies[dependencyKey]}`
|
|
218
|
+
]);
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
221
|
}
|
|
216
222
|
if (symlinkedPackages.length) {
|
|
217
|
-
|
|
223
|
+
symlinkedPackages.forEach(([current, recommended])=>{
|
|
224
|
+
_log.log(`\u203A Using symlinked ${_chalk().default.bold(current)} instead of recommended ${_chalk().default.bold(recommended)}.`);
|
|
225
|
+
});
|
|
218
226
|
}
|
|
219
227
|
if (nonRecommendedPackages.length) {
|
|
220
|
-
|
|
228
|
+
nonRecommendedPackages.forEach(([current, recommended])=>{
|
|
229
|
+
_log.warn(`\u203A Using ${_chalk().default.bold(current)} instead of recommended ${_chalk().default.bold(recommended)}.`);
|
|
230
|
+
});
|
|
221
231
|
}
|
|
222
232
|
// Only change the dependencies if the normalized hash changes, this helps to reduce meaningless changes.
|
|
223
233
|
const hasNewDependencies = hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/prebuild/updatePackageJson.ts"],"sourcesContent":["import { getPackageJson, PackageJSONConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { intersects as semverIntersects, Range as SemverRange } from 'semver';\n\nimport * as Log from '../log';\nimport { isModuleSymlinked } from '../utils/isModuleSymlinked';\nimport { logNewSection } from '../utils/ora';\n\nexport type DependenciesMap = { [key: string]: string | number };\n\nexport type DependenciesModificationResults = {\n /** A list of new values were added to the `dependencies` object in the `package.json`. */\n changedDependencies: string[];\n};\n\n/** Modifies the `package.json` with `modifyPackageJson` and format/displays the results. */\nexport async function updatePackageJSONAsync(\n projectRoot: string,\n {\n templateDirectory,\n templatePkg = getPackageJson(templateDirectory),\n pkg,\n skipDependencyUpdate,\n }: {\n templateDirectory: string;\n templatePkg?: PackageJSONConfig;\n pkg: PackageJSONConfig;\n skipDependencyUpdate?: string[];\n }\n): Promise<DependenciesModificationResults> {\n const updatingPackageJsonStep = logNewSection('Updating package.json');\n\n const results = modifyPackageJson(projectRoot, {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n });\n\n const hasChanges = results.changedDependencies.length || results.scriptsChanged;\n\n // NOTE: This is effectively bundler caching and subject to breakage if the inputs don't match the mutations.\n if (hasChanges) {\n await fs.promises.writeFile(\n path.resolve(projectRoot, 'package.json'),\n // Add new line to match the format of running yarn.\n // This prevents the `package.json` from changing when running `prebuild --no-install` multiple times.\n JSON.stringify(pkg, null, 2) + '\\n'\n );\n }\n\n updatingPackageJsonStep.succeed(\n 'Updated package.json' + (hasChanges ? '' : chalk.dim(` | no changes`))\n );\n\n return results;\n}\n\n/**\n * Make required modifications to the `package.json` file as a JSON object.\n *\n * 1. Update `package.json` `scripts`.\n * 2. Update `package.json` `dependencies` (not `devDependencies`).\n * 3. Update `package.json` `main`.\n *\n * @param projectRoot The root directory of the project.\n * @param templatePkg Template project package.json as JSON.\n * @param pkg Current package.json as JSON.\n * @param skipDependencyUpdate Array of dependencies to skip updating.\n * @returns\n */\nfunction modifyPackageJson(\n projectRoot: string,\n {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n }: {\n templatePkg: PackageJSONConfig;\n pkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n) {\n const scriptsChanged = updatePkgScripts({ pkg });\n\n // TODO: Move to `npx expo-doctor`\n return {\n scriptsChanged,\n ...updatePkgDependencies(projectRoot, {\n pkg,\n templatePkg,\n skipDependencyUpdate,\n }),\n };\n}\n\n/**\n * Update `package.json` dependencies by combining the `dependencies` in the\n * project we are creating with the dependencies in the template project.\n *\n * > Exposed for testing.\n */\nexport function updatePkgDependencies(\n projectRoot: string,\n {\n pkg,\n templatePkg,\n skipDependencyUpdate = [],\n }: {\n pkg: PackageJSONConfig;\n templatePkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n): DependenciesModificationResults {\n const { dependencies } = templatePkg;\n // The default values come from the bare-minimum template's package.json.\n // Users can change this by using different templates with the `--template` flag.\n // The main reason for allowing the changing of dependencies would be to include\n // dependencies that are required for the native project to build. For example,\n // it does not need to include dependencies that are used in the JS-code only.\n const defaultDependencies = createDependenciesMap(dependencies);\n\n // NOTE: This is a hack to ensure this doesn't trigger an extraneous change in the `package.json`\n // it isn't required for anything in the `ios` and `android` folders.\n delete defaultDependencies['expo-status-bar'];\n // NOTE: Expo splash screen is installed by default in the template but the config plugin also lives in prebuild-config\n // so we can delete it to prevent an extraneous change in the `package.json`.\n delete defaultDependencies['expo-splash-screen'];\n\n const combinedDependencies: DependenciesMap = createDependenciesMap({\n ...defaultDependencies,\n ...pkg.dependencies,\n });\n\n // These dependencies are only added, not overwritten from the project\n const requiredDependencies = [\n // TODO: This is no longer required because it's this same package.\n 'expo',\n // TODO: Drop this somehow.\n 'react-native',\n ].filter((depKey) => !!defaultDependencies[depKey]);\n\n const symlinkedPackages: string[] = [];\n const nonRecommendedPackages: string[] = [];\n\n for (const dependenciesKey of requiredDependencies) {\n // If the local package.json defined the dependency that we want to overwrite...\n if (pkg.dependencies?.[dependenciesKey]) {\n // Then ensure it isn't symlinked (i.e. the user has a custom version in their yarn workspace).\n if (isModuleSymlinked(projectRoot, { moduleId: dependenciesKey, isSilent: true })) {\n // If the package is in the project's package.json and it's symlinked, then skip overwriting it.\n symlinkedPackages.push(dependenciesKey);\n continue;\n }\n\n // Do not modify manually skipped dependencies\n if (skipDependencyUpdate.includes(dependenciesKey)) {\n continue;\n }\n\n // Warn users for outdated dependencies when prebuilding\n const hasRecommendedVersion = versionRangesIntersect(\n pkg.dependencies[dependenciesKey],\n String(defaultDependencies[dependenciesKey])\n );\n if (!hasRecommendedVersion) {\n nonRecommendedPackages.push(`${dependenciesKey}@${defaultDependencies[dependenciesKey]}`);\n }\n }\n }\n\n if (symlinkedPackages.length) {\n Log.log(\n `\\u203A Using symlinked ${symlinkedPackages\n .map((pkg) => chalk.bold(pkg))\n .join(', ')} instead of recommended version(s).`\n );\n }\n\n if (nonRecommendedPackages.length) {\n Log.warn(\n `\\u203A Using current versions instead of recommended ${nonRecommendedPackages\n .map((pkg) => chalk.bold(pkg))\n .join(', ')}.`\n );\n }\n\n // Only change the dependencies if the normalized hash changes, this helps to reduce meaningless changes.\n const hasNewDependencies =\n hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);\n // Save the dependencies\n let changedDependencies: string[] = [];\n if (hasNewDependencies) {\n changedDependencies = diffKeys(combinedDependencies, pkg.dependencies ?? {}).sort();\n // Use Object.assign to preserve the original order of dependencies, this makes it easier to see what changed in the git diff.\n pkg.dependencies = Object.assign(pkg.dependencies ?? {}, combinedDependencies);\n }\n\n return {\n changedDependencies,\n };\n}\n\nfunction diffKeys(a: Record<string, any>, b: Record<string, any>): string[] {\n return Object.keys(a).filter((key) => a[key] !== b[key]);\n}\n\n/**\n * Create an object of type DependenciesMap a dependencies object or throw if not valid.\n *\n * @param dependencies - ideally an object of type {[key]: string} - if not then this will error.\n */\nexport function createDependenciesMap(dependencies: any): DependenciesMap {\n if (typeof dependencies !== 'object') {\n throw new Error(`Dependency map is invalid, expected object but got ${typeof dependencies}`);\n } else if (!dependencies) {\n return {};\n }\n\n const outputMap: DependenciesMap = {};\n\n for (const key of Object.keys(dependencies)) {\n const value = dependencies[key];\n if (typeof value === 'string') {\n outputMap[key] = value;\n } else {\n throw new Error(\n `Dependency for key \\`${key}\\` should be a \\`string\\`, instead got: \\`{ ${key}: ${JSON.stringify(\n value\n )} }\\``\n );\n }\n }\n return outputMap;\n}\n\n/**\n * Updates the package.json scripts for prebuild if the scripts match\n * the default values used in project templates.\n */\nexport function updatePkgScripts({ pkg }: { pkg: PackageJSONConfig }) {\n let hasChanged = false;\n if (!pkg.scripts) {\n pkg.scripts = {};\n }\n if (\n !pkg.scripts.android ||\n pkg.scripts.android === 'expo start --android' ||\n pkg.scripts.android === 'react-native run-android'\n ) {\n pkg.scripts.android = 'expo run:android';\n hasChanged = true;\n }\n if (\n !pkg.scripts.ios ||\n pkg.scripts.ios === 'expo start --ios' ||\n pkg.scripts.ios === 'react-native run-ios'\n ) {\n pkg.scripts.ios = 'expo run:ios';\n hasChanged = true;\n }\n return hasChanged;\n}\n\nfunction normalizeDependencyMap(deps: DependenciesMap): string[] {\n return Object.keys(deps)\n .map((dependency) => `${dependency}@${deps[dependency]}`)\n .sort();\n}\n\nexport function hashForDependencyMap(deps: DependenciesMap = {}): string {\n const depsList = normalizeDependencyMap(deps);\n const depsString = depsList.join('\\n');\n return createFileHash(depsString);\n}\n\nexport function createFileHash(contents: string): string {\n // this doesn't need to be secure, the shorter the better.\n return crypto.createHash('sha1').update(contents).digest('hex');\n}\n\n/**\n * Determine if two semver ranges are overlapping or intersecting.\n * This is a safe version of `semver.intersects` that does not throw.\n */\nfunction versionRangesIntersect(rangeA: string | SemverRange, rangeB: string | SemverRange) {\n try {\n return semverIntersects(rangeA, rangeB);\n } catch {\n return false;\n }\n}\n"],"names":["createDependenciesMap","createFileHash","hashForDependencyMap","updatePackageJSONAsync","updatePkgDependencies","updatePkgScripts","projectRoot","templateDirectory","templatePkg","getPackageJson","pkg","skipDependencyUpdate","updatingPackageJsonStep","logNewSection","results","modifyPackageJson","hasChanges","changedDependencies","length","scriptsChanged","fs","promises","writeFile","path","resolve","JSON","stringify","succeed","chalk","dim","dependencies","defaultDependencies","combinedDependencies","requiredDependencies","filter","depKey","symlinkedPackages","nonRecommendedPackages","dependenciesKey","isModuleSymlinked","moduleId","isSilent","push","includes","hasRecommendedVersion","versionRangesIntersect","String","Log","log","map","bold","join","warn","hasNewDependencies","diffKeys","sort","Object","assign","a","b","keys","key","Error","outputMap","value","hasChanged","scripts","android","ios","normalizeDependencyMap","deps","dependency","depsList","depsString","contents","crypto","createHash","update","digest","rangeA","rangeB","semverIntersects"],"mappings":";;;;;;;;;;;IAwNgBA,qBAAqB;eAArBA;;IAgEAC,cAAc;eAAdA;;IANAC,oBAAoB;eAApBA;;IA/PMC,sBAAsB;eAAtBA;;IAsFNC,qBAAqB;eAArBA;;IA2IAC,gBAAgB;eAAhBA;;;;yBApPkC;;;;;;;gEAChC;;;;;;;gEACC;;;;;;;gEACJ;;;;;;;gEACE;;;;;;;yBACoD;;;;;;6DAEhD;mCACa;qBACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUvB,eAAeF,uBACpBG,WAAmB,EACnB,EACEC,iBAAiB,EACjBC,cAAcC,IAAAA,wBAAc,EAACF,kBAAkB,EAC/CG,GAAG,EACHC,oBAAoB,EAMrB;IAED,MAAMC,0BAA0BC,IAAAA,kBAAa,EAAC;IAE9C,MAAMC,UAAUC,kBAAkBT,aAAa;QAC7CE;QACAE;QACAC;IACF;IAEA,MAAMK,aAAaF,QAAQG,mBAAmB,CAACC,MAAM,IAAIJ,QAAQK,cAAc;IAE/E,6GAA6G;IAC7G,IAAIH,YAAY;QACd,MAAMI,aAAE,CAACC,QAAQ,CAACC,SAAS,CACzBC,eAAI,CAACC,OAAO,CAAClB,aAAa,iBAC1B,oDAAoD;QACpD,sGAAsG;QACtGmB,KAAKC,SAAS,CAAChB,KAAK,MAAM,KAAK;IAEnC;IAEAE,wBAAwBe,OAAO,CAC7B,yBAA0BX,CAAAA,aAAa,KAAKY,gBAAK,CAACC,GAAG,CAAC,CAAC,aAAa,CAAC,CAAA;IAGvE,OAAOf;AACT;AAEA;;;;;;;;;;;;CAYC,GACD,SAASC,kBACPT,WAAmB,EACnB,EACEE,WAAW,EACXE,GAAG,EACHC,oBAAoB,EAMrB;IAED,MAAMQ,iBAAiBd,iBAAiB;QAAEK;IAAI;IAE9C,kCAAkC;IAClC,OAAO;QACLS;QACA,GAAGf,sBAAsBE,aAAa;YACpCI;YACAF;YACAG;QACF,EAAE;IACJ;AACF;AAQO,SAASP,sBACdE,WAAmB,EACnB,EACEI,GAAG,EACHF,WAAW,EACXG,uBAAuB,EAAE,EAM1B;IAED,MAAM,EAAEmB,YAAY,EAAE,GAAGtB;IACzB,yEAAyE;IACzE,iFAAiF;IACjF,gFAAgF;IAChF,+EAA+E;IAC/E,8EAA8E;IAC9E,MAAMuB,sBAAsB/B,sBAAsB8B;IAElD,iGAAiG;IACjG,qEAAqE;IACrE,OAAOC,mBAAmB,CAAC,kBAAkB;IAC7C,uHAAuH;IACvH,6EAA6E;IAC7E,OAAOA,mBAAmB,CAAC,qBAAqB;IAEhD,MAAMC,uBAAwChC,sBAAsB;QAClE,GAAG+B,mBAAmB;QACtB,GAAGrB,IAAIoB,YAAY;IACrB;IAEA,sEAAsE;IACtE,MAAMG,uBAAuB;QAC3B,mEAAmE;QACnE;QACA,2BAA2B;QAC3B;KACD,CAACC,MAAM,CAAC,CAACC,SAAW,CAAC,CAACJ,mBAAmB,CAACI,OAAO;IAElD,MAAMC,oBAA8B,EAAE;IACtC,MAAMC,yBAAmC,EAAE;IAE3C,KAAK,MAAMC,mBAAmBL,qBAAsB;YAE9CvB;QADJ,gFAAgF;QAChF,KAAIA,oBAAAA,IAAIoB,YAAY,qBAAhBpB,iBAAkB,CAAC4B,gBAAgB,EAAE;YACvC,+FAA+F;YAC/F,IAAIC,IAAAA,oCAAiB,EAACjC,aAAa;gBAAEkC,UAAUF;gBAAiBG,UAAU;YAAK,IAAI;gBACjF,gGAAgG;gBAChGL,kBAAkBM,IAAI,CAACJ;gBACvB;YACF;YAEA,8CAA8C;YAC9C,IAAI3B,qBAAqBgC,QAAQ,CAACL,kBAAkB;gBAClD;YACF;YAEA,wDAAwD;YACxD,MAAMM,wBAAwBC,uBAC5BnC,IAAIoB,YAAY,CAACQ,gBAAgB,EACjCQ,OAAOf,mBAAmB,CAACO,gBAAgB;YAE7C,IAAI,CAACM,uBAAuB;gBAC1BP,uBAAuBK,IAAI,CAAC,GAAGJ,gBAAgB,CAAC,EAAEP,mBAAmB,CAACO,gBAAgB,EAAE;YAC1F;QACF;IACF;IAEA,IAAIF,kBAAkBlB,MAAM,EAAE;QAC5B6B,KAAIC,GAAG,CACL,CAAC,uBAAuB,EAAEZ,kBACvBa,GAAG,CAAC,CAACvC,MAAQkB,gBAAK,CAACsB,IAAI,CAACxC,MACxByC,IAAI,CAAC,MAAM,mCAAmC,CAAC;IAEtD;IAEA,IAAId,uBAAuBnB,MAAM,EAAE;QACjC6B,KAAIK,IAAI,CACN,CAAC,qDAAqD,EAAEf,uBACrDY,GAAG,CAAC,CAACvC,MAAQkB,gBAAK,CAACsB,IAAI,CAACxC,MACxByC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpB;IAEA,yGAAyG;IACzG,MAAME,qBACJnD,qBAAqBQ,IAAIoB,YAAY,MAAM5B,qBAAqB8B;IAClE,wBAAwB;IACxB,IAAIf,sBAAgC,EAAE;IACtC,IAAIoC,oBAAoB;QACtBpC,sBAAsBqC,SAAStB,sBAAsBtB,IAAIoB,YAAY,IAAI,CAAC,GAAGyB,IAAI;QACjF,8HAA8H;QAC9H7C,IAAIoB,YAAY,GAAG0B,OAAOC,MAAM,CAAC/C,IAAIoB,YAAY,IAAI,CAAC,GAAGE;IAC3D;IAEA,OAAO;QACLf;IACF;AACF;AAEA,SAASqC,SAASI,CAAsB,EAAEC,CAAsB;IAC9D,OAAOH,OAAOI,IAAI,CAACF,GAAGxB,MAAM,CAAC,CAAC2B,MAAQH,CAAC,CAACG,IAAI,KAAKF,CAAC,CAACE,IAAI;AACzD;AAOO,SAAS7D,sBAAsB8B,YAAiB;IACrD,IAAI,OAAOA,iBAAiB,UAAU;QACpC,MAAM,IAAIgC,MAAM,CAAC,mDAAmD,EAAE,OAAOhC,cAAc;IAC7F,OAAO,IAAI,CAACA,cAAc;QACxB,OAAO,CAAC;IACV;IAEA,MAAMiC,YAA6B,CAAC;IAEpC,KAAK,MAAMF,OAAOL,OAAOI,IAAI,CAAC9B,cAAe;QAC3C,MAAMkC,QAAQlC,YAAY,CAAC+B,IAAI;QAC/B,IAAI,OAAOG,UAAU,UAAU;YAC7BD,SAAS,CAACF,IAAI,GAAGG;QACnB,OAAO;YACL,MAAM,IAAIF,MACR,CAAC,qBAAqB,EAAED,IAAI,4CAA4C,EAAEA,IAAI,EAAE,EAAEpC,KAAKC,SAAS,CAC9FsC,OACA,IAAI,CAAC;QAEX;IACF;IACA,OAAOD;AACT;AAMO,SAAS1D,iBAAiB,EAAEK,GAAG,EAA8B;IAClE,IAAIuD,aAAa;IACjB,IAAI,CAACvD,IAAIwD,OAAO,EAAE;QAChBxD,IAAIwD,OAAO,GAAG,CAAC;IACjB;IACA,IACE,CAACxD,IAAIwD,OAAO,CAACC,OAAO,IACpBzD,IAAIwD,OAAO,CAACC,OAAO,KAAK,0BACxBzD,IAAIwD,OAAO,CAACC,OAAO,KAAK,4BACxB;QACAzD,IAAIwD,OAAO,CAACC,OAAO,GAAG;QACtBF,aAAa;IACf;IACA,IACE,CAACvD,IAAIwD,OAAO,CAACE,GAAG,IAChB1D,IAAIwD,OAAO,CAACE,GAAG,KAAK,sBACpB1D,IAAIwD,OAAO,CAACE,GAAG,KAAK,wBACpB;QACA1D,IAAIwD,OAAO,CAACE,GAAG,GAAG;QAClBH,aAAa;IACf;IACA,OAAOA;AACT;AAEA,SAASI,uBAAuBC,IAAqB;IACnD,OAAOd,OAAOI,IAAI,CAACU,MAChBrB,GAAG,CAAC,CAACsB,aAAe,GAAGA,WAAW,CAAC,EAAED,IAAI,CAACC,WAAW,EAAE,EACvDhB,IAAI;AACT;AAEO,SAASrD,qBAAqBoE,OAAwB,CAAC,CAAC;IAC7D,MAAME,WAAWH,uBAAuBC;IACxC,MAAMG,aAAaD,SAASrB,IAAI,CAAC;IACjC,OAAOlD,eAAewE;AACxB;AAEO,SAASxE,eAAeyE,QAAgB;IAC7C,0DAA0D;IAC1D,OAAOC,iBAAM,CAACC,UAAU,CAAC,QAAQC,MAAM,CAACH,UAAUI,MAAM,CAAC;AAC3D;AAEA;;;CAGC,GACD,SAASjC,uBAAuBkC,MAA4B,EAAEC,MAA4B;IACxF,IAAI;QACF,OAAOC,IAAAA,oBAAgB,EAACF,QAAQC;IAClC,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/prebuild/updatePackageJson.ts"],"sourcesContent":["import { getPackageJson, PackageJSONConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { intersects as semverIntersects, Range as SemverRange } from 'semver';\n\nimport * as Log from '../log';\nimport { isModuleSymlinked } from '../utils/isModuleSymlinked';\nimport { logNewSection } from '../utils/ora';\n\nexport type DependenciesMap = { [key: string]: string | number };\n\nexport type DependenciesModificationResults = {\n /** A list of new values were added to the `dependencies` object in the `package.json`. */\n changedDependencies: string[];\n};\n\n/** Modifies the `package.json` with `modifyPackageJson` and format/displays the results. */\nexport async function updatePackageJSONAsync(\n projectRoot: string,\n {\n templateDirectory,\n templatePkg = getPackageJson(templateDirectory),\n pkg,\n skipDependencyUpdate,\n }: {\n templateDirectory: string;\n templatePkg?: PackageJSONConfig;\n pkg: PackageJSONConfig;\n skipDependencyUpdate?: string[];\n }\n): Promise<DependenciesModificationResults> {\n const updatingPackageJsonStep = logNewSection('Updating package.json');\n\n const results = modifyPackageJson(projectRoot, {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n });\n\n const hasChanges = results.changedDependencies.length || results.scriptsChanged;\n\n // NOTE: This is effectively bundler caching and subject to breakage if the inputs don't match the mutations.\n if (hasChanges) {\n await fs.promises.writeFile(\n path.resolve(projectRoot, 'package.json'),\n // Add new line to match the format of running yarn.\n // This prevents the `package.json` from changing when running `prebuild --no-install` multiple times.\n JSON.stringify(pkg, null, 2) + '\\n'\n );\n }\n\n updatingPackageJsonStep.succeed(\n 'Updated package.json' + (hasChanges ? '' : chalk.dim(` | no changes`))\n );\n\n return results;\n}\n\n/**\n * Make required modifications to the `package.json` file as a JSON object.\n *\n * 1. Update `package.json` `scripts`.\n * 2. Update `package.json` `dependencies` (not `devDependencies`).\n * 3. Update `package.json` `main`.\n *\n * @param projectRoot The root directory of the project.\n * @param templatePkg Template project package.json as JSON.\n * @param pkg Current package.json as JSON.\n * @param skipDependencyUpdate Array of dependencies to skip updating.\n * @returns\n */\nfunction modifyPackageJson(\n projectRoot: string,\n {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n }: {\n templatePkg: PackageJSONConfig;\n pkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n) {\n const scriptsChanged = updatePkgScripts({ pkg });\n\n // TODO: Move to `npx expo-doctor`\n return {\n scriptsChanged,\n ...updatePkgDependencies(projectRoot, {\n pkg,\n templatePkg,\n skipDependencyUpdate,\n }),\n };\n}\n\n/**\n * Update `package.json` dependencies by combining the `dependencies` in the\n * project we are creating with the dependencies in the template project.\n *\n * > Exposed for testing.\n */\nexport function updatePkgDependencies(\n projectRoot: string,\n {\n pkg,\n templatePkg,\n skipDependencyUpdate = [],\n }: {\n pkg: PackageJSONConfig;\n templatePkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n): DependenciesModificationResults {\n const { dependencies } = templatePkg;\n // The default values come from the bare-minimum template's package.json.\n // Users can change this by using different templates with the `--template` flag.\n // The main reason for allowing the changing of dependencies would be to include\n // dependencies that are required for the native project to build. For example,\n // it does not need to include dependencies that are used in the JS-code only.\n const defaultDependencies = createDependenciesMap(dependencies);\n\n // NOTE: This is a hack to ensure this doesn't trigger an extraneous change in the `package.json`\n // it isn't required for anything in the `ios` and `android` folders.\n delete defaultDependencies['expo-status-bar'];\n // NOTE: Expo splash screen is installed by default in the template but the config plugin also lives in prebuild-config\n // so we can delete it to prevent an extraneous change in the `package.json`.\n delete defaultDependencies['expo-splash-screen'];\n\n const combinedDependencies: DependenciesMap = createDependenciesMap({\n ...defaultDependencies,\n ...pkg.dependencies,\n });\n\n // These dependencies are only added, not overwritten from the project\n const requiredDependencies = [\n // TODO: This is no longer required because it's this same package.\n 'expo',\n // TODO: Drop this somehow.\n 'react-native',\n ].filter((depKey) => !!defaultDependencies[depKey]);\n\n const symlinkedPackages: [string, string][] = [];\n const nonRecommendedPackages: [string, string][] = [];\n\n for (const dependencyKey of requiredDependencies) {\n // If the local package.json defined the dependency that we want to overwrite...\n if (pkg.dependencies?.[dependencyKey]) {\n // Then ensure it isn't symlinked (i.e. the user has a custom version in their yarn workspace).\n if (isModuleSymlinked(projectRoot, { moduleId: dependencyKey, isSilent: true })) {\n // If the package is in the project's package.json and it's symlinked, then skip overwriting it.\n symlinkedPackages.push([\n `${dependencyKey}`,\n `${dependencyKey}@${defaultDependencies[dependencyKey]}`,\n ]);\n continue;\n }\n\n // Do not modify manually skipped dependencies\n if (skipDependencyUpdate.includes(dependencyKey)) {\n continue;\n }\n\n // Warn users for outdated dependencies when prebuilding\n const hasRecommendedVersion = versionRangesIntersect(\n pkg.dependencies[dependencyKey],\n String(defaultDependencies[dependencyKey])\n );\n if (!hasRecommendedVersion) {\n nonRecommendedPackages.push([\n `${dependencyKey}@${pkg.dependencies[dependencyKey]}`,\n `${dependencyKey}@${defaultDependencies[dependencyKey]}`,\n ]);\n }\n }\n }\n\n if (symlinkedPackages.length) {\n symlinkedPackages.forEach(([current, recommended]) => {\n Log.log(\n `\\u203A Using symlinked ${chalk.bold(current)} instead of recommended ${chalk.bold(recommended)}.`\n );\n });\n }\n\n if (nonRecommendedPackages.length) {\n nonRecommendedPackages.forEach(([current, recommended]) => {\n Log.warn(\n `\\u203A Using ${chalk.bold(current)} instead of recommended ${chalk.bold(recommended)}.`\n );\n });\n }\n\n // Only change the dependencies if the normalized hash changes, this helps to reduce meaningless changes.\n const hasNewDependencies =\n hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);\n // Save the dependencies\n let changedDependencies: string[] = [];\n if (hasNewDependencies) {\n changedDependencies = diffKeys(combinedDependencies, pkg.dependencies ?? {}).sort();\n // Use Object.assign to preserve the original order of dependencies, this makes it easier to see what changed in the git diff.\n pkg.dependencies = Object.assign(pkg.dependencies ?? {}, combinedDependencies);\n }\n\n return {\n changedDependencies,\n };\n}\n\nfunction diffKeys(a: Record<string, any>, b: Record<string, any>): string[] {\n return Object.keys(a).filter((key) => a[key] !== b[key]);\n}\n\n/**\n * Create an object of type DependenciesMap a dependencies object or throw if not valid.\n *\n * @param dependencies - ideally an object of type {[key]: string} - if not then this will error.\n */\nexport function createDependenciesMap(dependencies: any): DependenciesMap {\n if (typeof dependencies !== 'object') {\n throw new Error(`Dependency map is invalid, expected object but got ${typeof dependencies}`);\n } else if (!dependencies) {\n return {};\n }\n\n const outputMap: DependenciesMap = {};\n\n for (const key of Object.keys(dependencies)) {\n const value = dependencies[key];\n if (typeof value === 'string') {\n outputMap[key] = value;\n } else {\n throw new Error(\n `Dependency for key \\`${key}\\` should be a \\`string\\`, instead got: \\`{ ${key}: ${JSON.stringify(\n value\n )} }\\``\n );\n }\n }\n return outputMap;\n}\n\n/**\n * Updates the package.json scripts for prebuild if the scripts match\n * the default values used in project templates.\n */\nexport function updatePkgScripts({ pkg }: { pkg: PackageJSONConfig }) {\n let hasChanged = false;\n if (!pkg.scripts) {\n pkg.scripts = {};\n }\n if (\n !pkg.scripts.android ||\n pkg.scripts.android === 'expo start --android' ||\n pkg.scripts.android === 'react-native run-android'\n ) {\n pkg.scripts.android = 'expo run:android';\n hasChanged = true;\n }\n if (\n !pkg.scripts.ios ||\n pkg.scripts.ios === 'expo start --ios' ||\n pkg.scripts.ios === 'react-native run-ios'\n ) {\n pkg.scripts.ios = 'expo run:ios';\n hasChanged = true;\n }\n return hasChanged;\n}\n\nfunction normalizeDependencyMap(deps: DependenciesMap): string[] {\n return Object.keys(deps)\n .map((dependency) => `${dependency}@${deps[dependency]}`)\n .sort();\n}\n\nexport function hashForDependencyMap(deps: DependenciesMap = {}): string {\n const depsList = normalizeDependencyMap(deps);\n const depsString = depsList.join('\\n');\n return createFileHash(depsString);\n}\n\nexport function createFileHash(contents: string): string {\n // this doesn't need to be secure, the shorter the better.\n return crypto.createHash('sha1').update(contents).digest('hex');\n}\n\n/**\n * Determine if two semver ranges are overlapping or intersecting.\n * This is a safe version of `semver.intersects` that does not throw.\n */\nfunction versionRangesIntersect(rangeA: string | SemverRange, rangeB: string | SemverRange) {\n try {\n return semverIntersects(rangeA, rangeB);\n } catch {\n return false;\n }\n}\n"],"names":["createDependenciesMap","createFileHash","hashForDependencyMap","updatePackageJSONAsync","updatePkgDependencies","updatePkgScripts","projectRoot","templateDirectory","templatePkg","getPackageJson","pkg","skipDependencyUpdate","updatingPackageJsonStep","logNewSection","results","modifyPackageJson","hasChanges","changedDependencies","length","scriptsChanged","fs","promises","writeFile","path","resolve","JSON","stringify","succeed","chalk","dim","dependencies","defaultDependencies","combinedDependencies","requiredDependencies","filter","depKey","symlinkedPackages","nonRecommendedPackages","dependencyKey","isModuleSymlinked","moduleId","isSilent","push","includes","hasRecommendedVersion","versionRangesIntersect","String","forEach","current","recommended","Log","log","bold","warn","hasNewDependencies","diffKeys","sort","Object","assign","a","b","keys","key","Error","outputMap","value","hasChanged","scripts","android","ios","normalizeDependencyMap","deps","map","dependency","depsList","depsString","join","contents","crypto","createHash","update","digest","rangeA","rangeB","semverIntersects"],"mappings":"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"}
|
|
@@ -8,13 +8,24 @@ Object.defineProperty(exports, "resolveOptionsAsync", {
|
|
|
8
8
|
return resolveOptionsAsync;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
function _config() {
|
|
12
|
+
const data = require("@expo/config");
|
|
13
|
+
_config = function() {
|
|
14
|
+
return data;
|
|
15
|
+
};
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
11
18
|
const _resolveDevice = require("./resolveDevice");
|
|
12
19
|
const _resolveGradlePropsAsync = require("./resolveGradlePropsAsync");
|
|
13
20
|
const _resolveLaunchProps = require("./resolveLaunchProps");
|
|
21
|
+
const _buildcacheproviders = require("../../utils/build-cache-providers");
|
|
14
22
|
const _resolveBundlerProps = require("../resolveBundlerProps");
|
|
15
23
|
async function resolveOptionsAsync(projectRoot, options) {
|
|
24
|
+
var _projectConfig_exp_experiments, _projectConfig_exp_experiments_remoteBuildCache, _projectConfig_exp_experiments1;
|
|
16
25
|
// Resolve the device before the gradle props because we need the device to be running to get the ABI.
|
|
17
26
|
const device = await (0, _resolveDevice.resolveDeviceAsync)(options.device);
|
|
27
|
+
const projectConfig = (0, _config().getConfig)(projectRoot);
|
|
28
|
+
const buildCacheProvider = await (0, _buildcacheproviders.resolveBuildCacheProvider)(((_projectConfig_exp_experiments = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments.buildCacheProvider) ?? ((_projectConfig_exp_experiments1 = projectConfig.exp.experiments) == null ? void 0 : (_projectConfig_exp_experiments_remoteBuildCache = _projectConfig_exp_experiments1.remoteBuildCache) == null ? void 0 : _projectConfig_exp_experiments_remoteBuildCache.provider), projectRoot);
|
|
18
29
|
return {
|
|
19
30
|
...await (0, _resolveBundlerProps.resolveBundlerPropsAsync)(projectRoot, options),
|
|
20
31
|
...await (0, _resolveGradlePropsAsync.resolveGradlePropsAsync)(projectRoot, options, device.device),
|
|
@@ -24,7 +35,8 @@ async function resolveOptionsAsync(projectRoot, options) {
|
|
|
24
35
|
// from a list of devices (connected or simulated) that are filtered by the scheme.
|
|
25
36
|
device,
|
|
26
37
|
buildCache: !!options.buildCache,
|
|
27
|
-
install: !!options.install
|
|
38
|
+
install: !!options.install,
|
|
39
|
+
buildCacheProvider
|
|
28
40
|
};
|
|
29
41
|
}
|
|
30
42
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/android/resolveOptions.ts"],"sourcesContent":["import { resolveDeviceAsync } from './resolveDevice';\nimport { GradleProps, resolveGradlePropsAsync } from './resolveGradlePropsAsync';\nimport { LaunchProps, resolveLaunchPropsAsync } from './resolveLaunchProps';\nimport { AndroidDeviceManager } from '../../start/platforms/android/AndroidDeviceManager';\nimport { BundlerProps, resolveBundlerPropsAsync } from '../resolveBundlerProps';\n\nexport type Options = {\n variant?: string;\n device?: boolean | string;\n port?: number;\n bundler?: boolean;\n install?: boolean;\n buildCache?: boolean;\n allArch?: boolean;\n binary?: string;\n appId?: string;\n};\n\nexport type ResolvedOptions = GradleProps &\n BundlerProps &\n LaunchProps & {\n variant: string;\n buildCache: boolean;\n device: AndroidDeviceManager;\n install: boolean;\n architectures?: string;\n appId?: string;\n };\n\nexport async function resolveOptionsAsync(\n projectRoot: string,\n options: Options\n): Promise<ResolvedOptions> {\n // Resolve the device before the gradle props because we need the device to be running to get the ABI.\n const device = await resolveDeviceAsync(options.device);\n\n return {\n ...(await resolveBundlerPropsAsync(projectRoot, options)),\n ...(await resolveGradlePropsAsync(projectRoot, options, device.device)),\n ...(await resolveLaunchPropsAsync(projectRoot, options)),\n variant: options.variant ?? 'debug',\n // Resolve the device based on the provided device id or prompt\n // from a list of devices (connected or simulated) that are filtered by the scheme.\n device,\n buildCache: !!options.buildCache,\n install: !!options.install,\n };\n}\n"],"names":["resolveOptionsAsync","projectRoot","options","device","resolveDeviceAsync","resolveBundlerPropsAsync","resolveGradlePropsAsync","resolveLaunchPropsAsync","variant","buildCache","install"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/android/resolveOptions.ts"],"sourcesContent":["import { BuildCacheProvider, getConfig } from '@expo/config';\n\nimport { resolveDeviceAsync } from './resolveDevice';\nimport { GradleProps, resolveGradlePropsAsync } from './resolveGradlePropsAsync';\nimport { LaunchProps, resolveLaunchPropsAsync } from './resolveLaunchProps';\nimport { AndroidDeviceManager } from '../../start/platforms/android/AndroidDeviceManager';\nimport { resolveBuildCacheProvider } from '../../utils/build-cache-providers';\nimport { BundlerProps, resolveBundlerPropsAsync } from '../resolveBundlerProps';\n\nexport type Options = {\n variant?: string;\n device?: boolean | string;\n port?: number;\n bundler?: boolean;\n install?: boolean;\n buildCache?: boolean;\n allArch?: boolean;\n binary?: string;\n appId?: string;\n};\n\nexport type ResolvedOptions = GradleProps &\n BundlerProps &\n LaunchProps & {\n variant: string;\n buildCache: boolean;\n device: AndroidDeviceManager;\n install: boolean;\n architectures?: string;\n appId?: string;\n buildCacheProvider?: BuildCacheProvider;\n };\n\nexport async function resolveOptionsAsync(\n projectRoot: string,\n options: Options\n): Promise<ResolvedOptions> {\n // Resolve the device before the gradle props because we need the device to be running to get the ABI.\n const device = await resolveDeviceAsync(options.device);\n\n const projectConfig = getConfig(projectRoot);\n const buildCacheProvider = await resolveBuildCacheProvider(\n projectConfig.exp.experiments?.buildCacheProvider ??\n projectConfig.exp.experiments?.remoteBuildCache?.provider,\n projectRoot\n );\n\n return {\n ...(await resolveBundlerPropsAsync(projectRoot, options)),\n ...(await resolveGradlePropsAsync(projectRoot, options, device.device)),\n ...(await resolveLaunchPropsAsync(projectRoot, options)),\n variant: options.variant ?? 'debug',\n // Resolve the device based on the provided device id or prompt\n // from a list of devices (connected or simulated) that are filtered by the scheme.\n device,\n buildCache: !!options.buildCache,\n install: !!options.install,\n buildCacheProvider,\n };\n}\n"],"names":["resolveOptionsAsync","projectRoot","options","projectConfig","device","resolveDeviceAsync","getConfig","buildCacheProvider","resolveBuildCacheProvider","exp","experiments","remoteBuildCache","provider","resolveBundlerPropsAsync","resolveGradlePropsAsync","resolveLaunchPropsAsync","variant","buildCache","install"],"mappings":";;;;+BAiCsBA;;;eAAAA;;;;yBAjCwB;;;;;;+BAEX;yCACkB;oCACA;qCAEX;qCACa;AA0BhD,eAAeA,oBACpBC,WAAmB,EACnBC,OAAgB;QAOdC,gCACEA,iDAAAA;IANJ,sGAAsG;IACtG,MAAMC,SAAS,MAAMC,IAAAA,iCAAkB,EAACH,QAAQE,MAAM;IAEtD,MAAMD,gBAAgBG,IAAAA,mBAAS,EAACL;IAChC,MAAMM,qBAAqB,MAAMC,IAAAA,8CAAyB,EACxDL,EAAAA,iCAAAA,cAAcM,GAAG,CAACC,WAAW,qBAA7BP,+BAA+BI,kBAAkB,OAC/CJ,kCAAAA,cAAcM,GAAG,CAACC,WAAW,sBAA7BP,kDAAAA,gCAA+BQ,gBAAgB,qBAA/CR,gDAAiDS,QAAQ,GAC3DX;IAGF,OAAO;QACL,GAAI,MAAMY,IAAAA,6CAAwB,EAACZ,aAAaC,QAAQ;QACxD,GAAI,MAAMY,IAAAA,gDAAuB,EAACb,aAAaC,SAASE,OAAOA,MAAM,CAAC;QACtE,GAAI,MAAMW,IAAAA,2CAAuB,EAACd,aAAaC,QAAQ;QACvDc,SAASd,QAAQc,OAAO,IAAI;QAC5B,+DAA+D;QAC/D,mFAAmF;QACnFZ;QACAa,YAAY,CAAC,CAACf,QAAQe,UAAU;QAChCC,SAAS,CAAC,CAAChB,QAAQgB,OAAO;QAC1BX;IACF;AACF"}
|
|
@@ -34,6 +34,7 @@ const _resolveOptions = require("./resolveOptions");
|
|
|
34
34
|
const _exportEager = require("../../export/embed/exportEager");
|
|
35
35
|
const _log = require("../../log");
|
|
36
36
|
const _gradle = require("../../start/platforms/android/gradle");
|
|
37
|
+
const _buildcacheproviders = require("../../utils/build-cache-providers");
|
|
37
38
|
const _errors = require("../../utils/errors");
|
|
38
39
|
const _nodeEnv = require("../../utils/nodeEnv");
|
|
39
40
|
const _port = require("../../utils/port");
|
|
@@ -58,9 +59,21 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
|
|
|
58
59
|
install
|
|
59
60
|
});
|
|
60
61
|
const props = await (0, _resolveOptions.resolveOptionsAsync)(projectRoot, options);
|
|
62
|
+
if (!options.binary && props.buildCacheProvider) {
|
|
63
|
+
const localPath = await (0, _buildcacheproviders.resolveBuildCache)({
|
|
64
|
+
projectRoot,
|
|
65
|
+
platform: 'android',
|
|
66
|
+
provider: props.buildCacheProvider,
|
|
67
|
+
runOptions: options
|
|
68
|
+
});
|
|
69
|
+
if (localPath) {
|
|
70
|
+
options.binary = localPath;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
61
73
|
debug('Package name: ' + props.packageName);
|
|
62
74
|
_log.Log.log('› Building app...');
|
|
63
75
|
const androidProjectRoot = _path().default.join(projectRoot, 'android');
|
|
76
|
+
let shouldUpdateBuildCache = false;
|
|
64
77
|
if (!options.binary) {
|
|
65
78
|
let eagerBundleOptions;
|
|
66
79
|
if (isProduction) {
|
|
@@ -77,6 +90,7 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
|
|
|
77
90
|
architectures: props.architectures,
|
|
78
91
|
eagerBundleOptions
|
|
79
92
|
});
|
|
93
|
+
shouldUpdateBuildCache = true;
|
|
80
94
|
// Ensure the port hasn't become busy during the build.
|
|
81
95
|
if (props.shouldStartBundler && !await (0, _port.ensurePortAvailabilityAsync)(projectRoot, props)) {
|
|
82
96
|
props.shouldStartBundler = false;
|
|
@@ -88,6 +102,14 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
|
|
|
88
102
|
scheme: (_this = await (0, _scheme.getSchemesForAndroidAsync)(projectRoot)) == null ? void 0 : _this[0],
|
|
89
103
|
headless: !props.shouldStartBundler
|
|
90
104
|
});
|
|
105
|
+
if (!options.binary) {
|
|
106
|
+
// Find the APK file path
|
|
107
|
+
const apkFile = await (0, _resolveInstallApkName.resolveInstallApkNameAsync)(props.device.device, props);
|
|
108
|
+
if (apkFile) {
|
|
109
|
+
// Attempt to install the APK from the file path
|
|
110
|
+
options.binary = _path().default.join(props.apkVariantDirectory, apkFile);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
91
113
|
if (options.binary) {
|
|
92
114
|
// Attempt to install the APK from the file path
|
|
93
115
|
const binaryPath = _path().default.join(options.binary);
|
|
@@ -111,25 +133,25 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
|
|
|
111
133
|
} else {
|
|
112
134
|
await manager.stopAsync();
|
|
113
135
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
_log.Log.log(_chalk().default.gray`\u203A Installing ${binaryPath}`);
|
|
122
|
-
await props.device.installAppAsync(binaryPath);
|
|
123
|
-
} else {
|
|
124
|
-
// If we cannot resolve the APK file path then we can attempt to install using Gradle.
|
|
125
|
-
// This offers more advanced resolution that we may not have first class support for.
|
|
126
|
-
_log.Log.log('› Failed to locate binary file, installing with Gradle...');
|
|
127
|
-
await (0, _gradle.installAsync)(androidProjectRoot, {
|
|
128
|
-
variant: props.variant ?? 'debug',
|
|
129
|
-
appName: props.appName ?? 'app',
|
|
130
|
-
port: props.port
|
|
136
|
+
if (options.binary && shouldUpdateBuildCache && props.buildCacheProvider) {
|
|
137
|
+
await (0, _buildcacheproviders.uploadBuildCache)({
|
|
138
|
+
projectRoot,
|
|
139
|
+
platform: 'android',
|
|
140
|
+
provider: props.buildCacheProvider,
|
|
141
|
+
buildPath: options.binary,
|
|
142
|
+
runOptions: options
|
|
131
143
|
});
|
|
132
144
|
}
|
|
133
145
|
}
|
|
146
|
+
async function installAppAsync(androidProjectRoot, props) {
|
|
147
|
+
// If we cannot resolve the APK file path then we can attempt to install using Gradle.
|
|
148
|
+
// This offers more advanced resolution that we may not have first class support for.
|
|
149
|
+
_log.Log.log('› Failed to locate binary file, installing with Gradle...');
|
|
150
|
+
await (0, _gradle.installAsync)(androidProjectRoot, {
|
|
151
|
+
variant: props.variant ?? 'debug',
|
|
152
|
+
appName: props.appName ?? 'app',
|
|
153
|
+
port: props.port
|
|
154
|
+
});
|
|
155
|
+
}
|
|
134
156
|
|
|
135
157
|
//# sourceMappingURL=runAndroidAsync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/android/runAndroidAsync.ts"],"sourcesContent":["import chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { resolveInstallApkNameAsync } from './resolveInstallApkName';\nimport { Options, ResolvedOptions, resolveOptionsAsync } from './resolveOptions';\nimport { exportEagerAsync } from '../../export/embed/exportEager';\nimport { Log } from '../../log';\nimport type { AndroidOpenInCustomProps } from '../../start/platforms/android/AndroidPlatformManager';\nimport { assembleAsync, installAsync } from '../../start/platforms/android/gradle';\nimport { CommandError } from '../../utils/errors';\nimport { setNodeEnv } from '../../utils/nodeEnv';\nimport { ensurePortAvailabilityAsync } from '../../utils/port';\nimport { getSchemesForAndroidAsync } from '../../utils/scheme';\nimport { ensureNativeProjectAsync } from '../ensureNativeProject';\nimport { logProjectLogsLocation } from '../hints';\nimport { startBundlerAsync } from '../startBundler';\n\nconst debug = require('debug')('expo:run:android');\n\nexport async function runAndroidAsync(projectRoot: string, { install, ...options }: Options) {\n // NOTE: This is a guess, the developer can overwrite with `NODE_ENV`.\n const isProduction = options.variant?.toLowerCase().endsWith('release');\n setNodeEnv(isProduction ? 'production' : 'development');\n require('@expo/env').load(projectRoot);\n\n await ensureNativeProjectAsync(projectRoot, { platform: 'android', install });\n\n const props = await resolveOptionsAsync(projectRoot, options);\n\n debug('Package name: ' + props.packageName);\n Log.log('› Building app...');\n\n const androidProjectRoot = path.join(projectRoot, 'android');\n\n if (!options.binary) {\n let eagerBundleOptions: string | undefined;\n\n if (isProduction) {\n eagerBundleOptions = JSON.stringify(\n await exportEagerAsync(projectRoot, {\n dev: false,\n platform: 'android',\n })\n );\n }\n\n await assembleAsync(androidProjectRoot, {\n variant: props.variant,\n port: props.port,\n appName: props.appName,\n buildCache: props.buildCache,\n architectures: props.architectures,\n eagerBundleOptions,\n });\n\n // Ensure the port hasn't become busy during the build.\n if (props.shouldStartBundler && !(await ensurePortAvailabilityAsync(projectRoot, props))) {\n props.shouldStartBundler = false;\n }\n }\n\n const manager = await startBundlerAsync(projectRoot, {\n port: props.port,\n // If a scheme is specified then use that instead of the package name.\n scheme: (await getSchemesForAndroidAsync(projectRoot))?.[0],\n headless: !props.shouldStartBundler,\n });\n\n if (options.binary) {\n // Attempt to install the APK from the file path\n const binaryPath = path.join(options.binary);\n\n if (!fs.existsSync(binaryPath)) {\n throw new CommandError(`The path to the custom Android binary does not exist: ${binaryPath}`);\n }\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n await props.device.installAppAsync(binaryPath);\n } else {\n await installAppAsync(androidProjectRoot, props);\n }\n\n await manager.getDefaultDevServer().openCustomRuntimeAsync<AndroidOpenInCustomProps>(\n 'emulator',\n {\n applicationId: props.packageName,\n customAppId: props.customAppId,\n launchActivity: props.launchActivity,\n },\n { device: props.device.device }\n );\n\n if (props.shouldStartBundler) {\n logProjectLogsLocation();\n } else {\n await manager.stopAsync();\n }\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/android/runAndroidAsync.ts"],"sourcesContent":["import chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { resolveInstallApkNameAsync } from './resolveInstallApkName';\nimport { Options, ResolvedOptions, resolveOptionsAsync } from './resolveOptions';\nimport { exportEagerAsync } from '../../export/embed/exportEager';\nimport { Log } from '../../log';\nimport type { AndroidOpenInCustomProps } from '../../start/platforms/android/AndroidPlatformManager';\nimport { assembleAsync, installAsync } from '../../start/platforms/android/gradle';\nimport { resolveBuildCache, uploadBuildCache } from '../../utils/build-cache-providers';\nimport { CommandError } from '../../utils/errors';\nimport { setNodeEnv } from '../../utils/nodeEnv';\nimport { ensurePortAvailabilityAsync } from '../../utils/port';\nimport { getSchemesForAndroidAsync } from '../../utils/scheme';\nimport { ensureNativeProjectAsync } from '../ensureNativeProject';\nimport { logProjectLogsLocation } from '../hints';\nimport { startBundlerAsync } from '../startBundler';\n\nconst debug = require('debug')('expo:run:android');\n\nexport async function runAndroidAsync(projectRoot: string, { install, ...options }: Options) {\n // NOTE: This is a guess, the developer can overwrite with `NODE_ENV`.\n const isProduction = options.variant?.toLowerCase().endsWith('release');\n setNodeEnv(isProduction ? 'production' : 'development');\n require('@expo/env').load(projectRoot);\n\n await ensureNativeProjectAsync(projectRoot, { platform: 'android', install });\n\n const props = await resolveOptionsAsync(projectRoot, options);\n\n if (!options.binary && props.buildCacheProvider) {\n const localPath = await resolveBuildCache({\n projectRoot,\n platform: 'android',\n provider: props.buildCacheProvider,\n runOptions: options,\n });\n if (localPath) {\n options.binary = localPath;\n }\n }\n\n debug('Package name: ' + props.packageName);\n Log.log('› Building app...');\n\n const androidProjectRoot = path.join(projectRoot, 'android');\n\n let shouldUpdateBuildCache = false;\n if (!options.binary) {\n let eagerBundleOptions: string | undefined;\n\n if (isProduction) {\n eagerBundleOptions = JSON.stringify(\n await exportEagerAsync(projectRoot, {\n dev: false,\n platform: 'android',\n })\n );\n }\n\n await assembleAsync(androidProjectRoot, {\n variant: props.variant,\n port: props.port,\n appName: props.appName,\n buildCache: props.buildCache,\n architectures: props.architectures,\n eagerBundleOptions,\n });\n shouldUpdateBuildCache = true;\n\n // Ensure the port hasn't become busy during the build.\n if (props.shouldStartBundler && !(await ensurePortAvailabilityAsync(projectRoot, props))) {\n props.shouldStartBundler = false;\n }\n }\n\n const manager = await startBundlerAsync(projectRoot, {\n port: props.port,\n // If a scheme is specified then use that instead of the package name.\n scheme: (await getSchemesForAndroidAsync(projectRoot))?.[0],\n headless: !props.shouldStartBundler,\n });\n\n if (!options.binary) {\n // Find the APK file path\n const apkFile = await resolveInstallApkNameAsync(props.device.device, props);\n if (apkFile) {\n // Attempt to install the APK from the file path\n options.binary = path.join(props.apkVariantDirectory, apkFile);\n }\n }\n\n if (options.binary) {\n // Attempt to install the APK from the file path\n const binaryPath = path.join(options.binary);\n\n if (!fs.existsSync(binaryPath)) {\n throw new CommandError(`The path to the custom Android binary does not exist: ${binaryPath}`);\n }\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n await props.device.installAppAsync(binaryPath);\n } else {\n await installAppAsync(androidProjectRoot, props);\n }\n\n await manager.getDefaultDevServer().openCustomRuntimeAsync<AndroidOpenInCustomProps>(\n 'emulator',\n {\n applicationId: props.packageName,\n customAppId: props.customAppId,\n launchActivity: props.launchActivity,\n },\n { device: props.device.device }\n );\n\n if (props.shouldStartBundler) {\n logProjectLogsLocation();\n } else {\n await manager.stopAsync();\n }\n\n if (options.binary && shouldUpdateBuildCache && props.buildCacheProvider) {\n await uploadBuildCache({\n projectRoot,\n platform: 'android',\n provider: props.buildCacheProvider,\n buildPath: options.binary,\n runOptions: options,\n });\n }\n}\n\nasync function installAppAsync(androidProjectRoot: string, props: ResolvedOptions) {\n // If we cannot resolve the APK file path then we can attempt to install using Gradle.\n // This offers more advanced resolution that we may not have first class support for.\n Log.log('› Failed to locate binary file, installing with Gradle...');\n await installAsync(androidProjectRoot, {\n variant: props.variant ?? 'debug',\n appName: props.appName ?? 'app',\n port: props.port,\n });\n}\n"],"names":["runAndroidAsync","debug","require","projectRoot","install","options","isProduction","variant","toLowerCase","endsWith","setNodeEnv","load","ensureNativeProjectAsync","platform","props","resolveOptionsAsync","binary","buildCacheProvider","localPath","resolveBuildCache","provider","runOptions","packageName","Log","log","androidProjectRoot","path","join","shouldUpdateBuildCache","eagerBundleOptions","JSON","stringify","exportEagerAsync","dev","assembleAsync","port","appName","buildCache","architectures","shouldStartBundler","ensurePortAvailabilityAsync","manager","startBundlerAsync","scheme","getSchemesForAndroidAsync","headless","apkFile","resolveInstallApkNameAsync","device","apkVariantDirectory","binaryPath","fs","existsSync","CommandError","chalk","gray","installAppAsync","getDefaultDevServer","openCustomRuntimeAsync","applicationId","customAppId","launchActivity","logProjectLogsLocation","stopAsync","uploadBuildCache","buildPath","installAsync"],"mappings":"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"}
|
|
@@ -139,7 +139,7 @@ function matchEstimatedBinaryPath(buildOutput) {
|
|
|
139
139
|
// Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`
|
|
140
140
|
const appBinaryPathMatch = buildOutput.match(/(\/(?:\\\s|[^ ])+\/Developer\/Xcode\/DerivedData\/(?:\\\s|[^ ])+\/Build\/Products\/(?:Debug|Release)-(?:[^\s/]+)\/(?:\\\s|[^ ])+\.app)/);
|
|
141
141
|
if (!(appBinaryPathMatch == null ? void 0 : appBinaryPathMatch.length)) {
|
|
142
|
-
throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: app binary path was not generated in build output.
|
|
142
|
+
throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: app binary path was not generated in build output. Report this issue and run your project with Xcode instead.`);
|
|
143
143
|
} else {
|
|
144
144
|
// Sort for the shortest
|
|
145
145
|
const shortestPath = appBinaryPathMatch.filter((a)=>typeof a === 'string' && a).sort((a, b)=>a.length - b.length)[0].trim();
|
|
@@ -181,7 +181,7 @@ function getEscapedPath(filePath) {
|
|
|
181
181
|
if (_fs().default.existsSync(unescapedPath)) {
|
|
182
182
|
return unescapedPath;
|
|
183
183
|
}
|
|
184
|
-
throw new _errors.CommandError('XCODE_BUILD', `Unexpected: Generated app at path "${filePath}" cannot be read, the app cannot be installed.
|
|
184
|
+
throw new _errors.CommandError('XCODE_BUILD', `Unexpected: Generated app at path "${filePath}" cannot be read, the app cannot be installed. Report this and build onto a simulator.`);
|
|
185
185
|
}
|
|
186
186
|
function extractEnvVariableFromBuild(buildOutput, variableName) {
|
|
187
187
|
// Xcode can sometimes escape `=` with a backslash or put the value in quotes
|
|
@@ -190,7 +190,7 @@ function extractEnvVariableFromBuild(buildOutput, variableName) {
|
|
|
190
190
|
...buildOutput.matchAll(reg)
|
|
191
191
|
];
|
|
192
192
|
if (!matched || !matched.length) {
|
|
193
|
-
throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: "${variableName}" variable was not generated in build output.
|
|
193
|
+
throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: "${variableName}" variable was not generated in build output. Report this issue and run your project with Xcode instead.`);
|
|
194
194
|
}
|
|
195
195
|
return matched.map((value)=>value[1]).filter(Boolean);
|
|
196
196
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/ios/XcodeBuild.ts"],"sourcesContent":["import { ExpoRunFormatter } from '@expo/xcpretty';\nimport chalk from 'chalk';\nimport { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport { BuildProps, ProjectInfo } from './XcodeBuild.types';\nimport { ensureDeviceIsCodeSignedForDeploymentAsync } from './codeSigning/configureCodeSigning';\nimport { simulatorBuildRequiresCodeSigning } from './codeSigning/simulatorCodeSigning';\nimport * as Log from '../../log';\nimport { ensureDirectory } from '../../utils/dir';\nimport { env } from '../../utils/env';\nimport { AbortCommandError, CommandError } from '../../utils/errors';\nimport { getUserTerminal } from '../../utils/terminal';\nexport function logPrettyItem(message: string) {\n Log.log(chalk`{whiteBright \\u203A} ${message}`);\n}\n\nexport function matchEstimatedBinaryPath(buildOutput: string): string | null {\n // Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`\n const appBinaryPathMatch = buildOutput.match(\n /(\\/(?:\\\\\\s|[^ ])+\\/Developer\\/Xcode\\/DerivedData\\/(?:\\\\\\s|[^ ])+\\/Build\\/Products\\/(?:Debug|Release)-(?:[^\\s/]+)\\/(?:\\\\\\s|[^ ])+\\.app)/\n );\n if (!appBinaryPathMatch?.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: app binary path was not generated in build output. Please report this issue and run your project with Xcode instead.`\n );\n } else {\n // Sort for the shortest\n const shortestPath = (appBinaryPathMatch.filter((a) => typeof a === 'string' && a) as string[])\n .sort((a: string, b: string) => a.length - b.length)[0]\n .trim();\n\n Log.debug(`Found app binary path: ${shortestPath}`);\n return shortestPath;\n }\n}\n/**\n *\n * @returns '/Users/evanbacon/Library/Developer/Xcode/DerivedData/myapp-gpgjqjodrxtervaufttwnsgimhrx/Build/Products/Debug-iphonesimulator/myapp.app'\n */\nexport function getAppBinaryPath(buildOutput: string) {\n // Matches what's used in \"Bundle React Native code and images\" script.\n // Requires that `-hideShellScriptEnvironment` is not included in the build command (extra logs).\n\n try {\n // Like `\\=/Users/evanbacon/Library/Developer/Xcode/DerivedData/Exponent-anpuosnglkxokahjhfszejloqfvo/Build/Products/Debug-iphonesimulator`\n const CONFIGURATION_BUILD_DIR = extractEnvVariableFromBuild(\n buildOutput,\n 'CONFIGURATION_BUILD_DIR'\n ).sort(\n // Longer name means more suffixes, we want the shortest possible one to be first.\n // Massive projects (like Expo Go) can sometimes print multiple different sets of environment variables.\n // This can become an issue with some\n (a, b) => a.length - b.length\n );\n // Like `Exponent.app`\n const UNLOCALIZED_RESOURCES_FOLDER_PATH = extractEnvVariableFromBuild(\n buildOutput,\n 'UNLOCALIZED_RESOURCES_FOLDER_PATH'\n );\n\n const binaryPath = path.join(\n // Use the shortest defined env variable (usually there's just one).\n CONFIGURATION_BUILD_DIR[0],\n // Use the last defined env variable.\n UNLOCALIZED_RESOURCES_FOLDER_PATH[UNLOCALIZED_RESOURCES_FOLDER_PATH.length - 1]\n );\n\n // If the app has a space in the name it'll fail because it isn't escaped properly by Xcode.\n return getEscapedPath(binaryPath);\n } catch (error) {\n if (error instanceof CommandError && error.code === 'XCODE_BUILD') {\n const possiblePath = matchEstimatedBinaryPath(buildOutput);\n if (possiblePath) {\n return possiblePath;\n }\n }\n throw error;\n }\n}\n\nexport function getEscapedPath(filePath: string): string {\n if (fs.existsSync(filePath)) {\n return filePath;\n }\n const unescapedPath = filePath.split(/\\\\ /).join(' ');\n if (fs.existsSync(unescapedPath)) {\n return unescapedPath;\n }\n throw new CommandError(\n 'XCODE_BUILD',\n `Unexpected: Generated app at path \"${filePath}\" cannot be read, the app cannot be installed. Please report this and build onto a simulator.`\n );\n}\n\nexport function extractEnvVariableFromBuild(buildOutput: string, variableName: string) {\n // Xcode can sometimes escape `=` with a backslash or put the value in quotes\n const reg = new RegExp(`export ${variableName}\\\\\\\\?=(.*)$`, 'mg');\n const matched = [...buildOutput.matchAll(reg)];\n\n if (!matched || !matched.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: \"${variableName}\" variable was not generated in build output. Please report this issue and run your project with Xcode instead.`\n );\n }\n return matched.map((value) => value[1]).filter(Boolean) as string[];\n}\n\nexport function getProcessOptions({\n packager,\n shouldSkipInitialBundling,\n terminal,\n port,\n eagerBundleOptions,\n}: {\n packager: boolean;\n shouldSkipInitialBundling?: boolean;\n terminal: string | undefined;\n port: number;\n eagerBundleOptions?: string;\n}): SpawnOptionsWithoutStdio {\n const SKIP_BUNDLING = shouldSkipInitialBundling ? '1' : undefined;\n if (packager) {\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n RCT_METRO_PORT: port.toString(),\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n },\n };\n }\n\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n // Always skip launching the packager from a build script.\n // The script is used for people building their project directly from Xcode.\n // This essentially means \"› Running script 'Start Packager'\" does nothing.\n RCT_NO_LAUNCH_PACKAGER: 'true',\n // FORCE_BUNDLING: '0'\n },\n };\n}\n\nexport async function getXcodeBuildArgsAsync(\n props: Pick<\n BuildProps,\n | 'buildCache'\n | 'projectRoot'\n | 'xcodeProject'\n | 'configuration'\n | 'scheme'\n | 'device'\n | 'isSimulator'\n >\n): Promise<string[]> {\n const args = [\n props.xcodeProject.isWorkspace ? '-workspace' : '-project',\n props.xcodeProject.name,\n '-configuration',\n props.configuration,\n '-scheme',\n props.scheme,\n '-destination',\n `id=${props.device.udid}`,\n ];\n\n if (!props.isSimulator || simulatorBuildRequiresCodeSigning(props.projectRoot)) {\n const developmentTeamId = await ensureDeviceIsCodeSignedForDeploymentAsync(props.projectRoot);\n if (developmentTeamId) {\n args.push(\n `DEVELOPMENT_TEAM=${developmentTeamId}`,\n '-allowProvisioningUpdates',\n '-allowProvisioningDeviceRegistration'\n );\n }\n }\n\n // Add last\n if (props.buildCache === false) {\n args.push(\n // Will first clean the derived data folder.\n 'clean',\n // Then build step must be added otherwise the process will simply clean and exit.\n 'build'\n );\n }\n return args;\n}\n\nfunction spawnXcodeBuild(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onData }: { onData: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n const buildProcess = spawn('xcodebuild', args, options);\n\n let results = '';\n let error = '';\n\n buildProcess.stdout.on('data', (data: Buffer) => {\n const stringData = data.toString();\n results += stringData;\n onData(stringData);\n });\n\n buildProcess.stderr.on('data', (data: Buffer) => {\n const stringData = data instanceof Buffer ? data.toString() : data;\n error += stringData;\n });\n\n return new Promise(async (resolve, reject) => {\n buildProcess.on('close', (code: number) => {\n resolve({ code, results, error });\n });\n });\n}\n\nasync function spawnXcodeBuildWithFlush(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onFlush }: { onFlush: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n let currentBuffer = '';\n\n // Data can be sent in chunks that would have no relevance to our regex\n // this can cause massive slowdowns, so we need to ensure the data is complete before attempting to parse it.\n function flushBuffer() {\n if (!currentBuffer) {\n return;\n }\n\n const data = currentBuffer;\n // Reset buffer.\n currentBuffer = '';\n // Process data.\n onFlush(data);\n }\n\n const data = await spawnXcodeBuild(args, options, {\n onData(stringData) {\n currentBuffer += stringData;\n // Only flush the data if we have a full line.\n if (currentBuffer.endsWith(os.EOL)) {\n flushBuffer();\n }\n },\n });\n\n // Flush log data at the end just in case we missed something.\n flushBuffer();\n return data;\n}\n\nasync function spawnXcodeBuildWithFormat(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { projectRoot, xcodeProject }: { projectRoot: string; xcodeProject: ProjectInfo }\n): Promise<{ code: number | null; results: string; error: string; formatter: ExpoRunFormatter }> {\n Log.debug(` xcodebuild ${args.join(' ')}`);\n\n logPrettyItem(chalk.bold`Planning build`);\n\n const formatter = ExpoRunFormatter.create(projectRoot, {\n xcodeProject,\n isDebug: env.EXPO_DEBUG,\n });\n\n const results = await spawnXcodeBuildWithFlush(args, options, {\n onFlush(data) {\n // Process data.\n for (const line of formatter.pipe(data)) {\n // Log parsed results.\n Log.log(line);\n }\n },\n });\n\n Log.debug(`Exited with code: ${results.code}`);\n\n if (\n // User cancelled with ctrl-c\n results.code === null ||\n // Build interrupted\n results.code === 75\n ) {\n throw new AbortCommandError();\n }\n\n Log.log(formatter.getBuildSummary());\n\n return { ...results, formatter };\n}\n\nexport async function buildAsync(props: BuildProps): Promise<string> {\n const args = await getXcodeBuildArgsAsync(props);\n\n const { projectRoot, xcodeProject, shouldSkipInitialBundling, port, eagerBundleOptions } = props;\n\n const { code, results, formatter, error } = await spawnXcodeBuildWithFormat(\n args,\n getProcessOptions({\n packager: false,\n terminal: getUserTerminal(),\n shouldSkipInitialBundling,\n port,\n eagerBundleOptions,\n }),\n {\n projectRoot,\n xcodeProject,\n }\n );\n\n const logFilePath = writeBuildLogs(projectRoot, results, error);\n\n if (code !== 0) {\n // Determine if the logger found any errors;\n const wasErrorPresented = !!formatter.errors.length;\n\n if (wasErrorPresented) {\n // This has a flaw, if the user is missing a file, and there is a script error, only the missing file error will be shown.\n // They will only see the script error if they fix the missing file and rerun.\n // The flaw can be fixed by catching script errors in the custom logger.\n throw new CommandError(\n `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`\n );\n }\n\n _assertXcodeBuildResults(code, results, error, xcodeProject, logFilePath);\n }\n return results;\n}\n\n// Exposed for testing.\nexport function _assertXcodeBuildResults(\n code: number | null,\n results: string,\n error: string,\n xcodeProject: { name: string },\n logFilePath: string\n): void {\n const errorTitle = `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`;\n\n const throwWithMessage = (message: string): never => {\n throw new CommandError(\n `${errorTitle}\\nTo view more error logs, try building the app with Xcode directly, by opening ${xcodeProject.name}.\\n\\n` +\n message +\n `Build logs written to ${chalk.underline(logFilePath)}`\n );\n };\n\n const localizedError = error.match(/NSLocalizedFailure = \"(.*)\"/)?.[1];\n\n if (localizedError) {\n throwWithMessage(chalk.bold(localizedError) + '\\n\\n');\n }\n // Show all the log info because often times the error is coming from a shell script,\n // that invoked a node script, that started metro, which threw an error.\n\n throwWithMessage(results + '\\n\\n' + error);\n}\n\nfunction writeBuildLogs(projectRoot: string, buildOutput: string, errorOutput: string) {\n const [logFilePath, errorFilePath] = getErrorLogFilePath(projectRoot);\n\n fs.writeFileSync(logFilePath, buildOutput);\n fs.writeFileSync(errorFilePath, errorOutput);\n return logFilePath;\n}\n\nfunction getErrorLogFilePath(projectRoot: string): [string, string] {\n const folder = path.join(projectRoot, '.expo');\n ensureDirectory(folder);\n return [path.join(folder, 'xcodebuild.log'), path.join(folder, 'xcodebuild-error.log')];\n}\n"],"names":["_assertXcodeBuildResults","buildAsync","extractEnvVariableFromBuild","getAppBinaryPath","getEscapedPath","getProcessOptions","getXcodeBuildArgsAsync","logPrettyItem","matchEstimatedBinaryPath","message","Log","log","chalk","buildOutput","appBinaryPathMatch","match","length","CommandError","shortestPath","filter","a","sort","b","trim","debug","CONFIGURATION_BUILD_DIR","UNLOCALIZED_RESOURCES_FOLDER_PATH","binaryPath","path","join","error","code","possiblePath","filePath","fs","existsSync","unescapedPath","split","variableName","reg","RegExp","matched","matchAll","map","value","Boolean","packager","shouldSkipInitialBundling","terminal","port","eagerBundleOptions","SKIP_BUNDLING","undefined","env","process","RCT_TERMINAL","RCT_METRO_PORT","toString","__EXPO_EAGER_BUNDLE_OPTIONS","RCT_NO_LAUNCH_PACKAGER","props","args","xcodeProject","isWorkspace","name","configuration","scheme","device","udid","isSimulator","simulatorBuildRequiresCodeSigning","projectRoot","developmentTeamId","ensureDeviceIsCodeSignedForDeploymentAsync","push","buildCache","spawnXcodeBuild","options","onData","buildProcess","spawn","results","stdout","on","data","stringData","stderr","Buffer","Promise","resolve","reject","spawnXcodeBuildWithFlush","onFlush","currentBuffer","flushBuffer","endsWith","os","EOL","spawnXcodeBuildWithFormat","bold","formatter","ExpoRunFormatter","create","isDebug","EXPO_DEBUG","line","pipe","AbortCommandError","getBuildSummary","getUserTerminal","logFilePath","writeBuildLogs","wasErrorPresented","errors","errorTitle","throwWithMessage","underline","localizedError","errorOutput","errorFilePath","getErrorLogFilePath","writeFileSync","folder","ensureDirectory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/ios/XcodeBuild.ts"],"sourcesContent":["import { ExpoRunFormatter } from '@expo/xcpretty';\nimport chalk from 'chalk';\nimport { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport { BuildProps, ProjectInfo } from './XcodeBuild.types';\nimport { ensureDeviceIsCodeSignedForDeploymentAsync } from './codeSigning/configureCodeSigning';\nimport { simulatorBuildRequiresCodeSigning } from './codeSigning/simulatorCodeSigning';\nimport * as Log from '../../log';\nimport { ensureDirectory } from '../../utils/dir';\nimport { env } from '../../utils/env';\nimport { AbortCommandError, CommandError } from '../../utils/errors';\nimport { getUserTerminal } from '../../utils/terminal';\nexport function logPrettyItem(message: string) {\n Log.log(chalk`{whiteBright \\u203A} ${message}`);\n}\n\nexport function matchEstimatedBinaryPath(buildOutput: string): string | null {\n // Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`\n const appBinaryPathMatch = buildOutput.match(\n /(\\/(?:\\\\\\s|[^ ])+\\/Developer\\/Xcode\\/DerivedData\\/(?:\\\\\\s|[^ ])+\\/Build\\/Products\\/(?:Debug|Release)-(?:[^\\s/]+)\\/(?:\\\\\\s|[^ ])+\\.app)/\n );\n if (!appBinaryPathMatch?.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: app binary path was not generated in build output. Report this issue and run your project with Xcode instead.`\n );\n } else {\n // Sort for the shortest\n const shortestPath = (appBinaryPathMatch.filter((a) => typeof a === 'string' && a) as string[])\n .sort((a: string, b: string) => a.length - b.length)[0]\n .trim();\n\n Log.debug(`Found app binary path: ${shortestPath}`);\n return shortestPath;\n }\n}\n/**\n *\n * @returns '/Users/evanbacon/Library/Developer/Xcode/DerivedData/myapp-gpgjqjodrxtervaufttwnsgimhrx/Build/Products/Debug-iphonesimulator/myapp.app'\n */\nexport function getAppBinaryPath(buildOutput: string) {\n // Matches what's used in \"Bundle React Native code and images\" script.\n // Requires that `-hideShellScriptEnvironment` is not included in the build command (extra logs).\n\n try {\n // Like `\\=/Users/evanbacon/Library/Developer/Xcode/DerivedData/Exponent-anpuosnglkxokahjhfszejloqfvo/Build/Products/Debug-iphonesimulator`\n const CONFIGURATION_BUILD_DIR = extractEnvVariableFromBuild(\n buildOutput,\n 'CONFIGURATION_BUILD_DIR'\n ).sort(\n // Longer name means more suffixes, we want the shortest possible one to be first.\n // Massive projects (like Expo Go) can sometimes print multiple different sets of environment variables.\n // This can become an issue with some\n (a, b) => a.length - b.length\n );\n // Like `Exponent.app`\n const UNLOCALIZED_RESOURCES_FOLDER_PATH = extractEnvVariableFromBuild(\n buildOutput,\n 'UNLOCALIZED_RESOURCES_FOLDER_PATH'\n );\n\n const binaryPath = path.join(\n // Use the shortest defined env variable (usually there's just one).\n CONFIGURATION_BUILD_DIR[0],\n // Use the last defined env variable.\n UNLOCALIZED_RESOURCES_FOLDER_PATH[UNLOCALIZED_RESOURCES_FOLDER_PATH.length - 1]\n );\n\n // If the app has a space in the name it'll fail because it isn't escaped properly by Xcode.\n return getEscapedPath(binaryPath);\n } catch (error) {\n if (error instanceof CommandError && error.code === 'XCODE_BUILD') {\n const possiblePath = matchEstimatedBinaryPath(buildOutput);\n if (possiblePath) {\n return possiblePath;\n }\n }\n throw error;\n }\n}\n\nexport function getEscapedPath(filePath: string): string {\n if (fs.existsSync(filePath)) {\n return filePath;\n }\n const unescapedPath = filePath.split(/\\\\ /).join(' ');\n if (fs.existsSync(unescapedPath)) {\n return unescapedPath;\n }\n throw new CommandError(\n 'XCODE_BUILD',\n `Unexpected: Generated app at path \"${filePath}\" cannot be read, the app cannot be installed. Report this and build onto a simulator.`\n );\n}\n\nexport function extractEnvVariableFromBuild(buildOutput: string, variableName: string) {\n // Xcode can sometimes escape `=` with a backslash or put the value in quotes\n const reg = new RegExp(`export ${variableName}\\\\\\\\?=(.*)$`, 'mg');\n const matched = [...buildOutput.matchAll(reg)];\n\n if (!matched || !matched.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: \"${variableName}\" variable was not generated in build output. Report this issue and run your project with Xcode instead.`\n );\n }\n return matched.map((value) => value[1]).filter(Boolean) as string[];\n}\n\nexport function getProcessOptions({\n packager,\n shouldSkipInitialBundling,\n terminal,\n port,\n eagerBundleOptions,\n}: {\n packager: boolean;\n shouldSkipInitialBundling?: boolean;\n terminal: string | undefined;\n port: number;\n eagerBundleOptions?: string;\n}): SpawnOptionsWithoutStdio {\n const SKIP_BUNDLING = shouldSkipInitialBundling ? '1' : undefined;\n if (packager) {\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n RCT_METRO_PORT: port.toString(),\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n },\n };\n }\n\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n // Always skip launching the packager from a build script.\n // The script is used for people building their project directly from Xcode.\n // This essentially means \"› Running script 'Start Packager'\" does nothing.\n RCT_NO_LAUNCH_PACKAGER: 'true',\n // FORCE_BUNDLING: '0'\n },\n };\n}\n\nexport async function getXcodeBuildArgsAsync(\n props: Pick<\n BuildProps,\n | 'buildCache'\n | 'projectRoot'\n | 'xcodeProject'\n | 'configuration'\n | 'scheme'\n | 'device'\n | 'isSimulator'\n >\n): Promise<string[]> {\n const args = [\n props.xcodeProject.isWorkspace ? '-workspace' : '-project',\n props.xcodeProject.name,\n '-configuration',\n props.configuration,\n '-scheme',\n props.scheme,\n '-destination',\n `id=${props.device.udid}`,\n ];\n\n if (!props.isSimulator || simulatorBuildRequiresCodeSigning(props.projectRoot)) {\n const developmentTeamId = await ensureDeviceIsCodeSignedForDeploymentAsync(props.projectRoot);\n if (developmentTeamId) {\n args.push(\n `DEVELOPMENT_TEAM=${developmentTeamId}`,\n '-allowProvisioningUpdates',\n '-allowProvisioningDeviceRegistration'\n );\n }\n }\n\n // Add last\n if (props.buildCache === false) {\n args.push(\n // Will first clean the derived data folder.\n 'clean',\n // Then build step must be added otherwise the process will simply clean and exit.\n 'build'\n );\n }\n return args;\n}\n\nfunction spawnXcodeBuild(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onData }: { onData: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n const buildProcess = spawn('xcodebuild', args, options);\n\n let results = '';\n let error = '';\n\n buildProcess.stdout.on('data', (data: Buffer) => {\n const stringData = data.toString();\n results += stringData;\n onData(stringData);\n });\n\n buildProcess.stderr.on('data', (data: Buffer) => {\n const stringData = data instanceof Buffer ? data.toString() : data;\n error += stringData;\n });\n\n return new Promise(async (resolve, reject) => {\n buildProcess.on('close', (code: number) => {\n resolve({ code, results, error });\n });\n });\n}\n\nasync function spawnXcodeBuildWithFlush(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onFlush }: { onFlush: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n let currentBuffer = '';\n\n // Data can be sent in chunks that would have no relevance to our regex\n // this can cause massive slowdowns, so we need to ensure the data is complete before attempting to parse it.\n function flushBuffer() {\n if (!currentBuffer) {\n return;\n }\n\n const data = currentBuffer;\n // Reset buffer.\n currentBuffer = '';\n // Process data.\n onFlush(data);\n }\n\n const data = await spawnXcodeBuild(args, options, {\n onData(stringData) {\n currentBuffer += stringData;\n // Only flush the data if we have a full line.\n if (currentBuffer.endsWith(os.EOL)) {\n flushBuffer();\n }\n },\n });\n\n // Flush log data at the end just in case we missed something.\n flushBuffer();\n return data;\n}\n\nasync function spawnXcodeBuildWithFormat(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { projectRoot, xcodeProject }: { projectRoot: string; xcodeProject: ProjectInfo }\n): Promise<{ code: number | null; results: string; error: string; formatter: ExpoRunFormatter }> {\n Log.debug(` xcodebuild ${args.join(' ')}`);\n\n logPrettyItem(chalk.bold`Planning build`);\n\n const formatter = ExpoRunFormatter.create(projectRoot, {\n xcodeProject,\n isDebug: env.EXPO_DEBUG,\n });\n\n const results = await spawnXcodeBuildWithFlush(args, options, {\n onFlush(data) {\n // Process data.\n for (const line of formatter.pipe(data)) {\n // Log parsed results.\n Log.log(line);\n }\n },\n });\n\n Log.debug(`Exited with code: ${results.code}`);\n\n if (\n // User cancelled with ctrl-c\n results.code === null ||\n // Build interrupted\n results.code === 75\n ) {\n throw new AbortCommandError();\n }\n\n Log.log(formatter.getBuildSummary());\n\n return { ...results, formatter };\n}\n\nexport async function buildAsync(props: BuildProps): Promise<string> {\n const args = await getXcodeBuildArgsAsync(props);\n\n const { projectRoot, xcodeProject, shouldSkipInitialBundling, port, eagerBundleOptions } = props;\n\n const { code, results, formatter, error } = await spawnXcodeBuildWithFormat(\n args,\n getProcessOptions({\n packager: false,\n terminal: getUserTerminal(),\n shouldSkipInitialBundling,\n port,\n eagerBundleOptions,\n }),\n {\n projectRoot,\n xcodeProject,\n }\n );\n\n const logFilePath = writeBuildLogs(projectRoot, results, error);\n\n if (code !== 0) {\n // Determine if the logger found any errors;\n const wasErrorPresented = !!formatter.errors.length;\n\n if (wasErrorPresented) {\n // This has a flaw, if the user is missing a file, and there is a script error, only the missing file error will be shown.\n // They will only see the script error if they fix the missing file and rerun.\n // The flaw can be fixed by catching script errors in the custom logger.\n throw new CommandError(\n `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`\n );\n }\n\n _assertXcodeBuildResults(code, results, error, xcodeProject, logFilePath);\n }\n return results;\n}\n\n// Exposed for testing.\nexport function _assertXcodeBuildResults(\n code: number | null,\n results: string,\n error: string,\n xcodeProject: { name: string },\n logFilePath: string\n): void {\n const errorTitle = `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`;\n\n const throwWithMessage = (message: string): never => {\n throw new CommandError(\n `${errorTitle}\\nTo view more error logs, try building the app with Xcode directly, by opening ${xcodeProject.name}.\\n\\n` +\n message +\n `Build logs written to ${chalk.underline(logFilePath)}`\n );\n };\n\n const localizedError = error.match(/NSLocalizedFailure = \"(.*)\"/)?.[1];\n\n if (localizedError) {\n throwWithMessage(chalk.bold(localizedError) + '\\n\\n');\n }\n // Show all the log info because often times the error is coming from a shell script,\n // that invoked a node script, that started metro, which threw an error.\n\n throwWithMessage(results + '\\n\\n' + error);\n}\n\nfunction writeBuildLogs(projectRoot: string, buildOutput: string, errorOutput: string) {\n const [logFilePath, errorFilePath] = getErrorLogFilePath(projectRoot);\n\n fs.writeFileSync(logFilePath, buildOutput);\n fs.writeFileSync(errorFilePath, errorOutput);\n return logFilePath;\n}\n\nfunction getErrorLogFilePath(projectRoot: string): [string, string] {\n const folder = path.join(projectRoot, '.expo');\n ensureDirectory(folder);\n return [path.join(folder, 'xcodebuild.log'), path.join(folder, 'xcodebuild-error.log')];\n}\n"],"names":["_assertXcodeBuildResults","buildAsync","extractEnvVariableFromBuild","getAppBinaryPath","getEscapedPath","getProcessOptions","getXcodeBuildArgsAsync","logPrettyItem","matchEstimatedBinaryPath","message","Log","log","chalk","buildOutput","appBinaryPathMatch","match","length","CommandError","shortestPath","filter","a","sort","b","trim","debug","CONFIGURATION_BUILD_DIR","UNLOCALIZED_RESOURCES_FOLDER_PATH","binaryPath","path","join","error","code","possiblePath","filePath","fs","existsSync","unescapedPath","split","variableName","reg","RegExp","matched","matchAll","map","value","Boolean","packager","shouldSkipInitialBundling","terminal","port","eagerBundleOptions","SKIP_BUNDLING","undefined","env","process","RCT_TERMINAL","RCT_METRO_PORT","toString","__EXPO_EAGER_BUNDLE_OPTIONS","RCT_NO_LAUNCH_PACKAGER","props","args","xcodeProject","isWorkspace","name","configuration","scheme","device","udid","isSimulator","simulatorBuildRequiresCodeSigning","projectRoot","developmentTeamId","ensureDeviceIsCodeSignedForDeploymentAsync","push","buildCache","spawnXcodeBuild","options","onData","buildProcess","spawn","results","stdout","on","data","stringData","stderr","Buffer","Promise","resolve","reject","spawnXcodeBuildWithFlush","onFlush","currentBuffer","flushBuffer","endsWith","os","EOL","spawnXcodeBuildWithFormat","bold","formatter","ExpoRunFormatter","create","isDebug","EXPO_DEBUG","line","pipe","AbortCommandError","getBuildSummary","getUserTerminal","logFilePath","writeBuildLogs","wasErrorPresented","errors","errorTitle","throwWithMessage","underline","localizedError","errorOutput","errorFilePath","getErrorLogFilePath","writeFileSync","folder","ensureDirectory"],"mappings":"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"}
|
|
@@ -8,13 +8,22 @@ Object.defineProperty(exports, "resolveOptionsAsync", {
|
|
|
8
8
|
return resolveOptionsAsync;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
function _config() {
|
|
12
|
+
const data = require("@expo/config");
|
|
13
|
+
_config = function() {
|
|
14
|
+
return data;
|
|
15
|
+
};
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
11
18
|
const _resolveDevice = require("./resolveDevice");
|
|
12
19
|
const _resolveNativeScheme = require("./resolveNativeScheme");
|
|
13
20
|
const _resolveXcodeProject = require("./resolveXcodeProject");
|
|
14
21
|
const _simctl = require("../../../start/platforms/ios/simctl");
|
|
22
|
+
const _buildcacheproviders = require("../../../utils/build-cache-providers");
|
|
15
23
|
const _profile = require("../../../utils/profile");
|
|
16
24
|
const _resolveBundlerProps = require("../../resolveBundlerProps");
|
|
17
25
|
async function resolveOptionsAsync(projectRoot, options) {
|
|
26
|
+
var _projectConfig_exp_experiments, _projectConfig_exp_experiments_remoteBuildCache, _projectConfig_exp_experiments1;
|
|
18
27
|
const xcodeProject = (0, _resolveXcodeProject.resolveXcodeProject)(projectRoot);
|
|
19
28
|
const bundlerProps = await (0, _resolveBundlerProps.resolveBundlerPropsAsync)(projectRoot, options);
|
|
20
29
|
// Resolve the scheme before the device so we can filter devices based on
|
|
@@ -32,6 +41,8 @@ async function resolveOptionsAsync(projectRoot, options) {
|
|
|
32
41
|
configuration
|
|
33
42
|
});
|
|
34
43
|
const isSimulator = (0, _resolveDevice.isSimulatorDevice)(device);
|
|
44
|
+
const projectConfig = (0, _config().getConfig)(projectRoot);
|
|
45
|
+
const buildCacheProvider = await (0, _buildcacheproviders.resolveBuildCacheProvider)(((_projectConfig_exp_experiments = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments.buildCacheProvider) ?? ((_projectConfig_exp_experiments1 = projectConfig.exp.experiments) == null ? void 0 : (_projectConfig_exp_experiments_remoteBuildCache = _projectConfig_exp_experiments1.remoteBuildCache) == null ? void 0 : _projectConfig_exp_experiments_remoteBuildCache.provider), projectRoot);
|
|
35
46
|
// This optimization skips resetting the Metro cache needlessly.
|
|
36
47
|
// The cache is reset in `../node_modules/react-native/scripts/react-native-xcode.sh` when the
|
|
37
48
|
// project is running in Debug and built onto a physical device. It seems that this is done because
|
|
@@ -47,7 +58,8 @@ async function resolveOptionsAsync(projectRoot, options) {
|
|
|
47
58
|
configuration,
|
|
48
59
|
shouldSkipInitialBundling,
|
|
49
60
|
buildCache: options.buildCache !== false,
|
|
50
|
-
scheme
|
|
61
|
+
scheme,
|
|
62
|
+
buildCacheProvider
|
|
51
63
|
};
|
|
52
64
|
}
|
|
53
65
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/run/ios/options/resolveOptions.ts"],"sourcesContent":["import { isSimulatorDevice, resolveDeviceAsync } from './resolveDevice';\nimport { resolveNativeSchemePropsAsync } from './resolveNativeScheme';\nimport { resolveXcodeProject } from './resolveXcodeProject';\nimport { isOSType } from '../../../start/platforms/ios/simctl';\nimport { profile } from '../../../utils/profile';\nimport { resolveBundlerPropsAsync } from '../../resolveBundlerProps';\nimport { BuildProps, Options } from '../XcodeBuild.types';\n\n/** Resolve arguments for the `run:ios` command. */\nexport async function resolveOptionsAsync(\n projectRoot: string,\n options: Options\n): Promise<BuildProps> {\n const xcodeProject = resolveXcodeProject(projectRoot);\n\n const bundlerProps = await resolveBundlerPropsAsync(projectRoot, options);\n\n // Resolve the scheme before the device so we can filter devices based on\n // whichever scheme is selected (i.e. don't present TV devices if the scheme cannot be run on a TV).\n const { osType, name: scheme } = await resolveNativeSchemePropsAsync(\n projectRoot,\n options,\n xcodeProject\n );\n\n // Use the configuration or `Debug` if none is provided.\n const configuration = options.configuration || 'Debug';\n\n // Resolve the device based on the provided device id or prompt\n // from a list of devices (connected or simulated) that are filtered by the scheme.\n const device = await profile(resolveDeviceAsync)(options.device, {\n // It's unclear if there's any value to asserting that we haven't hardcoded the os type in the CLI.\n osType: isOSType(osType) ? osType : undefined,\n xcodeProject,\n scheme,\n configuration,\n });\n\n const isSimulator = isSimulatorDevice(device);\n\n // This optimization skips resetting the Metro cache needlessly.\n // The cache is reset in `../node_modules/react-native/scripts/react-native-xcode.sh` when the\n // project is running in Debug and built onto a physical device. It seems that this is done because\n // the script is run from Xcode and unaware of the CLI instance.\n const shouldSkipInitialBundling = configuration === 'Debug' && !isSimulator;\n\n return {\n ...bundlerProps,\n shouldStartBundler: options.configuration === 'Debug' || bundlerProps.shouldStartBundler,\n projectRoot,\n isSimulator,\n xcodeProject,\n device,\n configuration,\n shouldSkipInitialBundling,\n buildCache: options.buildCache !== false,\n scheme,\n };\n}\n"],"names":["resolveOptionsAsync","projectRoot","options","xcodeProject","resolveXcodeProject","bundlerProps","resolveBundlerPropsAsync","osType","name","scheme","resolveNativeSchemePropsAsync","configuration","device","profile","resolveDeviceAsync","isOSType","undefined","isSimulator","isSimulatorDevice","shouldSkipInitialBundling","shouldStartBundler","buildCache"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["../../../../../src/run/ios/options/resolveOptions.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\n\nimport { isSimulatorDevice, resolveDeviceAsync } from './resolveDevice';\nimport { resolveNativeSchemePropsAsync } from './resolveNativeScheme';\nimport { resolveXcodeProject } from './resolveXcodeProject';\nimport { isOSType } from '../../../start/platforms/ios/simctl';\nimport { resolveBuildCacheProvider } from '../../../utils/build-cache-providers';\nimport { profile } from '../../../utils/profile';\nimport { resolveBundlerPropsAsync } from '../../resolveBundlerProps';\nimport { BuildProps, Options } from '../XcodeBuild.types';\n\n/** Resolve arguments for the `run:ios` command. */\nexport async function resolveOptionsAsync(\n projectRoot: string,\n options: Options\n): Promise<BuildProps> {\n const xcodeProject = resolveXcodeProject(projectRoot);\n\n const bundlerProps = await resolveBundlerPropsAsync(projectRoot, options);\n\n // Resolve the scheme before the device so we can filter devices based on\n // whichever scheme is selected (i.e. don't present TV devices if the scheme cannot be run on a TV).\n const { osType, name: scheme } = await resolveNativeSchemePropsAsync(\n projectRoot,\n options,\n xcodeProject\n );\n\n // Use the configuration or `Debug` if none is provided.\n const configuration = options.configuration || 'Debug';\n\n // Resolve the device based on the provided device id or prompt\n // from a list of devices (connected or simulated) that are filtered by the scheme.\n const device = await profile(resolveDeviceAsync)(options.device, {\n // It's unclear if there's any value to asserting that we haven't hardcoded the os type in the CLI.\n osType: isOSType(osType) ? osType : undefined,\n xcodeProject,\n scheme,\n configuration,\n });\n\n const isSimulator = isSimulatorDevice(device);\n\n const projectConfig = getConfig(projectRoot);\n const buildCacheProvider = await resolveBuildCacheProvider(\n projectConfig.exp.experiments?.buildCacheProvider ??\n projectConfig.exp.experiments?.remoteBuildCache?.provider,\n projectRoot\n );\n\n // This optimization skips resetting the Metro cache needlessly.\n // The cache is reset in `../node_modules/react-native/scripts/react-native-xcode.sh` when the\n // project is running in Debug and built onto a physical device. It seems that this is done because\n // the script is run from Xcode and unaware of the CLI instance.\n const shouldSkipInitialBundling = configuration === 'Debug' && !isSimulator;\n\n return {\n ...bundlerProps,\n shouldStartBundler: options.configuration === 'Debug' || bundlerProps.shouldStartBundler,\n projectRoot,\n isSimulator,\n xcodeProject,\n device,\n configuration,\n shouldSkipInitialBundling,\n buildCache: options.buildCache !== false,\n scheme,\n buildCacheProvider,\n };\n}\n"],"names":["resolveOptionsAsync","projectRoot","options","projectConfig","xcodeProject","resolveXcodeProject","bundlerProps","resolveBundlerPropsAsync","osType","name","scheme","resolveNativeSchemePropsAsync","configuration","device","profile","resolveDeviceAsync","isOSType","undefined","isSimulator","isSimulatorDevice","getConfig","buildCacheProvider","resolveBuildCacheProvider","exp","experiments","remoteBuildCache","provider","shouldSkipInitialBundling","shouldStartBundler","buildCache"],"mappings":";;;;+BAYsBA;;;eAAAA;;;;yBAZI;;;;;;+BAE4B;qCACR;qCACV;wBACX;qCACiB;yBAClB;qCACiB;AAIlC,eAAeA,oBACpBC,WAAmB,EACnBC,OAAgB;QA+BdC,gCACEA,iDAAAA;IA9BJ,MAAMC,eAAeC,IAAAA,wCAAmB,EAACJ;IAEzC,MAAMK,eAAe,MAAMC,IAAAA,6CAAwB,EAACN,aAAaC;IAEjE,yEAAyE;IACzE,oGAAoG;IACpG,MAAM,EAAEM,MAAM,EAAEC,MAAMC,MAAM,EAAE,GAAG,MAAMC,IAAAA,kDAA6B,EAClEV,aACAC,SACAE;IAGF,wDAAwD;IACxD,MAAMQ,gBAAgBV,QAAQU,aAAa,IAAI;IAE/C,+DAA+D;IAC/D,mFAAmF;IACnF,MAAMC,SAAS,MAAMC,IAAAA,gBAAO,EAACC,iCAAkB,EAAEb,QAAQW,MAAM,EAAE;QAC/D,mGAAmG;QACnGL,QAAQQ,IAAAA,gBAAQ,EAACR,UAAUA,SAASS;QACpCb;QACAM;QACAE;IACF;IAEA,MAAMM,cAAcC,IAAAA,gCAAiB,EAACN;IAEtC,MAAMV,gBAAgBiB,IAAAA,mBAAS,EAACnB;IAChC,MAAMoB,qBAAqB,MAAMC,IAAAA,8CAAyB,EACxDnB,EAAAA,iCAAAA,cAAcoB,GAAG,CAACC,WAAW,qBAA7BrB,+BAA+BkB,kBAAkB,OAC/ClB,kCAAAA,cAAcoB,GAAG,CAACC,WAAW,sBAA7BrB,kDAAAA,gCAA+BsB,gBAAgB,qBAA/CtB,gDAAiDuB,QAAQ,GAC3DzB;IAGF,gEAAgE;IAChE,8FAA8F;IAC9F,mGAAmG;IACnG,gEAAgE;IAChE,MAAM0B,4BAA4Bf,kBAAkB,WAAW,CAACM;IAEhE,OAAO;QACL,GAAGZ,YAAY;QACfsB,oBAAoB1B,QAAQU,aAAa,KAAK,WAAWN,aAAasB,kBAAkB;QACxF3B;QACAiB;QACAd;QACAS;QACAD;QACAe;QACAE,YAAY3B,QAAQ2B,UAAU,KAAK;QACnCnB;QACAW;IACF;AACF"}
|