@expo/build-tools 1.0.63 → 1.0.64
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/dist/steps/functions/installMaestro.js +40 -26
- package/dist/steps/functions/installMaestro.js.map +1 -1
- package/dist/steps/functions/startAndroidEmulator.js +11 -6
- package/dist/steps/functions/startAndroidEmulator.js.map +1 -1
- package/dist/steps/functions/startIosSimulator.js +14 -10
- package/dist/steps/functions/startIosSimulator.js.map +1 -1
- package/package.json +2 -2
|
@@ -23,11 +23,11 @@ function createInstallMaestroBuildFunction() {
|
|
|
23
23
|
],
|
|
24
24
|
fn: async ({ logger, global }, { inputs, env }) => {
|
|
25
25
|
const requestedMaestroVersion = inputs.maestro_version.value;
|
|
26
|
-
const currentMaestroVersion = await getMaestroVersion();
|
|
26
|
+
const currentMaestroVersion = await getMaestroVersion({ env });
|
|
27
27
|
// When not running in EAS Build VM, do not modify local environment.
|
|
28
28
|
if (env.EAS_BUILD_RUNNER !== 'eas-build') {
|
|
29
|
-
const currentIsJavaInstalled = await isJavaInstalled();
|
|
30
|
-
const currentIsIdbInstalled = await isIdbInstalled();
|
|
29
|
+
const currentIsJavaInstalled = await isJavaInstalled({ env });
|
|
30
|
+
const currentIsIdbInstalled = await isIdbInstalled({ env });
|
|
31
31
|
if (!currentIsJavaInstalled) {
|
|
32
32
|
logger.warn('It seems Java is not installed. It is required to run Maestro. If the job fails, this may be the reason.');
|
|
33
33
|
logger.info('');
|
|
@@ -49,10 +49,10 @@ function createInstallMaestroBuildFunction() {
|
|
|
49
49
|
}
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
|
-
if (!(await isJavaInstalled())) {
|
|
52
|
+
if (!(await isJavaInstalled({ env }))) {
|
|
53
53
|
if (global.runtimePlatform === steps_1.BuildRuntimePlatform.DARWIN) {
|
|
54
54
|
logger.info('Installing Java');
|
|
55
|
-
await installJavaFromGcs({ logger });
|
|
55
|
+
await installJavaFromGcs({ logger, env });
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
// We expect Java to be pre-installed on Linux images,
|
|
@@ -62,9 +62,10 @@ function createInstallMaestroBuildFunction() {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
// IDB is only a requirement on macOS.
|
|
65
|
-
if (global.runtimePlatform === steps_1.BuildRuntimePlatform.DARWIN &&
|
|
65
|
+
if (global.runtimePlatform === steps_1.BuildRuntimePlatform.DARWIN &&
|
|
66
|
+
!(await isIdbInstalled({ env }))) {
|
|
66
67
|
logger.info('Installing IDB');
|
|
67
|
-
await installIdbFromBrew({
|
|
68
|
+
await installIdbFromBrew({ logger, env });
|
|
68
69
|
}
|
|
69
70
|
// Skip installing if the input sets a specific Maestro version to install
|
|
70
71
|
// and it is already installed which happens when developing on a local computer.
|
|
@@ -73,25 +74,26 @@ function createInstallMaestroBuildFunction() {
|
|
|
73
74
|
version: requestedMaestroVersion,
|
|
74
75
|
global,
|
|
75
76
|
logger,
|
|
77
|
+
env,
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
|
-
const maestroVersion = await getMaestroVersion();
|
|
80
|
+
const maestroVersion = await getMaestroVersion({ env });
|
|
79
81
|
(0, assert_1.default)(maestroVersion, 'Failed to ensure Maestro is installed.');
|
|
80
82
|
logger.info(`Maestro ${maestroVersion} is ready.`);
|
|
81
83
|
},
|
|
82
84
|
});
|
|
83
85
|
}
|
|
84
86
|
exports.createInstallMaestroBuildFunction = createInstallMaestroBuildFunction;
|
|
85
|
-
async function getMaestroVersion() {
|
|
87
|
+
async function getMaestroVersion({ env }) {
|
|
86
88
|
try {
|
|
87
|
-
const maestroVersion = await (0, turtle_spawn_1.default)('maestro', ['--version'], { stdio: 'pipe' });
|
|
89
|
+
const maestroVersion = await (0, turtle_spawn_1.default)('maestro', ['--version'], { stdio: 'pipe', env });
|
|
88
90
|
return maestroVersion.stdout.trim();
|
|
89
91
|
}
|
|
90
92
|
catch {
|
|
91
93
|
return null;
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
|
-
async function installMaestro({ global, version, logger, }) {
|
|
96
|
+
async function installMaestro({ global, version, logger, env, }) {
|
|
95
97
|
logger.info('Fetching install script');
|
|
96
98
|
const tempDirectory = await fs_extra_1.default.mkdtemp('install_maestro');
|
|
97
99
|
try {
|
|
@@ -102,47 +104,59 @@ async function installMaestro({ global, version, logger, }) {
|
|
|
102
104
|
mode: 0o777,
|
|
103
105
|
});
|
|
104
106
|
logger.info('Installing Maestro');
|
|
107
|
+
(0, assert_1.default)(env.HOME, 'Failed to infer directory to install Maestro in: $HOME environment variable is empty.');
|
|
108
|
+
const maestroDir = path_1.default.join(env.HOME, '.maestro');
|
|
105
109
|
await (0, turtle_spawn_1.default)(installMaestroScriptFilePath, [], {
|
|
106
110
|
logger,
|
|
107
111
|
env: {
|
|
108
|
-
...
|
|
112
|
+
...env,
|
|
113
|
+
MAESTRO_DIR: maestroDir,
|
|
109
114
|
MAESTRO_VERSION: version,
|
|
110
115
|
},
|
|
111
116
|
});
|
|
117
|
+
// That's where Maestro installs binary as of February 2024
|
|
118
|
+
// I suspect/hope they don't change the location.
|
|
119
|
+
const maestroBinDir = path_1.default.join(maestroDir, 'bin');
|
|
120
|
+
global.updateEnv({
|
|
121
|
+
...global.env,
|
|
122
|
+
PATH: `${global.env.PATH}:${maestroBinDir}`,
|
|
123
|
+
});
|
|
124
|
+
env.PATH = `${env.PATH}:${maestroBinDir}`;
|
|
125
|
+
process.env.PATH = `${process.env.PATH}:${maestroBinDir}`;
|
|
112
126
|
}
|
|
113
127
|
finally {
|
|
114
128
|
await fs_extra_1.default.remove(tempDirectory);
|
|
115
129
|
}
|
|
116
130
|
}
|
|
117
|
-
async function isIdbInstalled() {
|
|
131
|
+
async function isIdbInstalled({ env }) {
|
|
118
132
|
try {
|
|
119
|
-
await (0, turtle_spawn_1.default)('idb', ['-h'], { ignoreStdio: true });
|
|
133
|
+
await (0, turtle_spawn_1.default)('idb', ['-h'], { ignoreStdio: true, env });
|
|
120
134
|
return true;
|
|
121
135
|
}
|
|
122
136
|
catch {
|
|
123
137
|
return false;
|
|
124
138
|
}
|
|
125
139
|
}
|
|
126
|
-
async function installIdbFromBrew({
|
|
140
|
+
async function installIdbFromBrew({ logger, env, }) {
|
|
127
141
|
// Unfortunately our Mac images sometimes have two Homebrew
|
|
128
142
|
// installations. We should use the ARM64 one, located in /opt/homebrew.
|
|
129
143
|
const brewPath = '/opt/homebrew/bin/brew';
|
|
130
|
-
const
|
|
131
|
-
...
|
|
144
|
+
const localEnv = {
|
|
145
|
+
...env,
|
|
132
146
|
HOMEBREW_NO_AUTO_UPDATE: '1',
|
|
133
147
|
};
|
|
134
148
|
await (0, turtle_spawn_1.default)(brewPath, ['tap', 'facebook/fb'], {
|
|
135
|
-
env,
|
|
149
|
+
env: localEnv,
|
|
136
150
|
logger,
|
|
137
151
|
});
|
|
138
152
|
await (0, turtle_spawn_1.default)(brewPath, ['install', 'idb-companion'], {
|
|
139
|
-
env,
|
|
153
|
+
env: localEnv,
|
|
140
154
|
logger,
|
|
141
155
|
});
|
|
142
156
|
}
|
|
143
|
-
async function isJavaInstalled() {
|
|
157
|
+
async function isJavaInstalled({ env }) {
|
|
144
158
|
try {
|
|
145
|
-
await (0, turtle_spawn_1.default)('java', ['-version'], { ignoreStdio: true });
|
|
159
|
+
await (0, turtle_spawn_1.default)('java', ['-version'], { ignoreStdio: true, env });
|
|
146
160
|
return true;
|
|
147
161
|
}
|
|
148
162
|
catch {
|
|
@@ -153,7 +167,7 @@ async function isJavaInstalled() {
|
|
|
153
167
|
* Installs Java 11 from a file uploaded manually to GCS as cache.
|
|
154
168
|
* Should not be run outside of EAS Build VMs not to break users' environments.
|
|
155
169
|
*/
|
|
156
|
-
async function installJavaFromGcs({ logger }) {
|
|
170
|
+
async function installJavaFromGcs({ logger, env, }) {
|
|
157
171
|
const downloadUrl = 'https://storage.googleapis.com/turtle-v2/zulu11.68.17-ca-jdk11.0.21-macosx_aarch64.dmg';
|
|
158
172
|
const filename = path_1.default.basename(downloadUrl);
|
|
159
173
|
const tempDirectory = await fs_extra_1.default.mkdtemp('install_java');
|
|
@@ -162,10 +176,10 @@ async function installJavaFromGcs({ logger }) {
|
|
|
162
176
|
try {
|
|
163
177
|
logger.info('Downloading Java installer');
|
|
164
178
|
// This is simpler than piping body into a write stream with node-fetch.
|
|
165
|
-
await (0, turtle_spawn_1.default)('curl', ['--output', installerPath, downloadUrl]);
|
|
179
|
+
await (0, turtle_spawn_1.default)('curl', ['--output', installerPath, downloadUrl], { env });
|
|
166
180
|
await fs_extra_1.default.mkdir(installerMountDirectory);
|
|
167
181
|
logger.info('Mounting Java installer');
|
|
168
|
-
await (0, turtle_spawn_1.default)('hdiutil', ['attach', installerPath, '-noverify', '-mountpoint', installerMountDirectory], { logger });
|
|
182
|
+
await (0, turtle_spawn_1.default)('hdiutil', ['attach', installerPath, '-noverify', '-mountpoint', installerMountDirectory], { logger, env });
|
|
169
183
|
logger.info('Installing Java');
|
|
170
184
|
await (0, turtle_spawn_1.default)('sudo', [
|
|
171
185
|
'installer',
|
|
@@ -173,12 +187,12 @@ async function installJavaFromGcs({ logger }) {
|
|
|
173
187
|
path_1.default.join(installerMountDirectory, 'Double-Click to Install Azul Zulu JDK 11.pkg'),
|
|
174
188
|
'-target',
|
|
175
189
|
'/',
|
|
176
|
-
], { logger });
|
|
190
|
+
], { logger, env });
|
|
177
191
|
}
|
|
178
192
|
finally {
|
|
179
193
|
try {
|
|
180
194
|
// We need to unmount to remove, otherwise we get "resource busy"
|
|
181
|
-
await (0, turtle_spawn_1.default)('hdiutil', ['detach', installerMountDirectory]);
|
|
195
|
+
await (0, turtle_spawn_1.default)('hdiutil', ['detach', installerMountDirectory], { env });
|
|
182
196
|
}
|
|
183
197
|
catch { }
|
|
184
198
|
await fs_extra_1.default.remove(tempDirectory);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installMaestro.js","sourceRoot":"","sources":["../../../src/steps/functions/installMaestro.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport path from 'path';\n\nimport fs from 'fs-extra';\nimport {\n BuildFunction,\n BuildRuntimePlatform,\n BuildStepGlobalContext,\n BuildStepInput,\n BuildStepInputValueTypeName,\n} from '@expo/steps';\nimport spawn from '@expo/turtle-spawn';\nimport { bunyan } from '@expo/logger';\n\nexport function createInstallMaestroBuildFunction(): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'install_maestro',\n name: 'Install Maestro',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'maestro_version',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async ({ logger, global }, { inputs, env }) => {\n const requestedMaestroVersion = inputs.maestro_version.value as string | undefined;\n const currentMaestroVersion = await getMaestroVersion();\n\n // When not running in EAS Build VM, do not modify local environment.\n if (env.EAS_BUILD_RUNNER !== 'eas-build') {\n const currentIsJavaInstalled = await isJavaInstalled();\n const currentIsIdbInstalled = await isIdbInstalled();\n\n if (!currentIsJavaInstalled) {\n logger.warn(\n 'It seems Java is not installed. It is required to run Maestro. If the job fails, this may be the reason.'\n );\n logger.info('');\n }\n\n if (!currentIsIdbInstalled) {\n logger.warn(\n 'It seems IDB is not installed. Maestro requires it to run flows on iOS Simulator. If the job fails, this may be the reason.'\n );\n logger.info('');\n }\n\n if (!currentMaestroVersion) {\n logger.warn(\n 'It seems Maestro is not installed. Please install Maestro manually and rerun the job.'\n );\n logger.info('');\n }\n\n // Guide is helpful in these two cases, it doesn't mention Java.\n if (!currentIsIdbInstalled || !currentMaestroVersion) {\n logger.warn(\n 'For more info, check out Maestro installation guide: https://maestro.mobile.dev/getting-started/installing-maestro'\n );\n }\n\n if (currentMaestroVersion) {\n logger.info(`Maestro ${currentMaestroVersion} is ready.`);\n }\n\n return;\n }\n\n if (!(await isJavaInstalled())) {\n if (global.runtimePlatform === BuildRuntimePlatform.DARWIN) {\n logger.info('Installing Java');\n await installJavaFromGcs({ logger });\n } else {\n // We expect Java to be pre-installed on Linux images,\n // so this should only happen when running this step locally.\n // We don't need to support installing Java on local computers.\n throw new Error('Please install Java manually and rerun the job.');\n }\n }\n\n // IDB is only a requirement on macOS.\n if (global.runtimePlatform === BuildRuntimePlatform.DARWIN && !(await isIdbInstalled())) {\n logger.info('Installing IDB');\n await installIdbFromBrew({ global, logger });\n }\n\n // Skip installing if the input sets a specific Maestro version to install\n // and it is already installed which happens when developing on a local computer.\n if (!currentMaestroVersion || requestedMaestroVersion !== currentMaestroVersion) {\n await installMaestro({\n version: requestedMaestroVersion,\n global,\n logger,\n });\n }\n\n const maestroVersion = await getMaestroVersion();\n assert(maestroVersion, 'Failed to ensure Maestro is installed.');\n logger.info(`Maestro ${maestroVersion} is ready.`);\n },\n });\n}\n\nasync function getMaestroVersion(): Promise<string | null> {\n try {\n const maestroVersion = await spawn('maestro', ['--version'], { stdio: 'pipe' });\n return maestroVersion.stdout.trim();\n } catch {\n return null;\n }\n}\n\nasync function installMaestro({\n global,\n version,\n logger,\n}: {\n version?: string;\n logger: bunyan;\n global: BuildStepGlobalContext;\n}): Promise<void> {\n logger.info('Fetching install script');\n const tempDirectory = await fs.mkdtemp('install_maestro');\n try {\n const installMaestroScriptResponse = await fetch('https://get.maestro.mobile.dev');\n const installMaestroScript = await installMaestroScriptResponse.text();\n const installMaestroScriptFilePath = path.join(tempDirectory, 'install_maestro.sh');\n await fs.writeFile(installMaestroScriptFilePath, installMaestroScript, {\n mode: 0o777,\n });\n logger.info('Installing Maestro');\n await spawn(installMaestroScriptFilePath, [], {\n logger,\n env: {\n ...global.env,\n MAESTRO_VERSION: version,\n },\n });\n } finally {\n await fs.remove(tempDirectory);\n }\n}\n\nasync function isIdbInstalled(): Promise<boolean> {\n try {\n await spawn('idb', ['-h'], { ignoreStdio: true });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function installIdbFromBrew({\n global,\n logger,\n}: {\n global: BuildStepGlobalContext;\n logger: bunyan;\n}): Promise<void> {\n // Unfortunately our Mac images sometimes have two Homebrew\n // installations. We should use the ARM64 one, located in /opt/homebrew.\n const brewPath = '/opt/homebrew/bin/brew';\n const env = {\n ...global.env,\n HOMEBREW_NO_AUTO_UPDATE: '1',\n };\n\n await spawn(brewPath, ['tap', 'facebook/fb'], {\n env,\n logger,\n });\n await spawn(brewPath, ['install', 'idb-companion'], {\n env,\n logger,\n });\n}\n\nasync function isJavaInstalled(): Promise<boolean> {\n try {\n await spawn('java', ['-version'], { ignoreStdio: true });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Installs Java 11 from a file uploaded manually to GCS as cache.\n * Should not be run outside of EAS Build VMs not to break users' environments.\n */\nasync function installJavaFromGcs({ logger }: { logger: bunyan }): Promise<void> {\n const downloadUrl =\n 'https://storage.googleapis.com/turtle-v2/zulu11.68.17-ca-jdk11.0.21-macosx_aarch64.dmg';\n const filename = path.basename(downloadUrl);\n const tempDirectory = await fs.mkdtemp('install_java');\n const installerPath = path.join(tempDirectory, filename);\n const installerMountDirectory = path.join(tempDirectory, 'mountpoint');\n try {\n logger.info('Downloading Java installer');\n // This is simpler than piping body into a write stream with node-fetch.\n await spawn('curl', ['--output', installerPath, downloadUrl]);\n\n await fs.mkdir(installerMountDirectory);\n logger.info('Mounting Java installer');\n await spawn(\n 'hdiutil',\n ['attach', installerPath, '-noverify', '-mountpoint', installerMountDirectory],\n { logger }\n );\n\n logger.info('Installing Java');\n await spawn(\n 'sudo',\n [\n 'installer',\n '-pkg',\n path.join(installerMountDirectory, 'Double-Click to Install Azul Zulu JDK 11.pkg'),\n '-target',\n '/',\n ],\n { logger }\n );\n } finally {\n try {\n // We need to unmount to remove, otherwise we get \"resource busy\"\n await spawn('hdiutil', ['detach', installerMountDirectory]);\n } catch {}\n\n await fs.remove(tempDirectory);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"installMaestro.js","sourceRoot":"","sources":["../../../src/steps/functions/installMaestro.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport path from 'path';\n\nimport fs from 'fs-extra';\nimport {\n BuildFunction,\n BuildRuntimePlatform,\n BuildStepEnv,\n BuildStepGlobalContext,\n BuildStepInput,\n BuildStepInputValueTypeName,\n} from '@expo/steps';\nimport spawn from '@expo/turtle-spawn';\nimport { bunyan } from '@expo/logger';\n\nexport function createInstallMaestroBuildFunction(): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'install_maestro',\n name: 'Install Maestro',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'maestro_version',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async ({ logger, global }, { inputs, env }) => {\n const requestedMaestroVersion = inputs.maestro_version.value as string | undefined;\n const currentMaestroVersion = await getMaestroVersion({ env });\n\n // When not running in EAS Build VM, do not modify local environment.\n if (env.EAS_BUILD_RUNNER !== 'eas-build') {\n const currentIsJavaInstalled = await isJavaInstalled({ env });\n const currentIsIdbInstalled = await isIdbInstalled({ env });\n\n if (!currentIsJavaInstalled) {\n logger.warn(\n 'It seems Java is not installed. It is required to run Maestro. If the job fails, this may be the reason.'\n );\n logger.info('');\n }\n\n if (!currentIsIdbInstalled) {\n logger.warn(\n 'It seems IDB is not installed. Maestro requires it to run flows on iOS Simulator. If the job fails, this may be the reason.'\n );\n logger.info('');\n }\n\n if (!currentMaestroVersion) {\n logger.warn(\n 'It seems Maestro is not installed. Please install Maestro manually and rerun the job.'\n );\n logger.info('');\n }\n\n // Guide is helpful in these two cases, it doesn't mention Java.\n if (!currentIsIdbInstalled || !currentMaestroVersion) {\n logger.warn(\n 'For more info, check out Maestro installation guide: https://maestro.mobile.dev/getting-started/installing-maestro'\n );\n }\n\n if (currentMaestroVersion) {\n logger.info(`Maestro ${currentMaestroVersion} is ready.`);\n }\n\n return;\n }\n\n if (!(await isJavaInstalled({ env }))) {\n if (global.runtimePlatform === BuildRuntimePlatform.DARWIN) {\n logger.info('Installing Java');\n await installJavaFromGcs({ logger, env });\n } else {\n // We expect Java to be pre-installed on Linux images,\n // so this should only happen when running this step locally.\n // We don't need to support installing Java on local computers.\n throw new Error('Please install Java manually and rerun the job.');\n }\n }\n\n // IDB is only a requirement on macOS.\n if (\n global.runtimePlatform === BuildRuntimePlatform.DARWIN &&\n !(await isIdbInstalled({ env }))\n ) {\n logger.info('Installing IDB');\n await installIdbFromBrew({ logger, env });\n }\n\n // Skip installing if the input sets a specific Maestro version to install\n // and it is already installed which happens when developing on a local computer.\n if (!currentMaestroVersion || requestedMaestroVersion !== currentMaestroVersion) {\n await installMaestro({\n version: requestedMaestroVersion,\n global,\n logger,\n env,\n });\n }\n\n const maestroVersion = await getMaestroVersion({ env });\n assert(maestroVersion, 'Failed to ensure Maestro is installed.');\n logger.info(`Maestro ${maestroVersion} is ready.`);\n },\n });\n}\n\nasync function getMaestroVersion({ env }: { env: BuildStepEnv }): Promise<string | null> {\n try {\n const maestroVersion = await spawn('maestro', ['--version'], { stdio: 'pipe', env });\n return maestroVersion.stdout.trim();\n } catch {\n return null;\n }\n}\n\nasync function installMaestro({\n global,\n version,\n logger,\n env,\n}: {\n version?: string;\n logger: bunyan;\n global: BuildStepGlobalContext;\n env: BuildStepEnv;\n}): Promise<void> {\n logger.info('Fetching install script');\n const tempDirectory = await fs.mkdtemp('install_maestro');\n try {\n const installMaestroScriptResponse = await fetch('https://get.maestro.mobile.dev');\n const installMaestroScript = await installMaestroScriptResponse.text();\n const installMaestroScriptFilePath = path.join(tempDirectory, 'install_maestro.sh');\n await fs.writeFile(installMaestroScriptFilePath, installMaestroScript, {\n mode: 0o777,\n });\n logger.info('Installing Maestro');\n assert(\n env.HOME,\n 'Failed to infer directory to install Maestro in: $HOME environment variable is empty.'\n );\n const maestroDir = path.join(env.HOME, '.maestro');\n await spawn(installMaestroScriptFilePath, [], {\n logger,\n env: {\n ...env,\n MAESTRO_DIR: maestroDir,\n MAESTRO_VERSION: version,\n },\n });\n // That's where Maestro installs binary as of February 2024\n // I suspect/hope they don't change the location.\n const maestroBinDir = path.join(maestroDir, 'bin');\n global.updateEnv({\n ...global.env,\n PATH: `${global.env.PATH}:${maestroBinDir}`,\n });\n env.PATH = `${env.PATH}:${maestroBinDir}`;\n process.env.PATH = `${process.env.PATH}:${maestroBinDir}`;\n } finally {\n await fs.remove(tempDirectory);\n }\n}\n\nasync function isIdbInstalled({ env }: { env: BuildStepEnv }): Promise<boolean> {\n try {\n await spawn('idb', ['-h'], { ignoreStdio: true, env });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function installIdbFromBrew({\n logger,\n env,\n}: {\n logger: bunyan;\n env: BuildStepEnv;\n}): Promise<void> {\n // Unfortunately our Mac images sometimes have two Homebrew\n // installations. We should use the ARM64 one, located in /opt/homebrew.\n const brewPath = '/opt/homebrew/bin/brew';\n const localEnv = {\n ...env,\n HOMEBREW_NO_AUTO_UPDATE: '1',\n };\n\n await spawn(brewPath, ['tap', 'facebook/fb'], {\n env: localEnv,\n logger,\n });\n await spawn(brewPath, ['install', 'idb-companion'], {\n env: localEnv,\n logger,\n });\n}\n\nasync function isJavaInstalled({ env }: { env: BuildStepEnv }): Promise<boolean> {\n try {\n await spawn('java', ['-version'], { ignoreStdio: true, env });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Installs Java 11 from a file uploaded manually to GCS as cache.\n * Should not be run outside of EAS Build VMs not to break users' environments.\n */\nasync function installJavaFromGcs({\n logger,\n env,\n}: {\n logger: bunyan;\n env: BuildStepEnv;\n}): Promise<void> {\n const downloadUrl =\n 'https://storage.googleapis.com/turtle-v2/zulu11.68.17-ca-jdk11.0.21-macosx_aarch64.dmg';\n const filename = path.basename(downloadUrl);\n const tempDirectory = await fs.mkdtemp('install_java');\n const installerPath = path.join(tempDirectory, filename);\n const installerMountDirectory = path.join(tempDirectory, 'mountpoint');\n try {\n logger.info('Downloading Java installer');\n // This is simpler than piping body into a write stream with node-fetch.\n await spawn('curl', ['--output', installerPath, downloadUrl], { env });\n\n await fs.mkdir(installerMountDirectory);\n logger.info('Mounting Java installer');\n await spawn(\n 'hdiutil',\n ['attach', installerPath, '-noverify', '-mountpoint', installerMountDirectory],\n { logger, env }\n );\n\n logger.info('Installing Java');\n await spawn(\n 'sudo',\n [\n 'installer',\n '-pkg',\n path.join(installerMountDirectory, 'Double-Click to Install Azul Zulu JDK 11.pkg'),\n '-target',\n '/',\n ],\n { logger, env }\n );\n } finally {\n try {\n // We need to unmount to remove, otherwise we get \"resource busy\"\n await spawn('hdiutil', ['detach', installerMountDirectory], { env });\n } catch {}\n\n await fs.remove(tempDirectory);\n }\n}\n"]}
|
|
@@ -30,16 +30,18 @@ function createStartAndroidEmulatorBuildFunction() {
|
|
|
30
30
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
31
31
|
}),
|
|
32
32
|
],
|
|
33
|
-
fn: async ({ logger }, { inputs }) => {
|
|
33
|
+
fn: async ({ logger }, { inputs, env }) => {
|
|
34
34
|
var _a, _b;
|
|
35
35
|
const deviceName = `${inputs.device_name.value}`;
|
|
36
36
|
const systemImagePackage = `${inputs.system_image_package.value}`;
|
|
37
37
|
logger.info('Making sure system image is installed');
|
|
38
38
|
await (0, turtle_spawn_1.default)('sdkmanager', [systemImagePackage], {
|
|
39
|
+
env,
|
|
39
40
|
logger,
|
|
40
41
|
});
|
|
41
42
|
logger.info('Creating emulator device');
|
|
42
43
|
const avdManager = (0, turtle_spawn_1.default)('avdmanager', ['create', 'avd', '--name', deviceName, '--package', systemImagePackage, '--force'], {
|
|
44
|
+
env,
|
|
43
45
|
stdio: 'pipe',
|
|
44
46
|
});
|
|
45
47
|
// `avdmanager create` always asks about creating a custom hardware profile.
|
|
@@ -50,10 +52,10 @@ function createStartAndroidEmulatorBuildFunction() {
|
|
|
50
52
|
await avdManager;
|
|
51
53
|
const qemuPropId = (0, uuid_1.v4)();
|
|
52
54
|
logger.info('Starting emulator device');
|
|
53
|
-
await startAndroidSimulator({ deviceName, qemuPropId });
|
|
55
|
+
await startAndroidSimulator({ deviceName, qemuPropId, env });
|
|
54
56
|
logger.info('Waiting for emulator to become ready');
|
|
55
57
|
const serialId = await (0, retry_1.retryAsync)(async () => {
|
|
56
|
-
const serialId = await getEmulatorSerialId({ qemuPropId });
|
|
58
|
+
const serialId = await getEmulatorSerialId({ qemuPropId, env });
|
|
57
59
|
(0, assert_1.default)(serialId, 'Failed to configure emulator: emulator with required ID not found.');
|
|
58
60
|
return serialId;
|
|
59
61
|
}, {
|
|
@@ -66,6 +68,7 @@ function createStartAndroidEmulatorBuildFunction() {
|
|
|
66
68
|
});
|
|
67
69
|
await (0, retry_1.retryAsync)(async () => {
|
|
68
70
|
const { stdout } = await (0, turtle_spawn_1.default)('adb', ['-s', serialId, 'shell', 'getprop', 'sys.boot_completed'], {
|
|
71
|
+
env,
|
|
69
72
|
mode: logger_1.PipeMode.COMBINED,
|
|
70
73
|
});
|
|
71
74
|
if (!stdout.startsWith('1')) {
|
|
@@ -83,7 +86,7 @@ function createStartAndroidEmulatorBuildFunction() {
|
|
|
83
86
|
});
|
|
84
87
|
}
|
|
85
88
|
exports.createStartAndroidEmulatorBuildFunction = createStartAndroidEmulatorBuildFunction;
|
|
86
|
-
async function startAndroidSimulator({ deviceName, qemuPropId, }) {
|
|
89
|
+
async function startAndroidSimulator({ deviceName, qemuPropId, env, }) {
|
|
87
90
|
const emulatorPromise = (0, turtle_spawn_1.default)(`${process.env.ANDROID_HOME}/emulator/emulator`, [
|
|
88
91
|
'-no-window',
|
|
89
92
|
'-no-boot-anim',
|
|
@@ -96,6 +99,7 @@ async function startAndroidSimulator({ deviceName, qemuPropId, }) {
|
|
|
96
99
|
], {
|
|
97
100
|
detached: true,
|
|
98
101
|
stdio: 'ignore',
|
|
102
|
+
env,
|
|
99
103
|
});
|
|
100
104
|
// If emulator fails to start, throw its error.
|
|
101
105
|
if (!emulatorPromise.child.pid) {
|
|
@@ -103,8 +107,8 @@ async function startAndroidSimulator({ deviceName, qemuPropId, }) {
|
|
|
103
107
|
}
|
|
104
108
|
emulatorPromise.child.unref();
|
|
105
109
|
}
|
|
106
|
-
async function getEmulatorSerialId({ qemuPropId }) {
|
|
107
|
-
const adbDevices = await (0, turtle_spawn_1.default)('adb', ['devices'], { mode: logger_1.PipeMode.COMBINED });
|
|
110
|
+
async function getEmulatorSerialId({ qemuPropId, env, }) {
|
|
111
|
+
const adbDevices = await (0, turtle_spawn_1.default)('adb', ['devices'], { mode: logger_1.PipeMode.COMBINED, env });
|
|
108
112
|
for (const adbDeviceLine of adbDevices.stdout.split('\n')) {
|
|
109
113
|
if (!adbDeviceLine.startsWith('emulator')) {
|
|
110
114
|
continue;
|
|
@@ -116,6 +120,7 @@ async function getEmulatorSerialId({ qemuPropId }) {
|
|
|
116
120
|
const [, serialId] = matches;
|
|
117
121
|
const getProp = await (0, turtle_spawn_1.default)('adb', ['-s', serialId, 'shell', 'getprop', 'qemu.uuid'], {
|
|
118
122
|
mode: logger_1.PipeMode.COMBINED,
|
|
123
|
+
env,
|
|
119
124
|
});
|
|
120
125
|
if (getProp.stdout.startsWith(qemuPropId)) {
|
|
121
126
|
return serialId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startAndroidEmulator.js","sourceRoot":"","sources":["../../../src/steps/functions/startAndroidEmulator.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAE5B,yCAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"startAndroidEmulator.js","sourceRoot":"","sources":["../../../src/steps/functions/startAndroidEmulator.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\n\nimport { PipeMode } from '@expo/logger';\nimport {\n BuildFunction,\n BuildStepEnv,\n BuildStepInput,\n BuildStepInputValueTypeName,\n} from '@expo/steps';\nimport spawn from '@expo/turtle-spawn';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { retryAsync } from '../../utils/retry';\n\nconst defaultSystemImagePackage = `system-images;android-30;default;${\n process.arch === 'arm64' ? 'arm64-v8a' : 'x86_64'\n}`;\n\nexport function createStartAndroidEmulatorBuildFunction(): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'start_android_emulator',\n name: 'Start Android Emulator',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'device_name',\n required: false,\n defaultValue: 'EasAndroidDevice01',\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n BuildStepInput.createProvider({\n id: 'system_image_package',\n required: false,\n defaultValue: defaultSystemImagePackage,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async ({ logger }, { inputs, env }) => {\n const deviceName = `${inputs.device_name.value}`;\n const systemImagePackage = `${inputs.system_image_package.value}`;\n logger.info('Making sure system image is installed');\n await spawn('sdkmanager', [systemImagePackage], {\n env,\n logger,\n });\n\n logger.info('Creating emulator device');\n const avdManager = spawn(\n 'avdmanager',\n ['create', 'avd', '--name', deviceName, '--package', systemImagePackage, '--force'],\n {\n env,\n stdio: 'pipe',\n }\n );\n // `avdmanager create` always asks about creating a custom hardware profile.\n // > Do you wish to create a custom hardware profile? [no]\n // We answer \"no\".\n avdManager.child.stdin?.write('no');\n avdManager.child.stdin?.end();\n await avdManager;\n\n const qemuPropId = uuidv4();\n\n logger.info('Starting emulator device');\n await startAndroidSimulator({ deviceName, qemuPropId, env });\n\n logger.info('Waiting for emulator to become ready');\n const serialId = await retryAsync(\n async () => {\n const serialId = await getEmulatorSerialId({ qemuPropId, env });\n assert(serialId, 'Failed to configure emulator: emulator with required ID not found.');\n return serialId;\n },\n {\n logger,\n retryOptions: {\n // Emulators usually take 30 second tops to boot.\n retries: 60,\n retryIntervalMs: 1_000,\n },\n }\n );\n\n await retryAsync(\n async () => {\n const { stdout } = await spawn(\n 'adb',\n ['-s', serialId, 'shell', 'getprop', 'sys.boot_completed'],\n {\n env,\n mode: PipeMode.COMBINED,\n }\n );\n\n if (!stdout.startsWith('1')) {\n throw new Error('Emulator boot has not completed.');\n }\n },\n {\n // Retry every second for 3 minutes.\n retryOptions: {\n retries: 3 * 60,\n retryIntervalMs: 1_000,\n },\n }\n );\n\n logger.info(`${deviceName} is ready.`);\n },\n });\n}\n\nasync function startAndroidSimulator({\n deviceName,\n qemuPropId,\n env,\n}: {\n deviceName: string;\n qemuPropId: string;\n env: BuildStepEnv;\n}): Promise<void> {\n const emulatorPromise = spawn(\n `${process.env.ANDROID_HOME}/emulator/emulator`,\n [\n '-no-window',\n '-no-boot-anim',\n '-writable-system',\n '-noaudio',\n '-avd',\n deviceName,\n '-prop',\n `qemu.uuid=${qemuPropId}`,\n ],\n {\n detached: true,\n stdio: 'ignore',\n env,\n }\n );\n // If emulator fails to start, throw its error.\n if (!emulatorPromise.child.pid) {\n await emulatorPromise;\n }\n emulatorPromise.child.unref();\n}\n\nasync function getEmulatorSerialId({\n qemuPropId,\n env,\n}: {\n qemuPropId: string;\n env: BuildStepEnv;\n}): Promise<string | null> {\n const adbDevices = await spawn('adb', ['devices'], { mode: PipeMode.COMBINED, env });\n for (const adbDeviceLine of adbDevices.stdout.split('\\n')) {\n if (!adbDeviceLine.startsWith('emulator')) {\n continue;\n }\n\n const matches = adbDeviceLine.match(/^(\\S+)/);\n if (!matches) {\n continue;\n }\n\n const [, serialId] = matches;\n const getProp = await spawn('adb', ['-s', serialId, 'shell', 'getprop', 'qemu.uuid'], {\n mode: PipeMode.COMBINED,\n env,\n });\n if (getProp.stdout.startsWith(qemuPropId)) {\n return serialId;\n }\n }\n\n return null;\n}\n"]}
|
|
@@ -21,10 +21,10 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
21
21
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
22
22
|
}),
|
|
23
23
|
],
|
|
24
|
-
fn: async ({ logger }, { inputs }) => {
|
|
24
|
+
fn: async ({ logger }, { inputs, env }) => {
|
|
25
25
|
var _a, _b, _c;
|
|
26
26
|
try {
|
|
27
|
-
const availableDevices = await getAvailableSimulatorDevices();
|
|
27
|
+
const availableDevices = await getAvailableSimulatorDevices({ env });
|
|
28
28
|
logger.info(`Available Simulator devices:\n- ${availableDevices
|
|
29
29
|
.map(formatSimulatorDevice)
|
|
30
30
|
.join(`\n- `)}`);
|
|
@@ -35,15 +35,18 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
35
35
|
finally {
|
|
36
36
|
logger.info('');
|
|
37
37
|
}
|
|
38
|
-
const deviceIdentifier = (_b = (_a = inputs.device_identifier.value) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : (_c = (await findMostGenericIphone())) === null || _c === void 0 ? void 0 : _c.name;
|
|
38
|
+
const deviceIdentifier = (_b = (_a = inputs.device_identifier.value) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : (_c = (await findMostGenericIphone({ env }))) === null || _c === void 0 ? void 0 : _c.name;
|
|
39
39
|
if (!deviceIdentifier) {
|
|
40
40
|
throw new Error('Could not find an iPhone among available simulator devices.');
|
|
41
41
|
}
|
|
42
42
|
const bootstatusResult = await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'bootstatus', deviceIdentifier, '-b'], {
|
|
43
43
|
logger,
|
|
44
|
+
env,
|
|
44
45
|
});
|
|
45
46
|
await (0, retry_1.retryAsync)(async () => {
|
|
46
|
-
await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'io', deviceIdentifier, 'screenshot', '/dev/null']
|
|
47
|
+
await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'io', deviceIdentifier, 'screenshot', '/dev/null'], {
|
|
48
|
+
env,
|
|
49
|
+
});
|
|
47
50
|
}, {
|
|
48
51
|
retryOptions: {
|
|
49
52
|
// There's 30 * 60 seconds in 30 minutes, which is the timeout.
|
|
@@ -53,14 +56,14 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
53
56
|
});
|
|
54
57
|
logger.info('');
|
|
55
58
|
const udid = parseUdidFromBootstatusStdout(bootstatusResult.stdout);
|
|
56
|
-
const device = udid ? await getSimulatorDevice(udid) : null;
|
|
59
|
+
const device = udid ? await getSimulatorDevice({ udid, env }) : null;
|
|
57
60
|
logger.info(`${device ? formatSimulatorDevice(device) : deviceIdentifier} is ready.`);
|
|
58
61
|
},
|
|
59
62
|
});
|
|
60
63
|
}
|
|
61
64
|
exports.createStartIosSimulatorBuildFunction = createStartIosSimulatorBuildFunction;
|
|
62
|
-
async function findMostGenericIphone() {
|
|
63
|
-
const availableSimulatorDevices = await getAvailableSimulatorDevices();
|
|
65
|
+
async function findMostGenericIphone({ env, }) {
|
|
66
|
+
const availableSimulatorDevices = await getAvailableSimulatorDevices({ env });
|
|
64
67
|
const availableIphones = availableSimulatorDevices.filter((device) => device.name.startsWith('iPhone'));
|
|
65
68
|
// It's funny, but it works.
|
|
66
69
|
const iphoneWithShortestName = (0, lodash_1.minBy)(availableIphones, (device) => device.name.length);
|
|
@@ -76,13 +79,14 @@ function parseUdidFromBootstatusStdout(stdout) {
|
|
|
76
79
|
}
|
|
77
80
|
return matches[1];
|
|
78
81
|
}
|
|
79
|
-
async function getSimulatorDevice(udid) {
|
|
82
|
+
async function getSimulatorDevice({ udid, env, }) {
|
|
80
83
|
var _a;
|
|
81
|
-
const devices = await getAvailableSimulatorDevices();
|
|
84
|
+
const devices = await getAvailableSimulatorDevices({ env });
|
|
82
85
|
return (_a = devices.find((device) => device.udid === udid)) !== null && _a !== void 0 ? _a : null;
|
|
83
86
|
}
|
|
84
|
-
async function getAvailableSimulatorDevices() {
|
|
87
|
+
async function getAvailableSimulatorDevices({ env, }) {
|
|
85
88
|
const result = await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'list', 'devices', '--json', '--no-escape-slashes', 'available'], {
|
|
89
|
+
env,
|
|
86
90
|
mode: logger_1.PipeMode.COMBINED_AS_STDOUT,
|
|
87
91
|
});
|
|
88
92
|
const xcrunData = JSON.parse(result.stdout);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startIosSimulator.js","sourceRoot":"","sources":["../../../src/steps/functions/startIosSimulator.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"startIosSimulator.js","sourceRoot":"","sources":["../../../src/steps/functions/startIosSimulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { PipeMode } from '@expo/logger';\nimport {\n BuildFunction,\n BuildStepEnv,\n BuildStepInput,\n BuildStepInputValueTypeName,\n} from '@expo/steps';\nimport spawn from '@expo/turtle-spawn';\nimport { minBy } from 'lodash';\n\nimport { retryAsync } from '../../utils/retry';\n\nexport function createStartIosSimulatorBuildFunction(): BuildFunction {\n return new BuildFunction({\n namespace: 'eas',\n id: 'start_ios_simulator',\n name: 'Start iOS Simulator',\n inputProviders: [\n BuildStepInput.createProvider({\n id: 'device_identifier',\n required: false,\n allowedValueTypeName: BuildStepInputValueTypeName.STRING,\n }),\n ],\n fn: async ({ logger }, { inputs, env }) => {\n try {\n const availableDevices = await getAvailableSimulatorDevices({ env });\n logger.info(\n `Available Simulator devices:\\n- ${availableDevices\n .map(formatSimulatorDevice)\n .join(`\\n- `)}`\n );\n } catch (error) {\n logger.info('Failed to list available Simulator devices.', error);\n } finally {\n logger.info('');\n }\n\n const deviceIdentifier =\n inputs.device_identifier.value?.toString() ?? (await findMostGenericIphone({ env }))?.name;\n\n if (!deviceIdentifier) {\n throw new Error('Could not find an iPhone among available simulator devices.');\n }\n\n const bootstatusResult = await spawn(\n 'xcrun',\n ['simctl', 'bootstatus', deviceIdentifier, '-b'],\n {\n logger,\n env,\n }\n );\n\n await retryAsync(\n async () => {\n await spawn('xcrun', ['simctl', 'io', deviceIdentifier, 'screenshot', '/dev/null'], {\n env,\n });\n },\n {\n retryOptions: {\n // There's 30 * 60 seconds in 30 minutes, which is the timeout.\n retries: 30 * 60,\n retryIntervalMs: 1_000,\n },\n }\n );\n\n logger.info('');\n\n const udid = parseUdidFromBootstatusStdout(bootstatusResult.stdout);\n const device = udid ? await getSimulatorDevice({ udid, env }) : null;\n logger.info(`${device ? formatSimulatorDevice(device) : deviceIdentifier} is ready.`);\n },\n });\n}\n\nasync function findMostGenericIphone({\n env,\n}: {\n env: BuildStepEnv;\n}): Promise<AvailableXcrunSimctlDevice | null> {\n const availableSimulatorDevices = await getAvailableSimulatorDevices({ env });\n const availableIphones = availableSimulatorDevices.filter((device) =>\n device.name.startsWith('iPhone')\n );\n // It's funny, but it works.\n const iphoneWithShortestName = minBy(availableIphones, (device) => device.name.length);\n return iphoneWithShortestName ?? null;\n}\n\nfunction formatSimulatorDevice(device: XcrunSimctlDevice & { runtime: string }): string {\n return `${device.name} (${device.udid}) on ${device.runtime}`;\n}\n\nfunction parseUdidFromBootstatusStdout(stdout: string): string | null {\n const matches = stdout.match(/^Monitoring boot status for .+ \\((.+)\\)\\.$/m);\n if (!matches) {\n return null;\n }\n return matches[1];\n}\n\nasync function getSimulatorDevice({\n udid,\n env,\n}: {\n udid: string;\n env: BuildStepEnv;\n}): Promise<SimulatorDevice | null> {\n const devices = await getAvailableSimulatorDevices({ env });\n return devices.find((device) => device.udid === udid) ?? null;\n}\n\nasync function getAvailableSimulatorDevices({\n env,\n}: {\n env: BuildStepEnv;\n}): Promise<SimulatorDevice[]> {\n const result = await spawn(\n 'xcrun',\n ['simctl', 'list', 'devices', '--json', '--no-escape-slashes', 'available'],\n {\n env,\n mode: PipeMode.COMBINED_AS_STDOUT,\n }\n );\n const xcrunData = JSON.parse(\n result.stdout\n ) as XcrunSimctlListDevicesJsonOutput<AvailableXcrunSimctlDevice>;\n\n const allAvailableDevices: (AvailableXcrunSimctlDevice & { runtime: string })[] = [];\n for (const [runtime, devices] of Object.entries(xcrunData.devices)) {\n allAvailableDevices.push(...devices.map((device) => ({ ...device, runtime })));\n }\n\n return allAvailableDevices;\n}\n\ntype XcrunSimctlDevice = {\n availabilityError?: string;\n /** e.g. /Users/sjchmiela/Library/Developer/CoreSimulator/Devices/8272DEB1-42B5-4F78-AB2D-0BC5F320B822/data */\n dataPath: string;\n /** e.g. 18341888 */\n dataPathSize: number;\n /** e.g. /Users/sjchmiela/Library/Logs/CoreSimulator/8272DEB1-42B5-4F78-AB2D-0BC5F320B822 */\n logPath: string;\n /** e.g. 8272DEB1-42B5-4F78-AB2D-0BC5F320B822 */\n udid: string;\n isAvailable: boolean;\n /** e.g. com.apple.CoreSimulator.SimDeviceType.iPhone-13-mini */\n deviceTypeIdentifier: string;\n state: 'Shutdown' | 'Booted';\n /** e.g. iPhone 15 */\n name: string;\n /** e.g. 2024-01-22T19:28:56Z */\n lastBootedAt?: string;\n};\n\ntype SimulatorDevice = AvailableXcrunSimctlDevice & { runtime: string };\n\ntype AvailableXcrunSimctlDevice = XcrunSimctlDevice & {\n availabilityError?: never;\n isAvailable: true;\n};\n\ntype XcrunSimctlListDevicesJsonOutput<TDevice extends XcrunSimctlDevice = XcrunSimctlDevice> = {\n devices: {\n [runtime: string]: TDevice[];\n };\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.64",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"node": "20.11.0",
|
|
68
68
|
"yarn": "1.22.21"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "41418a3e2a55dc9dabece13bc7a51ba568839d5e"
|
|
71
71
|
}
|