From e683cd5e51330d475db2e68ab62623c10c87d93c Mon Sep 17 00:00:00 2001 From: Luca Micieli Date: Wed, 6 Dec 2023 08:48:21 +0100 Subject: [PATCH] feat: support ios configuration --- packages/cli/src/application/buildIos.ts | 50 ++++++++++++------------ packages/cli/src/application/iosUtils.ts | 16 ++++---- packages/cli/src/application/runIos.ts | 10 +++-- packages/cli/src/application/utils.ts | 2 +- packages/cli/src/commands/build.ts | 6 ++- packages/cli/src/commands/run.ts | 4 +- 6 files changed, 48 insertions(+), 40 deletions(-) diff --git a/packages/cli/src/application/buildIos.ts b/packages/cli/src/application/buildIos.ts index d74a213..a921576 100644 --- a/packages/cli/src/application/buildIos.ts +++ b/packages/cli/src/application/buildIos.ts @@ -1,31 +1,33 @@ -import path from 'path'; -import { executeCommand, getAppName, getProjectRootDir, getRootDestinationFolder } from './utils'; -import { ux } from '@oclif/core'; -import { getBuildFolder, getIosBuildDestination, iosBuildPlatforms, IosPlatform } from './iosUtils'; -import { getIosFlavors } from './config'; +import path from "path"; +import { executeCommand, getAppName, getProjectRootDir, getRootDestinationFolder } from "./utils"; +import { ux } from "@oclif/core"; +import { getBuildFolder, getIosBuildDestination, iosBuildPlatforms, IosPlatform } from "./iosUtils"; +import { getIosFlavors } from "./config"; +import logger from "./logger"; const appName = getAppName(); function installPods() { - ux.debug('Pod install'); - const iosFolder = path.join(getProjectRootDir(), 'ios'); - executeCommand('pod install', { cwd: iosFolder }); + ux.debug("Pod install"); + const iosFolder = path.join(getProjectRootDir(), "ios"); + executeCommand("pod install", { cwd: iosFolder }); } -function _buildIos(buildType?: string, platform: IosPlatform = iosBuildPlatforms.simulator) { - const iosFolder = path.join(getProjectRootDir(), 'ios'); +function _buildIos(schema?: string, config = "Debug", platform: IosPlatform = iosBuildPlatforms.simulator) { + const iosFolder = path.join(getProjectRootDir(), "ios"); const workspacePath = path.join(iosFolder, `${appName}.xcworkspace`); - const buildFlavor = getIosFlavors(buildType); + const buildFlavor = getIosFlavors(schema); if (!buildFlavor) { - throw new Error(`No build flavor found for ${buildType}`); + throw new Error(`No build flavor found for ${schema}`); } + logger.log('builfing config', config); const archivePath = `${iosFolder}/build/Products/${appName}.xcarchive`; const buildCommand = `RCT_NO_LAUNCH_PACKAGER=true xcodebuild \ -workspace "${workspacePath}" \ -scheme "${buildFlavor.scheme}" \ - -configuration ${buildFlavor.config} \ + -configuration ${config || buildFlavor.config} \ -sdk ${platform.name} \ -archivePath '${archivePath}' \ -derivedDataPath ${iosFolder}/DerivedData/${appName} \ @@ -34,20 +36,20 @@ function _buildIos(buildType?: string, platform: IosPlatform = iosBuildPlatforms executeCommand(buildCommand); - // todo handle Debug/release - const appFolder = getBuildFolder(getAppName(), false, buildFlavor.flavorDir, platform.name); - const source = `${iosFolder}/DerivedData/${appName}/build/Products/Debug-${platform.name}/${appFolder}`; - const { destinationDir, destination } = getIosBuildDestination(platform, buildFlavor.flavorDir); + // todo handle Debug/release + const appFolder = getBuildFolder(getAppName(), config, buildFlavor.flavorDir, platform.name); + const source = `${iosFolder}/DerivedData/${appName}/build/Products/${config}-${platform.name}/${appFolder}`; + const { destinationDir, destination } = getIosBuildDestination(platform, buildFlavor.flavorDir, config); - executeCommand(`mkdir -p ${destinationDir}`); - executeCommand(`rm -rf ${destination}`); - const copyCommand = `cp -a '${source}' '${destination}'`; - executeCommand(copyCommand); - return destination; + executeCommand(`mkdir -p ${destinationDir}`); + executeCommand(`rm -rf ${destination}`); + const copyCommand = `cp -a '${source}' '${destination}'`; + executeCommand(copyCommand); + return destination; } -export function buildIos(buildType?: string, platform: IosPlatform = iosBuildPlatforms.simulator) { +export function buildIos(schema?: string, config = "Debug", platform: IosPlatform = iosBuildPlatforms.simulator) { // installPods(); - _buildIos(buildType, platform); + _buildIos(schema, config, platform); } diff --git a/packages/cli/src/application/iosUtils.ts b/packages/cli/src/application/iosUtils.ts index 80502f9..a41b047 100644 --- a/packages/cli/src/application/iosUtils.ts +++ b/packages/cli/src/application/iosUtils.ts @@ -15,9 +15,9 @@ export const iosBuildPlatforms = { } as const; export type IosPlatform = { - name: 'iphonesimulator'; - ext: 'app'; - buildCmd: 'build'; + name: "iphonesimulator"; + ext: "app"; + buildCmd: "build"; } | { name: "iphoneos", ext: "app", @@ -28,15 +28,15 @@ export function getIosBuildDestination(platform: { ext: string; buildCmd: string; name: string -}, buildType: string, buildId?: string) { +}, buildType: string, config: string, buildId?: string) { const baseBuildFolder = buildId ? getBuildFolderByBuildId(buildId) : getRootDestinationFolder(); // todo handle Debug/release const destinationDir = path.join( baseBuildFolder, - 'ios', + "ios", `${platform.name}-${buildType}`, - 'Debug' + config ); const destination = path.join(destinationDir, `${getAppName()}.${platform.ext}`); return { destinationDir, destination }; @@ -58,14 +58,14 @@ function getTargetPaths(buildSettings: string) { throw new Error("app destination not found"); } -export function getBuildFolder(projectName: string, release: boolean, buildFlavor: string, sdk: string) { +export function getBuildFolder(projectName: string, configuration: string, buildFlavor: string, sdk: string) { const buildSettings = executeCommandWithOutPut( // todo remove iso and support project `xcodebuild \ -workspace ./ios/${projectName}.xcworkspace \ -scheme ${buildFlavor} \ -sdk ${sdk}\ - -configuration ${release ? "Release" : "Debug"} \ + -configuration ${configuration} \ -showBuildSettings\ -json`, { diff --git a/packages/cli/src/application/runIos.ts b/packages/cli/src/application/runIos.ts index 36aa4ff..2b1f223 100644 --- a/packages/cli/src/application/runIos.ts +++ b/packages/cli/src/application/runIos.ts @@ -64,6 +64,7 @@ function getBootedDevices(allDevices: Device[]) { function checkBuildPresent( buildType: string, + config: string, target: { ext: string; buildCmd: string; @@ -71,7 +72,7 @@ function checkBuildPresent( }, buildId?: string ) { - const { destination } = getIosBuildDestination(target, buildType, buildId); + const { destination } = getIosBuildDestination(target, buildType,config, buildId); return fs.existsSync(destination); } @@ -172,18 +173,19 @@ function waitForBootedSimulatorOrTimeout() { export async function runApp( buildType?: string, + config?:string, iosPlatform: IosPlatform = iosBuildPlatforms.simulator, forceBuild?: boolean, buildId?: string ) { const buildFlavor = getIosFlavors(buildType); - if (forceBuild || !checkBuildPresent(buildFlavor.scheme, iosPlatform, buildId)) { + if (forceBuild || !checkBuildPresent(buildFlavor.scheme, config || buildFlavor.config, iosPlatform, buildId)) { logger.info('Build not present, starting build'); if (buildId) { throw new Error(`The requested build id ${buildId} does not contain an ios build for scheme ${buildFlavor}`); } - buildIos(buildType, iosPlatform); + buildIos(buildType,config, iosPlatform); } else { logger.info('Build already present, skipping build'); } @@ -227,7 +229,7 @@ export async function runApp( devicesToRun.push(...requestedDevices); } - const { destination } = getIosBuildDestination(iosPlatform, buildFlavor.scheme, buildId); + const { destination } = getIosBuildDestination(iosPlatform, buildFlavor.scheme, config || buildFlavor.config, buildId); for (const device of devicesToRun) { installApp(device, destination); diff --git a/packages/cli/src/application/utils.ts b/packages/cli/src/application/utils.ts index 1a403b0..1641b2a 100644 --- a/packages/cli/src/application/utils.ts +++ b/packages/cli/src/application/utils.ts @@ -11,7 +11,7 @@ import getAdbPath from '@react-native-community/cli-platform-android/build/comma const execAsync = util.promisify(require('child_process').exec); export function executeCommand(command: string, options?: ExecSyncOptionsWithBufferEncoding) { - execSync(command, { stdio: 'inherit', ...(options || {}) }); + execSync(command, { stdio: 'inherit', env: process.env, ...(options || {}) }); } export function executeCommandWithOutPut(command: string, options?: ExecSyncOptions) { diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts index e38389c..b8138d2 100644 --- a/packages/cli/src/commands/build.ts +++ b/packages/cli/src/commands/build.ts @@ -18,7 +18,8 @@ export default class Build extends Command { static flags = { ios: Flags.boolean({ char: 'i', description: 'Generate ios native build' }), android: Flags.boolean({ char: 'a', description: 'Generate android native build' }), - flavor: Flags.string({ char: 'f', description: 'Specify flavor to build' }), + flavor: Flags.string({ char: 'f', description: 'Specify flavor/schema to build' }), + config: Flags.string({ char: 'c', description: 'Specify the config to build' }), release: Flags.boolean({ description: 'Optimized release build', default: false }), incremental: Flags.boolean({ char: 'I', description: 'Incremental build', default: false }), iosPlatform: Flags.string({ @@ -35,6 +36,7 @@ export default class Build extends Command { const shouldBuildIos = flags.ios; const buildFlavor = flags.flavor; const release = flags.release; + const config = flags.config; const incremental = flags.incremental; let iosPlatform = flags.iosPlatform === 'simulator' ? iosBuildPlatforms.simulator : iosBuildPlatforms.iphone; @@ -42,7 +44,7 @@ export default class Build extends Command { if (shouldBuildIos) { logger.info('Building ios app'); - buildIos(buildFlavor, iosPlatform); + buildIos(buildFlavor, config, iosPlatform); } if (shouldBuildAndroid) { logger.info('Building android'); diff --git a/packages/cli/src/commands/run.ts b/packages/cli/src/commands/run.ts index 00beeb4..9c52c5e 100644 --- a/packages/cli/src/commands/run.ts +++ b/packages/cli/src/commands/run.ts @@ -16,6 +16,7 @@ export default class Run extends RemoteAwareCommand { android: Flags.boolean({ char: 'a', description: 'Run the android app' }), ios: Flags.boolean({ char: 'i', description: 'Run the ios app' }), flavor: Flags.string({ char: 'f', description: 'Specify the android flavor or the ios scheme to build' }), + config: Flags.string({ char: 'c', description: 'Specify the config to build' }), verbose: Flags.boolean({ description: 'Verbose output' }), iosPlatform: Flags.string({ description: 'Specify the ios platform to run on', @@ -40,6 +41,7 @@ export default class Run extends RemoteAwareCommand { const shouldRunAndroid = flags.android ?? flags.all; const shouldRunIos = flags.ios ?? flags.all; const buildFlavor = flags.flavor; + const config = flags.config; const forceBuild = flags.forceBuild; let buildId = flags.buildId; let iosPlatform = flags.iosPlatform === 'simulator' ? iosBuildPlatforms.simulator : iosBuildPlatforms.iphone; @@ -72,7 +74,7 @@ export default class Run extends RemoteAwareCommand { } if (shouldRunIos) { logger.info(`Running ios app ${buildFlavor ? `with flavor ${buildFlavor}` : ''}`); - await runIos(buildFlavor!, iosPlatform, forceBuild, buildId); + await runIos(buildFlavor!,config, iosPlatform, forceBuild, buildId); } logger.info(`Run finished in ${((performance.now() - start) / 1000).toFixed(1)} seconds`); this.exit(0);