eas-cli 2.5.1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1095
- package/build/branch/queries.d.ts +8 -1
- package/build/branch/queries.js +53 -23
- package/build/build/android/build.js +1 -0
- package/build/build/ios/build.js +1 -0
- package/build/build/local.js +1 -1
- package/build/build/queries.d.ts +11 -1
- package/build/build/queries.js +39 -1
- package/build/build/validate.d.ts +1 -0
- package/build/build/validate.js +121 -1
- package/build/channel/queries.d.ts +11 -0
- package/build/channel/queries.js +51 -9
- package/build/channel/utils.js +22 -22
- package/build/commandUtils/context/LoggedInContextField.d.ts +3 -0
- package/build/commandUtils/context/LoggedInContextField.js +9 -1
- package/build/commandUtils/context/MaybeLoggedInContextField.d.ts +3 -0
- package/build/commandUtils/context/MaybeLoggedInContextField.js +9 -1
- package/build/commandUtils/context/contextUtils/createGraphqlClient.d.ts +2 -2
- package/build/commandUtils/context/contextUtils/getProjectIdAsync.js +1 -1
- package/build/commandUtils/gating/FeatureGateEnvOverrides.d.ts +7 -0
- package/build/commandUtils/gating/FeatureGateEnvOverrides.js +35 -0
- package/build/commandUtils/gating/FeatureGateKey.d.ts +4 -0
- package/build/commandUtils/gating/FeatureGateKey.js +11 -0
- package/build/commandUtils/gating/FeatureGateTestOverrides.d.ts +5 -0
- package/build/commandUtils/gating/FeatureGateTestOverrides.js +17 -0
- package/build/commandUtils/gating/FeatureGating.d.ts +16 -0
- package/build/commandUtils/gating/FeatureGating.js +55 -0
- package/build/commandUtils/pagination.d.ts +4 -3
- package/build/commands/branch/create.d.ts +0 -3
- package/build/commands/branch/create.js +2 -27
- package/build/commands/branch/list.d.ts +1 -1
- package/build/commands/branch/view.d.ts +1 -1
- package/build/commands/build/configure.d.ts +1 -1
- package/build/commands/build/index.d.ts +2 -2
- package/build/commands/build/list.d.ts +4 -4
- package/build/commands/build/list.js +2 -15
- package/build/commands/build/run.d.ts +21 -0
- package/build/commands/build/run.js +149 -0
- package/build/commands/build/version/set.d.ts +1 -1
- package/build/commands/build/version/sync.d.ts +1 -1
- package/build/commands/channel/create.d.ts +0 -7
- package/build/commands/channel/create.js +4 -31
- package/build/commands/channel/list.d.ts +1 -1
- package/build/commands/channel/view.d.ts +1 -1
- package/build/commands/config.d.ts +1 -1
- package/build/commands/credentials.d.ts +1 -1
- package/build/commands/device/list.d.ts +1 -1
- package/build/commands/metadata/lint.d.ts +12 -0
- package/build/commands/metadata/lint.js +72 -0
- package/build/commands/metadata/pull.js +20 -9
- package/build/commands/metadata/push.js +20 -9
- package/build/commands/secret/create.d.ts +1 -1
- package/build/commands/secret/list.js +12 -17
- package/build/commands/submit.d.ts +1 -1
- package/build/commands/update/configure.d.ts +1 -0
- package/build/commands/update/configure.js +10 -216
- package/build/commands/update/index.d.ts +3 -9
- package/build/commands/update/index.js +136 -143
- package/build/commands/update/list.d.ts +1 -1
- package/build/commands/webhook/create.d.ts +1 -1
- package/build/commands/webhook/list.d.ts +1 -1
- package/build/commands/webhook/update.d.ts +1 -1
- package/build/devices/actions/create/inputMethod.js +2 -15
- package/build/devices/utils/formatDevice.d.ts +2 -0
- package/build/devices/utils/formatDevice.js +32 -7
- package/build/env.d.ts +8 -0
- package/build/env.js +8 -0
- package/build/graphql/generated.d.ts +100 -23
- package/build/graphql/generated.js +10 -2
- package/build/graphql/mutations/KeystoreGenerationUrlMutation.js +1 -1
- package/build/graphql/queries/UserQuery.js +2 -2
- package/build/graphql/types/Build.js +2 -0
- package/build/log.d.ts +1 -0
- package/build/log.js +3 -0
- package/build/metadata/apple/rules/index.d.ts +1 -0
- package/build/metadata/apple/rules/index.js +6 -0
- package/build/metadata/apple/rules/infoKeywordLength.d.ts +6 -0
- package/build/metadata/apple/rules/infoKeywordLength.js +35 -0
- package/build/metadata/apple/rules/infoRestrictedWords.d.ts +6 -0
- package/build/metadata/apple/rules/infoRestrictedWords.js +57 -0
- package/build/metadata/apple/tasks/index.d.ts +1 -2
- package/build/metadata/apple/tasks/index.js +1 -1
- package/build/metadata/auth.d.ts +21 -0
- package/build/metadata/auth.js +33 -0
- package/build/metadata/config/issue.d.ts +21 -0
- package/build/metadata/config/issue.js +9 -0
- package/build/metadata/config/resolve.d.ts +27 -0
- package/build/metadata/{config.js → config/resolve.js} +24 -25
- package/build/metadata/config/schema.d.ts +7 -0
- package/build/metadata/config/schema.js +2 -0
- package/build/metadata/config/validate.d.ts +3 -0
- package/build/metadata/config/validate.js +47 -0
- package/build/metadata/download.d.ts +11 -2
- package/build/metadata/download.js +14 -9
- package/build/metadata/errors.d.ts +3 -3
- package/build/metadata/errors.js +3 -1
- package/build/metadata/upload.d.ts +11 -2
- package/build/metadata/upload.js +16 -11
- package/build/metadata/utils/ajv.d.ts +10 -0
- package/build/metadata/utils/ajv.js +30 -0
- package/build/metadata/utils/telemetry.js +6 -6
- package/build/project/projectUtils.d.ts +3 -1
- package/build/project/projectUtils.js +10 -3
- package/build/project/publish.d.ts +13 -10
- package/build/project/publish.js +68 -38
- package/build/project/workflow.d.ts +1 -0
- package/build/project/workflow.js +9 -1
- package/build/run/android/run.d.ts +1 -0
- package/build/run/android/run.js +9 -0
- package/build/run/ios/run.d.ts +1 -0
- package/build/run/ios/run.js +31 -0
- package/build/run/ios/simctl.d.ts +2 -0
- package/build/run/ios/simctl.js +8 -0
- package/build/run/ios/simulator.d.ts +21 -0
- package/build/run/ios/simulator.js +161 -0
- package/build/run/ios/systemRequirements.d.ts +1 -0
- package/build/run/ios/systemRequirements.js +82 -0
- package/build/run/ios/xcode.d.ts +4 -0
- package/build/run/ios/xcode.js +41 -0
- package/build/run/ios/xcrun.d.ts +4 -0
- package/build/run/ios/xcrun.js +68 -0
- package/build/run/run.d.ts +8 -0
- package/build/run/run.js +15 -0
- package/build/submit/ArchiveSource.js +12 -16
- package/build/submit/utils/summary.d.ts +1 -1
- package/build/update/configure.d.ts +22 -0
- package/build/update/configure.js +200 -0
- package/build/update/queries.js +30 -39
- package/build/update/utils.d.ts +8 -1
- package/build/update/utils.js +35 -1
- package/build/utils/buildDistribution.d.ts +3 -0
- package/build/utils/buildDistribution.js +20 -0
- package/build/utils/download.d.ts +2 -0
- package/build/utils/download.js +114 -0
- package/build/utils/expoCli.d.ts +6 -0
- package/build/utils/expoCli.js +46 -1
- package/build/utils/expodash/filter.d.ts +2 -0
- package/build/utils/expodash/filter.js +8 -0
- package/build/utils/expodash/memoize.d.ts +2 -0
- package/build/utils/expodash/memoize.js +17 -0
- package/build/utils/formatFields.d.ts +3 -2
- package/build/utils/image.d.ts +6 -0
- package/build/utils/image.js +107 -0
- package/build/utils/statuspageService.js +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +36 -30
- package/schema/metadata-0.json +1 -1
- package/build/metadata/config.d.ts +0 -41
- package/build/metadata/context.d.ts +0 -50
- package/build/metadata/context.js +0 -47
package/build/project/publish.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
|
|
3
|
+
exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.filterExportedPlatformsByFlag = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const json_file_1 = tslib_1.__importDefault(require("@expo/json-file"));
|
|
6
6
|
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
@@ -12,6 +12,7 @@ const promise_limit_1 = tslib_1.__importDefault(require("promise-limit"));
|
|
|
12
12
|
const generated_1 = require("../graphql/generated");
|
|
13
13
|
const PublishMutation_1 = require("../graphql/mutations/PublishMutation");
|
|
14
14
|
const PublishQuery_1 = require("../graphql/queries/PublishQuery");
|
|
15
|
+
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
15
16
|
const uploads_1 = require("../uploads");
|
|
16
17
|
const expoCli_1 = require("../utils/expoCli");
|
|
17
18
|
const chunk_1 = tslib_1.__importDefault(require("../utils/expodash/chunk"));
|
|
@@ -21,13 +22,14 @@ const fileMetadataJoi = joi_1.default.object({
|
|
|
21
22
|
.required()
|
|
22
23
|
.items(joi_1.default.object({ path: joi_1.default.string().required(), ext: joi_1.default.string().required() })),
|
|
23
24
|
bundle: joi_1.default.string().required(),
|
|
24
|
-
}).
|
|
25
|
+
}).optional();
|
|
25
26
|
exports.MetadataJoi = joi_1.default.object({
|
|
26
27
|
version: joi_1.default.number().required(),
|
|
27
28
|
bundler: joi_1.default.string().required(),
|
|
28
29
|
fileMetadata: joi_1.default.object({
|
|
29
30
|
android: fileMetadataJoi,
|
|
30
31
|
ios: fileMetadataJoi,
|
|
32
|
+
web: fileMetadataJoi,
|
|
31
33
|
}).required(),
|
|
32
34
|
}).required();
|
|
33
35
|
function guessContentTypeFromExtension(ext) {
|
|
@@ -102,29 +104,44 @@ async function buildUnsortedUpdateInfoGroupAsync(assets, exp) {
|
|
|
102
104
|
return updateInfoGroup;
|
|
103
105
|
}
|
|
104
106
|
exports.buildUnsortedUpdateInfoGroupAsync = buildUnsortedUpdateInfoGroupAsync;
|
|
105
|
-
async function buildBundlesAsync({ projectDir, inputDir, }) {
|
|
107
|
+
async function buildBundlesAsync({ projectDir, inputDir, exp, platformFlag, }) {
|
|
106
108
|
const packageJSON = json_file_1.default.read(path_1.default.resolve(projectDir, 'package.json'));
|
|
107
109
|
if (!packageJSON) {
|
|
108
110
|
throw new Error('Could not locate package.json');
|
|
109
111
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
if ((0, expoCli_1.shouldUseVersionedExpoCLI)(projectDir, exp)) {
|
|
113
|
+
await (0, expoCli_1.expoCommandAsync)(projectDir, [
|
|
114
|
+
'export',
|
|
115
|
+
'--output-dir',
|
|
116
|
+
inputDir,
|
|
117
|
+
'--dump-sourcemap',
|
|
118
|
+
'--platform',
|
|
119
|
+
platformFlag,
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Legacy global Expo CLI
|
|
124
|
+
await (0, expoCli_1.expoCommandAsync)(projectDir, [
|
|
125
|
+
'export',
|
|
126
|
+
'--output-dir',
|
|
127
|
+
inputDir,
|
|
128
|
+
'--experimental-bundle',
|
|
129
|
+
'--non-interactive',
|
|
130
|
+
'--dump-sourcemap',
|
|
131
|
+
'--platform',
|
|
132
|
+
platformFlag,
|
|
133
|
+
]);
|
|
134
|
+
}
|
|
118
135
|
}
|
|
119
136
|
exports.buildBundlesAsync = buildBundlesAsync;
|
|
120
|
-
async function resolveInputDirectoryAsync(
|
|
121
|
-
const distRoot = path_1.default.resolve(
|
|
137
|
+
async function resolveInputDirectoryAsync(inputDir, { skipBundler }) {
|
|
138
|
+
const distRoot = path_1.default.resolve(inputDir);
|
|
122
139
|
if (!(await fs_extra_1.default.pathExists(distRoot))) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
140
|
+
let error = `--input-dir="${inputDir}" not found.`;
|
|
141
|
+
if (skipBundler) {
|
|
142
|
+
error += ` --skip-bundler requires the project to be exported manually before uploading. Ex: npx expo export && eas update --skip-bundler`;
|
|
143
|
+
}
|
|
144
|
+
throw new Error(error);
|
|
128
145
|
}
|
|
129
146
|
return distRoot;
|
|
130
147
|
}
|
|
@@ -143,37 +160,50 @@ function loadMetadata(distRoot) {
|
|
|
143
160
|
if (metadata.bundler !== 'metro') {
|
|
144
161
|
throw new Error('Only bundles created with Metro are currently supported');
|
|
145
162
|
}
|
|
163
|
+
const platforms = Object.keys(metadata.fileMetadata);
|
|
164
|
+
if (platforms.length === 0) {
|
|
165
|
+
log_1.default.warn('No updates were exported for any platform');
|
|
166
|
+
}
|
|
167
|
+
log_1.default.debug(`Loaded ${platforms.length} platform(s): ${platforms.join(', ')}`);
|
|
146
168
|
return metadata;
|
|
147
169
|
}
|
|
148
170
|
exports.loadMetadata = loadMetadata;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
171
|
+
function filterExportedPlatformsByFlag(record, platformFlag) {
|
|
172
|
+
if (platformFlag === 'all') {
|
|
173
|
+
return record;
|
|
174
|
+
}
|
|
175
|
+
const platform = platformFlag;
|
|
176
|
+
if (!record[platform]) {
|
|
177
|
+
throw new Error(`--platform="${platform}" not found in metadata.json. Available platform(s): ${Object.keys(record).join(', ')}`);
|
|
178
|
+
}
|
|
179
|
+
return { [platform]: record[platform] };
|
|
180
|
+
}
|
|
181
|
+
exports.filterExportedPlatformsByFlag = filterExportedPlatformsByFlag;
|
|
182
|
+
/** Given a directory, load the metadata.json and collect the assets for each platform. */
|
|
183
|
+
async function collectAssetsAsync(dir) {
|
|
184
|
+
const metadata = loadMetadata(dir);
|
|
185
|
+
const collectedAssets = {};
|
|
186
|
+
for (const platform of Object.keys(metadata.fileMetadata)) {
|
|
187
|
+
collectedAssets[platform] = {
|
|
155
188
|
launchAsset: {
|
|
156
189
|
fileExtension: '.bundle',
|
|
157
190
|
contentType: 'application/javascript',
|
|
158
|
-
path: path_1.default.resolve(
|
|
191
|
+
path: path_1.default.resolve(dir, metadata.fileMetadata[platform].bundle),
|
|
159
192
|
},
|
|
160
|
-
assets: metadata.fileMetadata[platform].assets.map(asset => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
fileExtension,
|
|
168
|
-
contentType: guessContentTypeFromExtension(asset.ext),
|
|
169
|
-
path: path_1.default.join(distRoot, asset.path),
|
|
170
|
-
};
|
|
171
|
-
}),
|
|
193
|
+
assets: metadata.fileMetadata[platform].assets.map(asset => ({
|
|
194
|
+
fileExtension: asset.ext ? ensureLeadingPeriod(asset.ext) : undefined,
|
|
195
|
+
contentType: guessContentTypeFromExtension(asset.ext),
|
|
196
|
+
path: path_1.default.join(dir, asset.path),
|
|
197
|
+
})),
|
|
172
198
|
};
|
|
173
199
|
}
|
|
174
|
-
return
|
|
200
|
+
return collectedAssets;
|
|
175
201
|
}
|
|
176
202
|
exports.collectAssetsAsync = collectAssetsAsync;
|
|
203
|
+
// ensure the file extension has a '.' prefix
|
|
204
|
+
function ensureLeadingPeriod(extension) {
|
|
205
|
+
return extension.startsWith('.') ? extension : `.${extension}`;
|
|
206
|
+
}
|
|
177
207
|
async function filterOutAssetsThatAlreadyExistAsync(graphqlClient, uniqueAssetsWithStorageKey) {
|
|
178
208
|
const assetMetadata = await PublishQuery_1.PublishQuery.getAssetMetadataAsync(graphqlClient, uniqueAssetsWithStorageKey.map(asset => asset.storageKey));
|
|
179
209
|
const missingAssetKeys = assetMetadata
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { Platform, Workflow } from '@expo/eas-build-job';
|
|
2
2
|
export declare function resolveWorkflowAsync(projectDir: string, platform: Platform): Promise<Workflow>;
|
|
3
|
+
export declare function resolveWorkflowPerPlatformAsync(projectDir: string): Promise<Record<Platform, Workflow>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveWorkflowAsync = void 0;
|
|
3
|
+
exports.resolveWorkflowPerPlatformAsync = exports.resolveWorkflowAsync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
6
6
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
@@ -32,3 +32,11 @@ async function resolveWorkflowAsync(projectDir, platform) {
|
|
|
32
32
|
return eas_build_job_1.Workflow.MANAGED;
|
|
33
33
|
}
|
|
34
34
|
exports.resolveWorkflowAsync = resolveWorkflowAsync;
|
|
35
|
+
async function resolveWorkflowPerPlatformAsync(projectDir) {
|
|
36
|
+
const [android, ios] = await Promise.all([
|
|
37
|
+
resolveWorkflowAsync(projectDir, eas_build_job_1.Platform.ANDROID),
|
|
38
|
+
resolveWorkflowAsync(projectDir, eas_build_job_1.Platform.IOS),
|
|
39
|
+
]);
|
|
40
|
+
return { android, ios };
|
|
41
|
+
}
|
|
42
|
+
exports.resolveWorkflowPerPlatformAsync = resolveWorkflowPerPlatformAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runAppOnAndroidEmulatorAsync(_appPath: string): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAppOnAndroidEmulatorAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
6
|
+
async function runAppOnAndroidEmulatorAsync(_appPath) {
|
|
7
|
+
log_1.default.error('Not implemented!');
|
|
8
|
+
}
|
|
9
|
+
exports.runAppOnAndroidEmulatorAsync = runAppOnAndroidEmulatorAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runAppOnIosSimulatorAsync(appPath: string): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAppOnIosSimulatorAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
6
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
+
const simulator = tslib_1.__importStar(require("./simulator"));
|
|
8
|
+
const systemRequirements_1 = require("./systemRequirements");
|
|
9
|
+
async function runAppOnIosSimulatorAsync(appPath) {
|
|
10
|
+
await (0, systemRequirements_1.validateSystemRequirementsAsync)();
|
|
11
|
+
const selectedSimulator = await simulator.selectSimulatorAsync();
|
|
12
|
+
await simulator.ensureSimulatorBootedAsync(selectedSimulator);
|
|
13
|
+
await simulator.ensureSimulatorAppOpenedAsync(selectedSimulator.udid);
|
|
14
|
+
const bundleIdentifier = await getAppBundleIdentifierAsync(appPath);
|
|
15
|
+
await simulator.installAppAsync(selectedSimulator.udid, appPath);
|
|
16
|
+
await simulator.launchAppAsync(selectedSimulator.udid, bundleIdentifier);
|
|
17
|
+
}
|
|
18
|
+
exports.runAppOnIosSimulatorAsync = runAppOnIosSimulatorAsync;
|
|
19
|
+
async function getAppBundleIdentifierAsync(appPath) {
|
|
20
|
+
const { stdout, stderr } = await (0, spawn_async_1.default)('xcrun', [
|
|
21
|
+
'plutil',
|
|
22
|
+
'-extract',
|
|
23
|
+
'CFBundleIdentifier',
|
|
24
|
+
'raw',
|
|
25
|
+
path_1.default.join(appPath, 'Info.plist'),
|
|
26
|
+
]);
|
|
27
|
+
if (!stdout) {
|
|
28
|
+
throw new Error(`Could not read app bundle identifier from ${path_1.default.join(appPath, 'Info.plist')}: ${stderr}`);
|
|
29
|
+
}
|
|
30
|
+
return stdout.trim();
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.simctlAsync = void 0;
|
|
4
|
+
const xcrun_1 = require("./xcrun");
|
|
5
|
+
async function simctlAsync(args, options) {
|
|
6
|
+
return (0, xcrun_1.xcrunAsync)(['simctl', ...args], options);
|
|
7
|
+
}
|
|
8
|
+
exports.simctlAsync = simctlAsync;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface IosSimulator {
|
|
2
|
+
runtime: string;
|
|
3
|
+
osVersion: string;
|
|
4
|
+
windowName: string;
|
|
5
|
+
osType: 'iOS';
|
|
6
|
+
state: 'Booted' | 'Shutdown';
|
|
7
|
+
isAvailable: boolean;
|
|
8
|
+
name: string;
|
|
9
|
+
udid: string;
|
|
10
|
+
lastBootedAt?: Date;
|
|
11
|
+
}
|
|
12
|
+
export declare function selectSimulatorAsync(): Promise<IosSimulator>;
|
|
13
|
+
export declare function getFirstBootedIosSimulatorAsync(): Promise<IosSimulator | undefined>;
|
|
14
|
+
export declare function getAvaliableIosSimulatorsListAsync(query?: string): Promise<IosSimulator[]>;
|
|
15
|
+
export declare function ensureSimulatorBootedAsync(simulator: IosSimulator): Promise<void>;
|
|
16
|
+
export declare function openSimulatorAppAsync(simulatorUdid: string): Promise<void>;
|
|
17
|
+
export declare function launchAppAsync(simulatorUdid: string, bundleIdentifier: string): Promise<void>;
|
|
18
|
+
export declare function ensureSimulatorAppOpenedAsync(simulatorUuid: string): Promise<void>;
|
|
19
|
+
export declare function installAppAsync(deviceId: string, filePath: string): Promise<void>;
|
|
20
|
+
export declare function getSimulatorAppIdAsync(): Promise<string | undefined>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSimulatorAppIdAsync = exports.installAppAsync = exports.ensureSimulatorAppOpenedAsync = exports.launchAppAsync = exports.openSimulatorAppAsync = exports.ensureSimulatorBootedAsync = exports.getAvaliableIosSimulatorsListAsync = exports.getFirstBootedIosSimulatorAsync = exports.selectSimulatorAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const osascript = tslib_1.__importStar(require("@expo/osascript"));
|
|
6
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
7
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
8
|
+
const prompts_1 = require("../../prompts");
|
|
9
|
+
const promise_1 = require("../../utils/promise");
|
|
10
|
+
const simctl_1 = require("./simctl");
|
|
11
|
+
async function selectSimulatorAsync() {
|
|
12
|
+
const bootedSimulator = await getFirstBootedIosSimulatorAsync();
|
|
13
|
+
if (bootedSimulator) {
|
|
14
|
+
return bootedSimulator;
|
|
15
|
+
}
|
|
16
|
+
const simulators = await getAvaliableIosSimulatorsListAsync();
|
|
17
|
+
log_1.default.newLine();
|
|
18
|
+
const { selectedSimulator } = await (0, prompts_1.promptAsync)({
|
|
19
|
+
type: 'select',
|
|
20
|
+
message: `Select a simulator to run your app on`,
|
|
21
|
+
name: 'selectedSimulator',
|
|
22
|
+
choices: simulators.map(simulator => ({
|
|
23
|
+
title: `ios ${simulator.osVersion} ${simulator.name}`,
|
|
24
|
+
value: simulator,
|
|
25
|
+
})),
|
|
26
|
+
});
|
|
27
|
+
return selectedSimulator;
|
|
28
|
+
}
|
|
29
|
+
exports.selectSimulatorAsync = selectSimulatorAsync;
|
|
30
|
+
async function getFirstBootedIosSimulatorAsync() {
|
|
31
|
+
const bootedSimulators = await getAvaliableIosSimulatorsListAsync('booted');
|
|
32
|
+
if (bootedSimulators.length > 0) {
|
|
33
|
+
return bootedSimulators[0];
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
exports.getFirstBootedIosSimulatorAsync = getFirstBootedIosSimulatorAsync;
|
|
38
|
+
async function getAvaliableIosSimulatorsListAsync(query) {
|
|
39
|
+
const { stdout } = query
|
|
40
|
+
? await (0, simctl_1.simctlAsync)(['list', 'devices', '--json', query])
|
|
41
|
+
: await (0, simctl_1.simctlAsync)(['list', 'devices', '--json']);
|
|
42
|
+
const info = parseSimControlJsonResults(stdout);
|
|
43
|
+
const iosSimulators = [];
|
|
44
|
+
for (const runtime of Object.keys(info.devices)) {
|
|
45
|
+
// Given a string like 'com.apple.CoreSimulator.SimRuntime.tvOS-13-4'
|
|
46
|
+
const runtimeSuffix = runtime.split('com.apple.CoreSimulator.SimRuntime.').pop();
|
|
47
|
+
if (!runtimeSuffix) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Create an array [tvOS, 13, 4]
|
|
51
|
+
const [osType, ...osVersionComponents] = runtimeSuffix.split('-');
|
|
52
|
+
if (osType === 'iOS') {
|
|
53
|
+
// Join the end components [13, 4] -> '13.4'
|
|
54
|
+
const osVersion = osVersionComponents.join('.');
|
|
55
|
+
const sims = info.devices[runtime];
|
|
56
|
+
for (const device of sims) {
|
|
57
|
+
if (device.isAvailable) {
|
|
58
|
+
iosSimulators.push({
|
|
59
|
+
...device,
|
|
60
|
+
runtime,
|
|
61
|
+
osVersion,
|
|
62
|
+
windowName: `${device.name} (${osVersion})`,
|
|
63
|
+
osType: 'iOS',
|
|
64
|
+
state: device.state,
|
|
65
|
+
lastBootedAt: device.lastBootedAt ? new Date(device.lastBootedAt) : undefined,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return iosSimulators;
|
|
72
|
+
}
|
|
73
|
+
exports.getAvaliableIosSimulatorsListAsync = getAvaliableIosSimulatorsListAsync;
|
|
74
|
+
function parseSimControlJsonResults(input) {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(input);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Nov 15, 2020: Observed this can happen when opening the simulator and the simulator prompts the user to update the xcode command line tools.
|
|
80
|
+
// Unexpected token I in JSON at position 0
|
|
81
|
+
if (error.message.includes('Unexpected token')) {
|
|
82
|
+
log_1.default.error(`Apple's simctl returned malformed JSON:\n${input}`);
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function ensureSimulatorBootedAsync(simulator) {
|
|
88
|
+
if (simulator.state === 'Booted') {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
await (0, simctl_1.simctlAsync)(['boot', simulator.udid]);
|
|
92
|
+
}
|
|
93
|
+
exports.ensureSimulatorBootedAsync = ensureSimulatorBootedAsync;
|
|
94
|
+
async function openSimulatorAppAsync(simulatorUdid) {
|
|
95
|
+
const args = ['-a', 'Simulator'];
|
|
96
|
+
if (simulatorUdid) {
|
|
97
|
+
// This has no effect if the app is already running.
|
|
98
|
+
args.push('--args', '-CurrentDeviceUDID', simulatorUdid);
|
|
99
|
+
}
|
|
100
|
+
await (0, spawn_async_1.default)('open', args);
|
|
101
|
+
}
|
|
102
|
+
exports.openSimulatorAppAsync = openSimulatorAppAsync;
|
|
103
|
+
async function launchAppAsync(simulatorUdid, bundleIdentifier) {
|
|
104
|
+
log_1.default.newLine();
|
|
105
|
+
log_1.default.log('Launching your app...');
|
|
106
|
+
await (0, simctl_1.simctlAsync)(['launch', simulatorUdid, bundleIdentifier]);
|
|
107
|
+
log_1.default.succeed('Successfully launched your app!');
|
|
108
|
+
}
|
|
109
|
+
exports.launchAppAsync = launchAppAsync;
|
|
110
|
+
// I think the app can be open while no simulators are booted.
|
|
111
|
+
async function waitForSimulatorAppToStartAsync(maxWaitTimeMs, intervalMs) {
|
|
112
|
+
log_1.default.newLine();
|
|
113
|
+
log_1.default.log('Waiting for Simulator app to start...');
|
|
114
|
+
const startTime = Date.now();
|
|
115
|
+
while (Date.now() - startTime < maxWaitTimeMs) {
|
|
116
|
+
if (await isSimulatorAppRunningAsync()) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await (0, promise_1.sleepAsync)(Math.min(intervalMs, Math.max(maxWaitTimeMs - (Date.now() - startTime), 0)));
|
|
120
|
+
}
|
|
121
|
+
throw new Error('Timed out waiting for the iOS simulator to start.');
|
|
122
|
+
}
|
|
123
|
+
async function isSimulatorAppRunningAsync() {
|
|
124
|
+
try {
|
|
125
|
+
const result = await osascript.execAsync('tell app "System Events" to count processes whose name is "Simulator"');
|
|
126
|
+
if (result.trim() === '0') {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (error.message.includes('Application isn’t running')) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
async function ensureSimulatorAppOpenedAsync(simulatorUuid) {
|
|
139
|
+
if (await isSimulatorAppRunningAsync()) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
await openSimulatorAppAsync(simulatorUuid);
|
|
143
|
+
await waitForSimulatorAppToStartAsync(60 * 1000, 1000);
|
|
144
|
+
}
|
|
145
|
+
exports.ensureSimulatorAppOpenedAsync = ensureSimulatorAppOpenedAsync;
|
|
146
|
+
async function installAppAsync(deviceId, filePath) {
|
|
147
|
+
log_1.default.newLine();
|
|
148
|
+
log_1.default.log('Installing your app on the simulator...');
|
|
149
|
+
await (0, simctl_1.simctlAsync)(['install', deviceId, filePath]);
|
|
150
|
+
log_1.default.succeed('Successfully installed your app on the simulator!');
|
|
151
|
+
}
|
|
152
|
+
exports.installAppAsync = installAppAsync;
|
|
153
|
+
async function getSimulatorAppIdAsync() {
|
|
154
|
+
try {
|
|
155
|
+
return (await osascript.execAsync('id of app "Simulator"')).trim();
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.getSimulatorAppIdAsync = getSimulatorAppIdAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validateSystemRequirementsAsync(): Promise<void>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSystemRequirementsAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
8
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
9
|
+
const prompts_1 = require("../../prompts");
|
|
10
|
+
const simulator_1 = require("./simulator");
|
|
11
|
+
const xcode = tslib_1.__importStar(require("./xcode"));
|
|
12
|
+
const xcrun_1 = require("./xcrun");
|
|
13
|
+
function assertPlatform() {
|
|
14
|
+
if (process.platform !== 'darwin') {
|
|
15
|
+
log_1.default.error('iOS simulator apps can only be run on macOS devices.');
|
|
16
|
+
throw Error('iOS simulator apps can only be run on macOS devices.');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function assertCorrectXcodeVersionInstalledAsync() {
|
|
20
|
+
const xcodeVersion = await xcode.getXcodeVersionAsync();
|
|
21
|
+
if (!xcodeVersion) {
|
|
22
|
+
const { goToAppStore } = await (0, prompts_1.promptAsync)({
|
|
23
|
+
type: 'select',
|
|
24
|
+
message: 'Xcode needs to be installed, would you like to continue to the App Store?',
|
|
25
|
+
name: 'goToAppStore',
|
|
26
|
+
choices: [
|
|
27
|
+
{ title: 'Yes', value: true },
|
|
28
|
+
{ title: 'No', value: false },
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
if (goToAppStore) {
|
|
32
|
+
await xcode.openAppStoreAsync(xcode.APP_STORE_ID);
|
|
33
|
+
}
|
|
34
|
+
throw Error('Please try again once Xcode is installed');
|
|
35
|
+
}
|
|
36
|
+
if (semver_1.default.lt(xcodeVersion, xcode.MIN_XCODE_VERSION)) {
|
|
37
|
+
throw Error(`Xcode version ${chalk_1.default.bold(xcodeVersion)} is too old. Please upgrade to version ${chalk_1.default.bold(xcode.MIN_XCODE_VERSION)} or higher.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function ensureXcrunInstalledAsync() {
|
|
41
|
+
if (!(0, xcrun_1.isXcrunInstalledAsync)()) {
|
|
42
|
+
const { installXcrun } = await (0, prompts_1.promptAsync)({
|
|
43
|
+
type: 'select',
|
|
44
|
+
message: 'Xcode Command Line Tools need to be installed, continue?',
|
|
45
|
+
name: 'installXcrun',
|
|
46
|
+
choices: [
|
|
47
|
+
{ title: 'Yes', value: true },
|
|
48
|
+
{ title: 'No', value: false },
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
if (installXcrun) {
|
|
52
|
+
await (0, xcrun_1.installXcrunAsync)();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
throw Error('Please try again once Xcode Command Line Tools are installed');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function assertSimulatorAppInstalledAsync() {
|
|
59
|
+
const simulatorAppId = await (0, simulator_1.getSimulatorAppIdAsync)();
|
|
60
|
+
if (!simulatorAppId) {
|
|
61
|
+
throw new Error(`Can't determine id of Simulator app; the Simulator is most likely not installed on this machine. Run 'sudo xcode-select -s /Applications/Xcode.app'`);
|
|
62
|
+
}
|
|
63
|
+
if (simulatorAppId !== 'com.apple.iphonesimulator' &&
|
|
64
|
+
simulatorAppId !== 'com.apple.CoreSimulator.SimulatorTrampoline') {
|
|
65
|
+
throw new Error(`Simulator is installed but is identified as '${simulatorAppId}', can't recognize what that is`);
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
// make sure we can run simctl
|
|
69
|
+
await (0, spawn_async_1.default)('xcrun', ['simctl', 'help']);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
log_1.default.warn(`Unable to run simctl:\n${error.toString()}`);
|
|
73
|
+
throw new Error('xcrun is not configured correctly. Ensure `sudo xcode-select --reset` works before running this command again.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function validateSystemRequirementsAsync() {
|
|
77
|
+
assertPlatform();
|
|
78
|
+
await assertCorrectXcodeVersionInstalledAsync();
|
|
79
|
+
await ensureXcrunInstalledAsync();
|
|
80
|
+
await assertSimulatorAppInstalledAsync();
|
|
81
|
+
}
|
|
82
|
+
exports.validateSystemRequirementsAsync = validateSystemRequirementsAsync;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openAppStoreAsync = exports.getXcodeVersionAsync = exports.APP_STORE_ID = exports.MIN_XCODE_VERSION = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
8
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
9
|
+
// Based on the RN docs (Aug 2020).
|
|
10
|
+
exports.MIN_XCODE_VERSION = '9.4.0';
|
|
11
|
+
exports.APP_STORE_ID = '497799835';
|
|
12
|
+
async function getXcodeVersionAsync() {
|
|
13
|
+
var _a;
|
|
14
|
+
try {
|
|
15
|
+
const { stdout } = await (0, spawn_async_1.default)('xcodebuild', ['-version']);
|
|
16
|
+
const version = (_a = stdout.match(/Xcode (\d+\.\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
17
|
+
const semverFormattedVersion = `${version}.0`;
|
|
18
|
+
if (!semver_1.default.valid(semverFormattedVersion)) {
|
|
19
|
+
log_1.default.warn(`Xcode version ${chalk_1.default.bold(version)} is in unknown format. Expected format is ${chalk_1.default.bold('12.0')}.`);
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
return semverFormattedVersion;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// not installed
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.getXcodeVersionAsync = getXcodeVersionAsync;
|
|
30
|
+
async function openAppStoreAsync(appId) {
|
|
31
|
+
const link = getAppStoreLink(appId);
|
|
32
|
+
await (0, spawn_async_1.default)(`open`, [link]);
|
|
33
|
+
}
|
|
34
|
+
exports.openAppStoreAsync = openAppStoreAsync;
|
|
35
|
+
function getAppStoreLink(appId) {
|
|
36
|
+
if (process.platform === 'darwin') {
|
|
37
|
+
// TODO: Is there ever a case where the macappstore isn't available on mac?
|
|
38
|
+
return `macappstore://itunes.apple.com/app/id${appId}`;
|
|
39
|
+
}
|
|
40
|
+
return `https://apps.apple.com/us/app/id${appId}`;
|
|
41
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SpawnOptions, SpawnResult } from '@expo/spawn-async';
|
|
2
|
+
export declare function xcrunAsync(args: string[], options?: SpawnOptions): Promise<SpawnResult>;
|
|
3
|
+
export declare function isXcrunInstalledAsync(): Promise<boolean>;
|
|
4
|
+
export declare function installXcrunAsync(): Promise<void>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installXcrunAsync = exports.isXcrunInstalledAsync = exports.xcrunAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
8
|
+
const promise_1 = require("../../utils/promise");
|
|
9
|
+
async function xcrunAsync(args, options) {
|
|
10
|
+
try {
|
|
11
|
+
return await (0, spawn_async_1.default)('xcrun', args, options);
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
throwXcrunError(e);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.xcrunAsync = xcrunAsync;
|
|
18
|
+
function throwXcrunError(e) {
|
|
19
|
+
var _a;
|
|
20
|
+
if (isLicenseOutOfDate(e.stdout) || isLicenseOutOfDate(e.stderr)) {
|
|
21
|
+
throw new Error('Xcode license is not accepted. Please run `sudo xcodebuild -license`.');
|
|
22
|
+
}
|
|
23
|
+
else if ((_a = e.stderr) === null || _a === void 0 ? void 0 : _a.includes('not a developer tool or in PATH')) {
|
|
24
|
+
throw new Error(`You may need to run ${chalk_1.default.bold('sudo xcode-select -s /Applications/Xcode.app')} and try again.`);
|
|
25
|
+
}
|
|
26
|
+
if (Array.isArray(e.output)) {
|
|
27
|
+
e.message += '\n' + e.output.join('\n').trim();
|
|
28
|
+
}
|
|
29
|
+
else if (e.stderr) {
|
|
30
|
+
e.message += '\n' + e.stderr;
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Some other error occurred while running xcrun command.
|
|
33
|
+
${e.message}`);
|
|
34
|
+
}
|
|
35
|
+
function isLicenseOutOfDate(text) {
|
|
36
|
+
if (!text) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const lower = text.toLowerCase();
|
|
40
|
+
return lower.includes('xcode') && lower.includes('license');
|
|
41
|
+
}
|
|
42
|
+
async function isXcrunInstalledAsync() {
|
|
43
|
+
try {
|
|
44
|
+
await (0, spawn_async_1.default)('xcrun', ['--version']);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.isXcrunInstalledAsync = isXcrunInstalledAsync;
|
|
52
|
+
async function installXcrunAsync() {
|
|
53
|
+
await (0, spawn_async_1.default)('xcode-select', ['--install']);
|
|
54
|
+
await waitForXcrunInstallToFinishAsync(60 * 1000, 1000);
|
|
55
|
+
}
|
|
56
|
+
exports.installXcrunAsync = installXcrunAsync;
|
|
57
|
+
async function waitForXcrunInstallToFinishAsync(maxWaitTimeMs, intervalMs) {
|
|
58
|
+
log_1.default.newLine();
|
|
59
|
+
log_1.default.log('Waiting for Xcode Command Line Tools install to finish...');
|
|
60
|
+
const startTime = Date.now();
|
|
61
|
+
while (Date.now() - startTime < maxWaitTimeMs) {
|
|
62
|
+
if (await isXcrunInstalledAsync()) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
await (0, promise_1.sleepAsync)(Math.min(intervalMs, Math.max(maxWaitTimeMs - (Date.now() - startTime), 0)));
|
|
66
|
+
}
|
|
67
|
+
throw new Error('Timed out waiting for Xcode Command Line Tools install to finish');
|
|
68
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AppPlatform } from '../graphql/generated';
|
|
2
|
+
export interface RunArchiveFlags {
|
|
3
|
+
latest?: boolean;
|
|
4
|
+
id?: string;
|
|
5
|
+
path?: string;
|
|
6
|
+
url?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function runAsync(simulatorBuildPath: string, selectedPlatform: AppPlatform): Promise<void>;
|