diff --git a/packages/sdk-android/src/runner.ts b/packages/sdk-android/src/runner.ts index 475f01494..386527fec 100644 --- a/packages/sdk-android/src/runner.ts +++ b/packages/sdk-android/src/runner.ts @@ -29,6 +29,7 @@ import { RnvPlatform, logInfo, RnvPlatformKey, + execCLI, } from '@rnv/core'; import { parseAndroidManifestSync } from './manifestParser'; import { @@ -186,7 +187,18 @@ export const getAndroidDeviceToRunOn = async () => { export const runAndroid = async (device: AndroidDevice) => { logDefault('runAndroid', `target:${device.udid}`); - + const c = getContext(); + const { uninstall } = c.program.opts(); + if (uninstall) { + const packageId = getConfigProp('id'); + if (packageId) { + try { + await execCLI(CLI_ANDROID_ADB, `uninstall ${packageId}`, { silent: true }); + } catch (e) { + return Promise.reject(`Failed to uninstall ${packageId}`); + } + } + } await runReactNativeAndroid(device); }; diff --git a/packages/sdk-android/src/taskOptions.ts b/packages/sdk-android/src/taskOptions.ts index c0b760765..078619e58 100644 --- a/packages/sdk-android/src/taskOptions.ts +++ b/packages/sdk-android/src/taskOptions.ts @@ -18,4 +18,8 @@ export const TaskOptions = createTaskOptionsMap([ altKey: 'resetAdb', description: 'Forces to reset android adb', }, + { + key: 'uninstall', + description: 'Uninstall the app with the current id', + }, ]); diff --git a/packages/sdk-android/src/tasks/taskRun.ts b/packages/sdk-android/src/tasks/taskRun.ts index e3f8c2968..dda342ced 100644 --- a/packages/sdk-android/src/tasks/taskRun.ts +++ b/packages/sdk-android/src/tasks/taskRun.ts @@ -34,6 +34,7 @@ export default createTask({ ...RnvTaskOptionPresets.withRun(), TaskOptions.resetAdb, TaskOptions.skipTargetCheck, + TaskOptions.uninstall, ], platforms: SdkPlatforms, }); diff --git a/packages/sdk-react-native/src/androidRunner.ts b/packages/sdk-react-native/src/androidRunner.ts index f73c0ddb6..69bf29783 100644 --- a/packages/sdk-react-native/src/androidRunner.ts +++ b/packages/sdk-react-native/src/androidRunner.ts @@ -12,6 +12,9 @@ import { CoreEnvVars, ExecOptionsPresets, getContext, + execCLI, + logWarning, + inquirerPrompt, } from '@rnv/core'; import { EnvVars } from './env'; import { getEntryFile } from '@rnv/sdk-utils'; @@ -95,20 +98,56 @@ export const runReactNativeAndroid = async (device: { udid?: string } | undefine if (udid) { command += ` --deviceId=${udid}`; } + const executeCommand = async () => { + return executeAsync(command, { + env: { + ...CoreEnvVars.BASE(), + ...CoreEnvVars.RNV_EXTENSIONS(), + ...EnvVars.RCT_METRO_PORT(), + ...EnvVars.RNV_REACT_NATIVE_PATH(), + ...EnvVars.RNV_APP_ID(), + ...EnvVars.RNV_SKIP_LINKING(), + }, + cwd: appFolder, + // To display react-native CLI logs in RNV executed terminal + ...ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER, + }); + }; - return executeAsync(command, { - env: { - ...CoreEnvVars.BASE(), - ...CoreEnvVars.RNV_EXTENSIONS(), - ...EnvVars.RCT_METRO_PORT(), - ...EnvVars.RNV_REACT_NATIVE_PATH(), - ...EnvVars.RNV_APP_ID(), - ...EnvVars.RNV_SKIP_LINKING(), - }, - cwd: appFolder, - //This is required to make rn cli logs visible in rnv executed terminal - ...ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER, - }); + try { + return await executeCommand(); + } catch (error) { + const packageId = getConfigProp('id'); + if (packageId) { + const { confirm } = await inquirerPrompt({ + name: 'confirm', + type: 'confirm', + message: `Failed to build the app. Try to uninstall and retry?`, + }); + + if (confirm) { + try { + await execCLI('androidAdb', `uninstall ${packageId}`, { silent: true }); + } catch (e) { + return Promise.reject(`Failed to uninstall ${packageId}`); + } + + return await executeCommand(); + } else { + if (typeof error === 'string') { + return Promise.reject(error); + } else if (error instanceof Error) { + return Promise.reject(error.message); + } + } + } else { + if (typeof error === 'string') { + return Promise.reject(error); + } else if (error instanceof Error) { + return Promise.reject(error.message); + } + } + } }; export const buildReactNativeAndroid = async () => {