82 lines
2.1 KiB
TypeScript

import { ExecutorContext } from '@nrwl/devkit';
import { join } from 'path';
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
import { ChildProcess, spawn } from 'child_process';
import { ReactNativeBuildOptions } from './schema';
import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files';
export interface ReactNativeBuildOutput {
success: boolean;
}
let childProcess: ChildProcess;
export default async function* buildAndroidExecutor(
options: ReactNativeBuildOptions,
context: ExecutorContext
): AsyncGenerator<ReactNativeBuildOutput> {
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
ensureNodeModulesSymlink(context.root, projectRoot);
chmodAndroidGradlewFiles(join(projectRoot, 'android'));
try {
await runCliBuild(context.root, projectRoot, options);
yield { success: true };
} finally {
if (childProcess) {
childProcess.kill();
}
}
}
function runCliBuild(
workspaceRoot: string,
projectRoot: string,
options: ReactNativeBuildOptions
) {
return new Promise((resolve, reject) => {
const gradleCommand = getGradleCommand(options);
childProcess = spawn(
process.platform === 'win32' ? 'gradlew.bat' : './gradlew',
[gradleCommand],
{
cwd: join(workspaceRoot, projectRoot, 'android'),
stdio: [0, 1, 2],
}
);
// 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);
}
});
});
}
function getGradleCommand(options: ReactNativeBuildOptions) {
if (options?.gradleTask) {
return options.gradleTask;
}
if (options.apk) {
if (options.debug) {
return 'assembleDebug';
}
return 'assembleRelease';
} else {
if (options.debug) {
return 'bundleDebug';
}
return 'bundleRelease';
}
}