Skip to content

Commit 652f3ce

Browse files
blakeffacebook-github-bot
authored andcommitted
Fix cli assemble, build & install (#44902)
Summary: Pull Request resolved: #44902 Add support for building (assembling) a React Native Android project. Changelog: [General][Added] core-cli-utils Android support Reviewed By: cortinico Differential Revision: D58287783
1 parent b19bf2b commit 652f3ce

File tree

1 file changed

+74
-81
lines changed

1 file changed

+74
-81
lines changed

packages/core-cli-utils/src/private/android.js

+74-81
Original file line numberDiff line numberDiff line change
@@ -12,117 +12,110 @@
1212
import type {Task} from './types';
1313
import type {ExecaPromise} from 'execa';
1414

15-
import {isWindows, task, toPascalCase} from './utils';
15+
import {isWindows, task} from './utils';
1616
import execa from 'execa';
1717

18-
type AndroidBuildMode = 'debug' | 'release';
18+
type AndroidBuildMode = 'Debug' | 'Release';
1919

20-
type AndroidBuild = {
21-
sourceDir: string,
22-
appName: string,
20+
type Path = string;
21+
type Args = $ReadOnlyArray<string>;
22+
23+
type Config = {
24+
cwd: Path,
25+
hermes?: boolean,
2326
mode: AndroidBuildMode,
24-
gradleArgs?: Array<string>,
27+
name: string,
28+
newArchitecture?: boolean,
29+
sdk?: Path,
2530
};
2631

27-
function gradle(cwd: string, ...args: string[]): ExecaPromise {
32+
function gradle(
33+
taskName: string,
34+
args: Args,
35+
options: {cwd: string, env?: {[k: string]: string | void}},
36+
): ExecaPromise {
2837
const gradlew = isWindows ? 'gradlew.bat' : './gradlew';
29-
return execa(gradlew, args, {
30-
cwd,
31-
stdio: 'inherit',
38+
return execa(gradlew, [taskName, ...args], {
39+
cwd: options.cwd,
40+
env: options.env,
3241
});
3342
}
3443

35-
//
36-
// Gradle Task wrappers
37-
//
38-
39-
/**
40-
* Assembles an Android app using Gradle
41-
*/
42-
export const assemble = (
43-
cwd: string,
44-
appName: string,
45-
mode: AndroidBuildMode,
46-
...args: $ReadOnlyArray<string>
47-
): ExecaPromise =>
48-
gradle(cwd, `${appName}:assemble${toPascalCase(mode)}`, ...args);
49-
50-
/**
51-
* Assembles and tests an Android app using Gradle
52-
*/
53-
export const build = (
54-
cwd: string,
55-
appName: string,
56-
mode: AndroidBuildMode,
57-
...args: $ReadOnlyArray<string>
58-
): ExecaPromise =>
59-
gradle(cwd, `${appName}:build${toPascalCase(mode)}`, ...args);
60-
61-
/**
62-
* Installs an Android app using Gradle
63-
*/
64-
export const install = (
65-
cwd: string,
66-
appName: string,
67-
mode: AndroidBuildMode,
68-
...args: $ReadOnlyArray<string>
69-
): ExecaPromise =>
70-
gradle(cwd, `${appName}:install${toPascalCase(mode)}`, ...args);
44+
function androidSdkPath(sdk?: string): string {
45+
return sdk ?? process.env.ANDROID_HOME ?? process.env.ANDROID_SDK ?? '';
46+
}
7147

72-
/**
73-
* Runs a custom Gradle task if your frameworks needs aren't handled by assemble, build or install.
74-
*/
75-
export const customTask = (
76-
cwd: string,
77-
customTaskName: string,
78-
...args: $ReadOnlyArray<string>
79-
): ExecaPromise => gradle(cwd, customTaskName, ...args);
48+
function boolToStr(value: boolean): string {
49+
return value ? 'true' : 'false';
50+
}
8051

8152
const FIRST = 1;
8253

8354
//
8455
// Android Tasks
8556
//
86-
type AndroidTasks = {
87-
assemble: (
88-
options: AndroidBuild,
89-
...args: $ReadOnlyArray<string>
90-
) => {run: Task<ExecaPromise>},
91-
build: (
92-
options: AndroidBuild,
93-
...args: $ReadOnlyArray<string>
94-
) => {run: Task<ExecaPromise>},
95-
install: (
96-
options: AndroidBuild,
97-
...args: $ReadOnlyArray<string>
98-
) => {run: Task<ExecaPromise>},
99-
};
100-
101-
export const tasks: AndroidTasks = {
102-
assemble: (options: AndroidBuild, ...gradleArgs: $ReadOnlyArray<string>) => ({
103-
run: task(FIRST, 'Assemble Android App', () =>
104-
assemble(options.sourceDir, options.appName, options.mode, ...gradleArgs),
105-
),
57+
export const tasks = (
58+
config: Config,
59+
): ({
60+
assemble: (...gradleArgs: Args) => {
61+
run: Task<ExecaPromise>,
62+
},
63+
build: (...gradleArgs: Args) => {
64+
run: Task<ExecaPromise>,
65+
},
66+
install: (...gradleArgs: Args) => {
67+
run: Task<ExecaPromise>,
68+
},
69+
}) => ({
70+
assemble: (...gradleArgs: Args) => ({
71+
run: task(FIRST, 'Assemble Android App', () => {
72+
const args = [];
73+
if (config.hermes != null) {
74+
args.push(`-PhermesEnabled=${boolToStr(config.hermes)}`);
75+
}
76+
if (config.newArchitecture != null) {
77+
args.push(`-PnewArchEnabled=${boolToStr(config.newArchitecture)}`);
78+
}
79+
args.push(...gradleArgs);
80+
return gradle(`${config.name}:assemble${config.mode}`, gradleArgs, {
81+
cwd: config.cwd,
82+
env: {ANDROID_HOME: androidSdkPath(config.sdk)},
83+
});
84+
}),
10685
}),
107-
build: (options: AndroidBuild, ...gradleArgs: $ReadOnlyArray<string>) => ({
108-
run: task(FIRST, 'Assembles and tests Android App', () =>
109-
build(options.sourceDir, options.appName, options.mode, ...gradleArgs),
110-
),
86+
build: (...gradleArgs: Args) => ({
87+
run: task(FIRST, 'Assembles and tests Android App', () => {
88+
const args = [];
89+
if (config.hermes != null) {
90+
args.push(`-PhermesEnabled=${boolToStr(config.hermes)}`);
91+
}
92+
if (config.newArchitecture != null) {
93+
args.push(`-PnewArchEnabled=${boolToStr(config.newArchitecture)}`);
94+
}
95+
args.push(...gradleArgs);
96+
return gradle(`${config.name}:bundle${config.mode}`, args, {
97+
cwd: config.cwd,
98+
env: {ANDROID_HOME: androidSdkPath(config.sdk)},
99+
});
100+
}),
111101
}),
112102
/**
113103
* Useful extra gradle arguments:
114104
*
115105
* -PreactNativeDevServerPort=8081 sets the port for the installed app to point towards a Metro
116106
* server on (for example) 8081.
117107
*/
118-
install: (options: AndroidBuild, ...gradleArgs: $ReadOnlyArray<string>) => ({
108+
install: (...gradleArgs: Args) => ({
119109
run: task(FIRST, 'Installs the assembled Android App', () =>
120-
install(options.sourceDir, options.appName, options.mode, ...gradleArgs),
110+
gradle(`${config.name}:install${config.mode}`, gradleArgs, {
111+
cwd: config.cwd,
112+
env: {ANDROID_HOME: androidSdkPath(config.sdk)},
113+
}),
121114
),
122115
}),
123116

124117
// We are not supporting launching the app and setting up the tunnel for metro <-> app, this is
125118
// a framework concern. For an example of how one could do this, please look at the community
126119
// CLI's code:
127120
// https://github.com/react-native-community/cli/blob/54d48a4e08a1aef334ae6168788e0157a666b4f5/packages/cli-platform-android/src/commands/runAndroid/index.ts#L272C1-L290C2
128-
};
121+
});

0 commit comments

Comments
 (0)