/
run-android.impl.ts
117 lines (104 loc) · 3.09 KB
/
run-android.impl.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { ExecutorContext } from '@nrwl/devkit';
import { join } from 'path';
import { ChildProcess, fork } from 'child_process';
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
import {
displayNewlyAddedDepsMessage,
syncDeps,
} from '../sync-deps/sync-deps.impl';
import { chmodSync } from 'fs';
import { ReactNativeRunAndroidOptions } from './schema';
import { runCliStart } from '../start/start.impl';
export interface ReactNativeRunAndroidOutput {
success: boolean;
}
let childProcess: ChildProcess;
export default async function* runAndroidExecutor(
options: ReactNativeRunAndroidOptions,
context: ExecutorContext
): AsyncGenerator<ReactNativeRunAndroidOutput> {
const projectRoot = context.workspace.projects[context.projectName].root;
ensureNodeModulesSymlink(context.root, projectRoot);
chmodSync(join(context.root, projectRoot, 'android', 'gradlew'), 0o775);
chmodSync(join(context.root, projectRoot, 'android', 'gradlew.bat'), 0o775);
if (options.sync) {
displayNewlyAddedDepsMessage(
context.projectName,
await syncDeps(context.projectName, projectRoot, context.root)
);
}
try {
const tasks = [runCliRunAndroid(context.root, projectRoot, options)];
if (options.packager) {
tasks.push(
runCliStart(context.root, projectRoot, {
port: options.port,
resetCache: options.resetCache,
interactive: options.interactive,
})
);
}
await Promise.all(tasks);
yield { success: true };
} finally {
if (childProcess) {
childProcess.kill();
}
}
}
function runCliRunAndroid(
workspaceRoot: string,
projectRoot: string,
options: ReactNativeRunAndroidOptions
) {
return new Promise((resolve, reject) => {
/**
* Call the react native cli with option `--no-packager`
* Not passing '--packager' due to cli will launch start command from the project root
*/
childProcess = fork(
join(workspaceRoot, './node_modules/react-native/cli.js'),
['run-android', ...createRunAndroidOptions(options), '--no-packager'],
{
cwd: join(workspaceRoot, projectRoot),
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
}
);
// Ensure the child process is killed when the parent exits
process.on('exit', () => childProcess.kill());
process.on('SIGTERM', () => childProcess.kill());
childProcess.on('error', (err) => {
reject(err);
});
childProcess.on('exit', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(code);
}
});
});
}
const nxOrStartOptions = [
'sync',
'install',
'packager',
'port',
'resetCache',
'interactive',
];
function createRunAndroidOptions(options) {
return Object.keys(options).reduce((acc, k) => {
const v = options[k];
if (k === 'mainActivity') {
acc.push(`--main-activity`, v);
} else if (k === 'jetifier') {
if (!v) {
acc.push(`--no-jetifier`);
}
} else if (v && !nxOrStartOptions.includes(k)) {
acc.push(`--${k}`, v);
}
return acc;
}, []);
}