|
| 1 | +import type { BuildFlags } from './buildOptions.js'; |
| 2 | +import { supportedPlatforms } from '../../supportedPlatforms.js'; |
| 3 | +import { ApplePlatform, XcodeProjectInfo } from '../../types/index.js'; |
| 4 | +import { logger } from '@callstack/rnef-tools'; |
| 5 | +import { getConfiguration } from './getConfiguration.js'; |
| 6 | +import { simulatorDestinationMap } from './simulatorDestinationMap.js'; |
| 7 | +import { spinner } from '@clack/prompts'; |
| 8 | +import spawn from 'nano-spawn'; |
| 9 | +import { selectFromInteractiveMode } from '../../utils/selectFromInteractiveMode.js'; |
| 10 | +import path from 'node:path'; |
| 11 | + |
| 12 | +const buildProject = async ( |
| 13 | + xcodeProject: XcodeProjectInfo, |
| 14 | + platformName: ApplePlatform, |
| 15 | + udid: string | undefined, |
| 16 | + args: BuildFlags |
| 17 | +) => { |
| 18 | + normalizeArgs(args, xcodeProject); |
| 19 | + const simulatorDest = simulatorDestinationMap[platformName]; |
| 20 | + |
| 21 | + if (!simulatorDest) { |
| 22 | + throw new Error( |
| 23 | + `Unknown platform: ${platformName}. Please, use one of: ${Object.values( |
| 24 | + supportedPlatforms |
| 25 | + ).join(', ')}.` |
| 26 | + ); |
| 27 | + } |
| 28 | + |
| 29 | + const { scheme, mode } = args.interactive |
| 30 | + ? await selectFromInteractiveMode(xcodeProject, args.scheme, args.mode) |
| 31 | + : await getConfiguration( |
| 32 | + xcodeProject, |
| 33 | + args.scheme, |
| 34 | + args.mode, |
| 35 | + platformName |
| 36 | + ); |
| 37 | + |
| 38 | + const xcodebuildArgs = [ |
| 39 | + xcodeProject.isWorkspace ? '-workspace' : '-project', |
| 40 | + xcodeProject.name, |
| 41 | + ...(args.buildFolder ? ['-derivedDataPath', args.buildFolder] : []), |
| 42 | + '-configuration', |
| 43 | + mode, |
| 44 | + '-scheme', |
| 45 | + scheme, |
| 46 | + '-destination', |
| 47 | + (() => { |
| 48 | + if (args.device && typeof args.device === 'string') { |
| 49 | + // Check if the device argument looks like a UDID (assuming UDIDs are alphanumeric and have specific length) |
| 50 | + const isUDID = /^[A-Fa-f0-9-]{25,}$/.test(args.device); |
| 51 | + if (isUDID) { |
| 52 | + return `id=${args.device}`; |
| 53 | + } else { |
| 54 | + // If it's a device name |
| 55 | + return `name=${args.device}`; |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + return udid |
| 60 | + ? `id=${udid}` |
| 61 | + : mode === 'Debug' || args.device |
| 62 | + ? `generic/platform=${simulatorDest}` |
| 63 | + : `generic/platform=${platformName}` + |
| 64 | + (args.destination ? ',' + args.destination : ''); |
| 65 | + })(), |
| 66 | + ]; |
| 67 | + |
| 68 | + if (args.extraParams) { |
| 69 | + xcodebuildArgs.push(...args.extraParams); |
| 70 | + } |
| 71 | + |
| 72 | + const loader = spinner(); |
| 73 | + loader.start( |
| 74 | + `Builing the app with xcodebuild for ${scheme} scheme in ${mode} mode.` |
| 75 | + ); |
| 76 | + logger.debug(`Running "xcodebuild ${xcodebuildArgs.join(' ')}.`); |
| 77 | + |
| 78 | + try { |
| 79 | + await spawn('xcodebuild', xcodebuildArgs, { |
| 80 | + stdio: logger.isVerbose() ? 'inherit' : ['ignore', 'ignore', 'inherit'], |
| 81 | + }); |
| 82 | + loader.stop( |
| 83 | + `Built the app with xcodebuild for ${scheme} scheme in ${mode} mode.` |
| 84 | + ); |
| 85 | + } catch (error) { |
| 86 | + loader.stop( |
| 87 | + 'Running xcodebuild failed. Check the error message above for details.', |
| 88 | + 1 |
| 89 | + ); |
| 90 | + throw error; |
| 91 | + } |
| 92 | +}; |
| 93 | + |
| 94 | +function normalizeArgs(args: BuildFlags, xcodeProject: XcodeProjectInfo) { |
| 95 | + if (!args.mode) { |
| 96 | + args.mode = 'Debug'; |
| 97 | + } |
| 98 | + if (!args.scheme) { |
| 99 | + args.scheme = path.basename( |
| 100 | + xcodeProject.name, |
| 101 | + path.extname(xcodeProject.name) |
| 102 | + ); |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +export { buildProject }; |
0 commit comments