From 1f5e8399134637c864241c06774df0c43ed94316 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Tue, 17 Mar 2020 12:23:34 +0100 Subject: [PATCH 1/2] refactor: unify apk build and install process --- .../__tests__/buildAndInstallApk.test.ts | 224 ++++++++++++++ .../__tests__/runOnAllDevices.test.ts | 12 +- .../commands/runAndroid/buildAndInstallApk.ts | 280 ++++++++++++++++++ .../src/commands/runAndroid/index.ts | 100 +------ .../commands/runAndroid/runOnAllDevices.ts | 68 +---- 5 files changed, 522 insertions(+), 162 deletions(-) create mode 100644 packages/platform-android/src/commands/runAndroid/__tests__/buildAndInstallApk.test.ts create mode 100644 packages/platform-android/src/commands/runAndroid/buildAndInstallApk.ts diff --git a/packages/platform-android/src/commands/runAndroid/__tests__/buildAndInstallApk.test.ts b/packages/platform-android/src/commands/runAndroid/__tests__/buildAndInstallApk.test.ts new file mode 100644 index 000000000..267a2ddc6 --- /dev/null +++ b/packages/platform-android/src/commands/runAndroid/__tests__/buildAndInstallApk.test.ts @@ -0,0 +1,224 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import fs from 'fs'; +import path from 'path'; +import execa from 'execa'; +import {Config} from '@react-native-community/cli-types'; + +import { + buildApk, + installApk, + createApkName, + getBuildAndFlavours, +} from '../buildAndInstallApk'; +import {Flags} from '../index'; + +type AndroidProject = NonNullable; + +jest.mock('execa'); +jest.mock('fs'); +jest.mock('path'); + +describe('apk', () => { + const args = { + root: '/root', + appFolder: '', + appId: '', + tasks: undefined, + variant: 'debug', + appIdSuffix: '', + mainActivity: 'MainActivity', + deviceId: undefined, + packager: true, + port: 8081, + terminal: 'iTerm2', + jetifier: true, + }; + const androidProject = { + manifestPath: '/android/app/src/main/AndroidManifest.xml', + appName: 'app', + packageName: 'com.test', + sourceDir: '/android', + isFlat: false, + folder: '', + stringsPath: '', + buildGradlePath: '', + settingsGradlePath: '', + assetsPath: '', + mainFilePath: '', + packageFolder: '', + }; + + const adb = 'path/to/adb'; + const gradle = './gradlew'; + + function createTestEnv(androProject: AndroidProject, flags: Flags) { + const androidSource = androProject.sourceDir; + const buildDir = `${ + flags.appFolder || androProject.appName + }/build/outputs/apk/${flags.variant}`; + const apkName = `app-${flags.variant}.apk`; + + fs.mkdirSync(androidSource); + + // create buildDir recursively + buildDir.split('/').reduce((currentPath, dir) => { + fs.mkdirSync(path.join(androidSource, `${currentPath}/${dir}`)); + return `${currentPath}/${dir}`; + }, ''); + + fs.writeFileSync(path.resolve(androidSource, buildDir, apkName), ''); + + return { + source: androidSource, + apkDir: path.resolve(androidSource, buildDir), + apkPath: path.resolve(androidSource, buildDir, apkName), + }; + } + + afterEach(() => { + jest.clearAllMocks(); + + fs.mock.clear('posix'); + }); + + describe('buildApk', () => { + it('uses default assembleDebug task', async () => { + await buildApk(args, gradle, androidProject); + + const calls = ((execa as unknown) as jest.Mock).mock.calls; + + expect(calls[0][1]).toEqual([ + 'app:assembleDebug', + '-PreactNativeDevServerPort=8081', + ]); + }); + + it.each([ + ['Debug', 'app'], + ['Production', 'myApp'], + ])('uses assemble task for %s variant', async (variant, appName) => { + const testArgs = { + ...args, + variant, + }; + const testProject = { + ...androidProject, + appName, + }; + + await buildApk(testArgs, gradle, testProject); + + expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toEqual([ + `${appName}:assemble${variant}`, + '-PreactNativeDevServerPort=8081', + ]); + }); + }); + describe('installApk', () => { + it('runs default installDebug task if APK is not build', async () => { + const sources = createTestEnv(androidProject, args); + + fs.unlinkSync(sources.apkPath); + + await installApk(args, gradle, adb, [], { + ...androidProject, + sourceDir: sources.source, + }); + + const calls = ((execa as unknown) as jest.Mock).mock.calls; + + expect(calls[0][0]).toContain(gradle); + expect(calls[0][1]).toContain('app:installDebug'); + }); + + it('installs already built apk through adb', async () => { + const sources = createTestEnv(androidProject, args); + + await installApk(args, gradle, adb, ['emu-1'], { + ...androidProject, + sourceDir: sources.source, + }); + + const calls = ((execa.sync as unknown) as jest.Mock).mock.calls; + + expect(calls[0][0]).toContain('adb'); + expect(calls[0][1]).toContain(sources.apkPath); + expect(calls[0][1]).toContain('emu-1'); + }); + it.each([ + ['Debug', 'app'], + ['Production', 'myApp'], + ])( + 'installs APK through gradle for %s variant', + async (variant: string, appName: string) => { + const testArgs = { + ...args, + variant, + }; + const testProject = { + ...androidProject, + appName, + }; + + const sources = createTestEnv(testProject, testArgs); + + fs.unlinkSync(sources.apkPath); + + await installApk(testArgs, gradle, adb, [], testProject); + + const calls = ((execa as unknown) as jest.Mock).mock.calls; + + expect(calls[0][0]).toContain(gradle); + expect(calls[0][1]).toContain(`${appName}:install${variant}`); + }, + ); + }); + + describe('build/install utilities', () => { + it.each([ + ['app-demo-free-debug.apk', 'app', 'debug', ['demo', 'free'], null], + ['app-debug.apk', 'app', 'debug', [], null], + ['dev-global-release.apk', 'dev', 'release', ['global'], null], + [ + 'other-super-max-x86-production.apk', + 'other', + 'production', + ['super', 'max'], + 'x86', + ], + ])( + 'builds %s apk file name', + (apkFile, appName, buildType, flavours, cpu) => { + const generatedName = createApkName(appName, buildType, flavours, cpu); + expect(generatedName).toEqual(apkFile); + }, + ); + + it.each([ + ['demoRelease', {buildType: 'release', flavours: ['demo']}], + ['demoFreeDebug', {buildType: 'debug', flavours: ['demo', 'free']}], + ['localGoogleDebug', {buildType: 'debug', flavours: ['local', 'google']}], + [ + 'mixingVeryLongFlavsProduction', + { + buildType: 'production', + flavours: ['mixing', 'very', 'long', 'flavs'], + }, + ], + ['debug', {buildType: 'debug', flavours: []}], + ])( + 'reads proper build type and flavours for variant %s', + (variant, result) => { + const config = getBuildAndFlavours(variant); + expect(config).toEqual(result); + }, + ); + }); +}); diff --git a/packages/platform-android/src/commands/runAndroid/__tests__/runOnAllDevices.test.ts b/packages/platform-android/src/commands/runAndroid/__tests__/runOnAllDevices.test.ts index 540861c06..ca7d73ac8 100644 --- a/packages/platform-android/src/commands/runAndroid/__tests__/runOnAllDevices.test.ts +++ b/packages/platform-android/src/commands/runAndroid/__tests__/runOnAllDevices.test.ts @@ -46,7 +46,7 @@ describe('--appFolder', () => { jest.clearAllMocks(); }); - it('uses task "install[Variant]" as default task', async () => { + it('uses task "assemble[Variant]" as default build task', async () => { await runOnAllDevices( {...args, variant: 'debug'}, './gradlew', @@ -55,7 +55,7 @@ describe('--appFolder', () => { androidProject, ); expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain( - 'app:installDebug', + 'app:assembleDebug', ); }); @@ -69,7 +69,7 @@ describe('--appFolder', () => { ); expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain( - 'someApp:installDebug', + 'someApp:assembleDebug', ); }); @@ -83,7 +83,7 @@ describe('--appFolder', () => { ); expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain( - 'anotherApp:installStaging', + 'anotherApp:assembleStaging', ); }); @@ -97,7 +97,7 @@ describe('--appFolder', () => { ); expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain( - 'someApp:installDebug', + 'someApp:assembleDebug', ); }); @@ -111,7 +111,7 @@ describe('--appFolder', () => { ); expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain( - 'anotherApp:installStaging', + 'anotherApp:assembleStaging', ); }); diff --git a/packages/platform-android/src/commands/runAndroid/buildAndInstallApk.ts b/packages/platform-android/src/commands/runAndroid/buildAndInstallApk.ts new file mode 100644 index 000000000..484177837 --- /dev/null +++ b/packages/platform-android/src/commands/runAndroid/buildAndInstallApk.ts @@ -0,0 +1,280 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import fs from 'fs'; +import path from 'path'; +import execa from 'execa'; +import chalk from 'chalk'; +import {Config} from '@react-native-community/cli-types'; +import {CLIError, logger} from '@react-native-community/cli-tools'; +import {Flags} from '.'; +import adb from './adb'; + +type AndroidProject = NonNullable; + +function toPascalCase(value: string) { + return value !== '' ? value[0].toUpperCase() + value.slice(1) : value; +} + +function getTaskNames(appName: string, commands: Array): Array { + return appName + ? commands.map((command) => `${appName}:${command}`) + : commands; +} + +function getGradleBaseArgs( + cmd: string, + args: Flags, + androidProject: AndroidProject, +) { + const tasks = args.tasks || [cmd + toPascalCase(args.variant)]; + + return getTaskNames(args.appFolder || androidProject.appName, tasks); +} + +export async function buildApk( + args: Flags, + gradlew: string, + androidProject: AndroidProject, +) { + try { + const gradleArgs = getGradleBaseArgs('assemble', args, androidProject); + + if (args.port != null) { + gradleArgs.push('-PreactNativeDevServerPort=' + args.port); + } + + logger.info('Building the apk...'); + logger.debug( + `Running command "cd android && ${gradlew} ${gradleArgs.join(' ')}"`, + ); + + await execa(gradlew, gradleArgs, { + stdio: ['inherit', 'inherit', 'pipe'], + cwd: androidProject.sourceDir, + }); + } catch (error) { + throw new CLIError('Failed to build the apk.', error); + } +} + +export async function installApk( + args: Flags, + gradlew: string, + adbPath: string, + devices: string[], + androidProject: AndroidProject, +) { + let installThroughAdb = true; + + if (devices.length === 0) { + // No devices were detected, so don't try running ADB + // instead, gradle will build APK, so consequent run (after device/emu is up) will be faster + installThroughAdb = false; + } else { + for (let device of devices) { + if (!checkApkFileExists(args, adbPath, device, androidProject)) { + // one of APK is not build for specific device + installThroughAdb = false; + } + } + } + + if (installThroughAdb) { + for (let device of devices) { + await installApkFromPath( + adbPath, + device, + getApkFilePath(args, adbPath, device, androidProject), + ); + } + } else { + await installApkWithGradle(args, gradlew, androidProject); + } +} + +async function installApkFromPath( + adbPath: string, + deviceId: string, + pathToApk: string, +) { + try { + const adbArgs = ['-s', deviceId, 'install', '-r', '-d', pathToApk]; + logger.info( + `Installing the app on the device "${deviceId}" through adb...`, + ); + logger.debug(`Running command "cd android && adb ${adbArgs.join(' ')}"`); + execa.sync(adbPath, adbArgs, {stdio: 'inherit'}); + } catch (error) { + throw new CLIError( + `Failed to install the app on the device ${deviceId}.`, + error, + ); + } +} + +async function installApkWithGradle( + args: Flags, + gradlew: string, + androidProject: AndroidProject, +) { + try { + const gradleArgs = getGradleBaseArgs('install', args, androidProject); + if (args.port != null) { + gradleArgs.push('-PreactNativeDevServerPort=' + args.port); + } + + logger.info('Installing the app on the devices through gradle...'); + logger.debug( + `Running command "cd android && ${gradlew} ${gradleArgs.join(' ')}`, + ); + + await execa(gradlew, gradleArgs, { + stdio: ['inherit', 'inherit', 'pipe'], + cwd: androidProject.sourceDir, + }); + } catch (error) { + throw createInstallError(error); + } +} + +function checkApkFileExists( + args: Flags, + adbPath: string, + device: string, + androidProject: AndroidProject, +) { + try { + const apkFile = getApkFilePath(args, adbPath, device, androidProject); + return fs.existsSync(apkFile); + } catch (_) { + return false; + } +} + +export function createApkName( + appName: string, + buildType: string, + flavours?: string[] | null, + cpuArch?: string | null, +) { + let apkName = `${appName}-`; + if (flavours) { + apkName += flavours.reduce((rest, flav) => `${rest}${flav}-`, ''); + } + if (cpuArch) { + apkName += `${cpuArch}-`; + } + apkName += `${buildType}.apk`; + + return apkName; +} + +/* Export for test only */ +export function getBuildAndFlavours(variant: string) { + const regExp = /[A-Z]/; + const flavours = []; + + let processing = variant; + + function firstLowerCase(text: string) { + return `${text[0].toLowerCase()}${text.slice(1)}`; + } + + while (true) { + const match = processing.match(regExp); + + if (!match) { + return { + buildType: processing, + flavours, + }; + } + + const foundFlavor = processing.slice(0, match.index); + flavours.push(foundFlavor.toLowerCase()); + processing = firstLowerCase(processing.slice(match.index)); + } +} + +/* Export for test only */ +function getApkFilePath( + args: Flags, + adbPath: string, + device: string, + androidProject: AndroidProject, +) { + let buildType = args.variant; + let appName = androidProject.appName; + let flavours: string[] = []; + + let buildDirectory = `${androidProject.sourceDir}/${ + args.appFolder || appName + }/build/outputs/apk/`; + + const realVariant = buildType.match(/[A-Z]/); + + /* + Argument --variant can be a "real" variant or just build type. + Real variant is a combination of flavour dimension and build type, ex. demoDebug. + APK name changes if flavors come into play. + */ + if (realVariant) { + buildType = getBuildAndFlavours(args.variant).buildType; + flavours = getBuildAndFlavours(args.variant).flavours; + buildDirectory = path.join(buildDirectory, ...flavours, buildType); + } else { + buildDirectory = path.join(buildDirectory, buildType); + } + + const availableCPUs = adb.getAvailableCPUs(adbPath, device); + + // check if there is an apk file like app-armeabi-v7a-debug.apk + for (const availableCPU of availableCPUs.concat('universal')) { + const apkName = createApkName(appName, buildType, flavours, availableCPU); + if (fs.existsSync(`${buildDirectory}/${apkName}`)) { + return `${buildDirectory}/${apkName}`; + } + } + + // check if there is a default file like app-debug.apk + const apkName = createApkName(appName, buildType, flavours); + if (fs.existsSync(`${buildDirectory}/${apkName}`)) { + return `${buildDirectory}/${apkName}`; + } + + throw new CLIError(`Could not find the correct install APK file: ${apkName}`); +} + +function createInstallError(error: Error & {stderr: string}) { + const stderr = (error.stderr || '').toString(); + const docs = + 'https://reactnative.dev/docs/getting-started.html#android-development-environment'; + let message = `Make sure you have the Android development environment set up: ${chalk.underline.dim( + docs, + )}`; + + // Pass the error message from the command to stdout because we pipe it to + // parent process so it's not visible + logger.log(stderr); + + // Handle some common failures and make the errors more helpful + if (stderr.includes('No connected devices')) { + message = + 'Make sure you have an Android emulator running or a device connected'; + } else if ( + stderr.includes('licences have not been accepted') || + stderr.includes('accept the SDK license') + ) { + message = `Please accept all necessary Android SDK licenses using Android SDK Manager: "${chalk.bold( + '$ANDROID_HOME/tools/bin/sdkmanager --licenses', + )}"`; + } + + return new CLIError(`Failed to install the app. ${message}.`, error); +} diff --git a/packages/platform-android/src/commands/runAndroid/index.ts b/packages/platform-android/src/commands/runAndroid/index.ts index 29f351d77..18f9f6f4a 100644 --- a/packages/platform-android/src/commands/runAndroid/index.ts +++ b/packages/platform-android/src/commands/runAndroid/index.ts @@ -23,6 +23,7 @@ import { } from '@react-native-community/cli-tools'; import warnAboutManuallyLinkedLibs from '../../link/warnAboutManuallyLinkedLibs'; import {getAndroidProject, getPackageName} from '../../utils/getAndroidProject'; +import {buildApk, installApk} from './buildAndInstallApk'; function displayWarnings(config: Config, args: Flags) { warnAboutManuallyLinkedLibs(config); @@ -116,16 +117,15 @@ function buildAndRun(args: Flags, androidProject: AndroidProject) { const adbPath = getAdbPath(); if (args.deviceId) { - return runOnSpecificDevice(args, cmd, packageName, adbPath, androidProject); + return runOnSpecificDevice(args, cmd, adbPath, androidProject); } else { return runOnAllDevices(args, cmd, packageName, adbPath, androidProject); } } -function runOnSpecificDevice( +async function runOnSpecificDevice( args: Flags, gradlew: 'gradlew.bat' | './gradlew', - packageName: string, adbPath: string, androidProject: AndroidProject, ) { @@ -133,14 +133,10 @@ function runOnSpecificDevice( const {deviceId} = args; if (devices.length > 0 && deviceId) { if (devices.indexOf(deviceId) !== -1) { - buildApk(gradlew, androidProject.sourceDir); - installAndLaunchOnDevice( - args, - deviceId, - packageName, - adbPath, - androidProject, - ); + await buildApk(args, gradlew, androidProject); + tryRunAdbReverse(args.port, deviceId); + await installApk(args, gradlew, adbPath, [deviceId], androidProject); + tryLaunchAppOnDevice(deviceId, androidProject.packageName, adbPath, args); } else { logger.error( `Could not find device with the id: "${deviceId}". Please choose one of the following:`, @@ -152,88 +148,6 @@ function runOnSpecificDevice( } } -function buildApk(gradlew: string, sourceDir: string) { - try { - // using '-x lint' in order to ignore linting errors while building the apk - const gradleArgs = ['build', '-x', 'lint']; - logger.info('Building the app...'); - logger.debug(`Running command "${gradlew} ${gradleArgs.join(' ')}"`); - execa.sync(gradlew, gradleArgs, {stdio: 'inherit', cwd: sourceDir}); - } catch (error) { - throw new CLIError('Failed to build the app.', error); - } -} - -function tryInstallAppOnDevice( - args: Flags, - adbPath: string, - device: string, - androidProject: AndroidProject, -) { - try { - // "app" is usually the default value for Android apps with only 1 app - const {appName, sourceDir} = androidProject; - const {appFolder} = args; - const variant = args.variant.toLowerCase(); - const buildDirectory = `${sourceDir}/${appName}/build/outputs/apk/${variant}`; - const apkFile = getInstallApkName( - appFolder || appName, // TODO: remove appFolder - adbPath, - variant, - device, - buildDirectory, - ); - - const pathToApk = `${buildDirectory}/${apkFile}`; - const adbArgs = ['-s', device, 'install', '-r', '-d', pathToApk]; - logger.info(`Installing the app on the device "${device}"...`); - logger.debug( - `Running command "cd android && adb -s ${device} install -r -d ${pathToApk}"`, - ); - execa.sync(adbPath, adbArgs, {stdio: 'inherit'}); - } catch (error) { - throw new CLIError('Failed to install the app on the device.', error); - } -} - -function getInstallApkName( - appName: string, - adbPath: string, - variant: string, - device: string, - buildDirectory: string, -) { - const availableCPUs = adb.getAvailableCPUs(adbPath, device); - - // check if there is an apk file like app-armeabi-v7a-debug.apk - for (const availableCPU of availableCPUs.concat('universal')) { - const apkName = `${appName}-${availableCPU}-${variant}.apk`; - if (fs.existsSync(`${buildDirectory}/${apkName}`)) { - return apkName; - } - } - - // check if there is a default file like app-debug.apk - const apkName = `${appName}-${variant}.apk`; - if (fs.existsSync(`${buildDirectory}/${apkName}`)) { - return apkName; - } - - throw new CLIError('Could not find the correct install APK file.'); -} - -function installAndLaunchOnDevice( - args: Flags, - selectedDevice: string, - packageName: string, - adbPath: string, - androidProject: AndroidProject, -) { - tryRunAdbReverse(args.port, selectedDevice); - tryInstallAppOnDevice(args, adbPath, selectedDevice, androidProject); - tryLaunchAppOnDevice(selectedDevice, packageName, adbPath, args); -} - function startServerInNewWindow( port: number, terminal: string, diff --git a/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts b/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts index 2a968fc72..0acb9b7a6 100644 --- a/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts +++ b/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts @@ -7,30 +7,20 @@ */ import chalk from 'chalk'; -import execa from 'execa'; import {Config} from '@react-native-community/cli-types'; -import {logger, CLIError} from '@react-native-community/cli-tools'; +import {logger} from '@react-native-community/cli-tools'; import adb from './adb'; import tryRunAdbReverse from './tryRunAdbReverse'; import tryLaunchAppOnDevice from './tryLaunchAppOnDevice'; import tryLaunchEmulator from './tryLaunchEmulator'; import {Flags} from '.'; - -function getTaskNames(appName: string, commands: Array): Array { - return appName - ? commands.map((command) => `${appName}:${command}`) - : commands; -} - -function toPascalCase(value: string) { - return value !== '' ? value[0].toUpperCase() + value.slice(1) : value; -} +import {buildApk, installApk} from './buildAndInstallApk'; type AndroidProject = NonNullable; async function runOnAllDevices( args: Flags, - cmd: string, + gradlew: string, packageName: string, adbPath: string, androidProject: AndroidProject, @@ -52,29 +42,8 @@ async function runOnAllDevices( } } - try { - const tasks = args.tasks || ['install' + toPascalCase(args.variant)]; - const gradleArgs = getTaskNames( - args.appFolder || androidProject.appName, - tasks, - ); - - if (args.port != null) { - gradleArgs.push('-PreactNativeDevServerPort=' + args.port); - } - - logger.info('Installing the app...'); - logger.debug( - `Running command "cd android && ${cmd} ${gradleArgs.join(' ')}"`, - ); - - await execa(cmd, gradleArgs, { - stdio: ['inherit', 'inherit', 'pipe'], - cwd: androidProject.sourceDir, - }); - } catch (error) { - throw createInstallError(error); - } + await buildApk(args, gradlew, androidProject); + await installApk(args, gradlew, adbPath, devices, androidProject); (devices.length > 0 ? devices : [undefined]).forEach( (device: string | void) => { @@ -84,31 +53,4 @@ async function runOnAllDevices( ); } -function createInstallError(error: Error & {stderr: string}) { - const stderr = (error.stderr || '').toString(); - const docs = 'https://reactnative.dev/docs/environment-setup'; - let message = `Make sure you have the Android development environment set up: ${chalk.underline.dim( - docs, - )}`; - - // Pass the error message from the command to stdout because we pipe it to - // parent process so it's not visible - logger.log(stderr); - - // Handle some common failures and make the errors more helpful - if (stderr.includes('No connected devices')) { - message = - 'Make sure you have an Android emulator running or a device connected'; - } else if ( - stderr.includes('licences have not been accepted') || - stderr.includes('accept the SDK license') - ) { - message = `Please accept all necessary Android SDK licenses using Android SDK Manager: "${chalk.bold( - '$ANDROID_HOME/tools/bin/sdkmanager --licenses', - )}"`; - } - - return new CLIError(`Failed to install the app. ${message}.`, error); -} - export default runOnAllDevices; From be0e2b780a3709f208803eb8084427c27d220048 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 16 Jul 2021 15:30:17 +0200 Subject: [PATCH 2/2] Update runOnAllDevices.ts --- .../commands/runAndroid/runOnAllDevices.ts | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts b/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts index 83f7266a5..874b72c06 100644 --- a/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts +++ b/packages/platform-android/src/commands/runAndroid/runOnAllDevices.ts @@ -46,44 +46,6 @@ async function runOnAllDevices( await buildApk(args, gradlew, androidProject); await installApk(args, gradlew, adbPath, devices, androidProject); - try { - const tasks = args.tasks || ['install' + toPascalCase(args.variant)]; - const gradleArgs = getTaskNames( - args.appFolder || androidProject.appName, - tasks, - ); - - if (args.port != null) { - gradleArgs.push('-PreactNativeDevServerPort=' + args.port); - } - - if (args.activeArchOnly) { - const architectures = devices - .map((device) => { - return adb.getCPU(adbPath, device); - }) - .filter((arch) => arch != null); - if (architectures.length > 0) { - logger.info(`Detected architectures ${architectures.join(', ')}`); - gradleArgs.push( - '-PreactNativeDebugArchitectures=' + architectures.join(','), - ); - } - } - - logger.info('Installing the app...'); - logger.debug( - `Running command "cd android && ${cmd} ${gradleArgs.join(' ')}"`, - ); - - await execa(cmd, gradleArgs, { - stdio: ['inherit', 'inherit', 'pipe'], - cwd: androidProject.sourceDir, - }); - } catch (error) { - throw createInstallError(error); - } - (devices.length > 0 ? devices : [undefined]).forEach( (device: string | void) => { tryRunAdbReverse(args.port, device);