xref: /expo/tools/src/commands/PrebuildPackages.ts (revision a272999e)
1import { Command } from '@expo/commander';
2import chalk from 'chalk';
3import { performance } from 'perf_hooks';
4
5import logger from '../Logger';
6import { Package, getPackageByName } from '../Packages';
7import {
8  buildFrameworksForProjectAsync,
9  cleanTemporaryFilesAsync,
10  cleanFrameworksAsync,
11  generateXcodeProjectSpecAsync,
12  PACKAGES_TO_PREBUILD,
13} from '../prebuilds/Prebuilder';
14import XcodeProject from '../prebuilds/XcodeProject';
15
16type ActionOptions = {
17  removeArtifacts: boolean;
18  cleanCache: boolean;
19  generateSpecs: boolean;
20};
21
22async function main(packageNames: string[], options: ActionOptions) {
23  const filteredPackageNames =
24    packageNames.length > 0
25      ? packageNames.filter((name) => PACKAGES_TO_PREBUILD.includes(name))
26      : PACKAGES_TO_PREBUILD;
27
28  if (options.cleanCache) {
29    logger.info('�� Cleaning shared derived data directory');
30    await XcodeProject.cleanBuildFolderAsync();
31  }
32
33  const packages = filteredPackageNames.map(getPackageByName).filter(Boolean) as Package[];
34
35  if (options.removeArtifacts) {
36    logger.info('�� Removing existing artifacts');
37    await cleanFrameworksAsync(packages);
38    // Stop here, it doesn't make much sense to build them again ;)
39    return;
40  }
41
42  for (const pkg of packages) {
43    logger.info(`�� Prebuilding ${chalk.green(pkg.packageName)}`);
44
45    const startTime = performance.now();
46    const xcodeProject = await generateXcodeProjectSpecAsync(pkg);
47
48    if (!options.generateSpecs) {
49      await buildFrameworksForProjectAsync(xcodeProject);
50      await cleanTemporaryFilesAsync(xcodeProject);
51    }
52
53    const endTime = performance.now();
54    const timeDiff = (endTime - startTime) / 1000;
55    logger.success('   Finished in: %s\n', chalk.magenta(timeDiff.toFixed(2) + 's'));
56  }
57}
58
59export default (program: Command) => {
60  program
61    .command('prebuild-packages [packageNames...]')
62    .description('Generates `.xcframework` artifacts for iOS packages.')
63    .alias('prebuild')
64    .option('-r, --remove-artifacts', 'Removes `.xcframework` artifacts for given packages.', false)
65    .option('-c, --clean-cache', 'Cleans the shared derived data folder before prebuilding.', false)
66    .option('-g, --generate-specs', 'Only generates project specs', false)
67    .asyncAction(main);
68};
69