Skip to content

Commit

Permalink
Merge pull request #1315 from flexn-io/fix/emulators-unwanted-exit
Browse files Browse the repository at this point in the history
Fix emulators unwanted exit
  • Loading branch information
ElenaDiachenko committed Dec 22, 2023
2 parents 1f17337 + d578b86 commit 478051c
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 46 deletions.
4 changes: 2 additions & 2 deletions packages/cli/src/logger/index.ts
Expand Up @@ -332,13 +332,13 @@ export const logTask = (task: string, customChalk?: string | RnvApiChalkFn) => {

let msg = '';
if (typeof customChalk === 'string') {
msg = `${currentChalk.green(`[ task ]${_getCurrentTask()} ${task}`)}${taskCount} ${currentChalk.grey(
msg = `${currentChalk.green(`[ task ]${_getCurrentTask()}`)} ${task}${taskCount} ${currentChalk.grey(
customChalk
)}`;
} else if (customChalk) {
msg = customChalk(`[ task ]${_getCurrentTask()} ${task}${taskCount}`);
} else {
msg = currentChalk.green(`[ task ]${_getCurrentTask()} ${task}${taskCount}`);
msg = `${currentChalk.green(`[ task ]${_getCurrentTask()}`)} ${task}${taskCount}`;
}

console.log(_sanitizePaths(msg));
Expand Down
10 changes: 9 additions & 1 deletion packages/core/src/__tests__/exec.test.ts
Expand Up @@ -3,7 +3,15 @@ import { createRnvContext } from '../context';
import { generateContextDefaults } from '../context/defaults';
import { executeAsync, commandExistsSync, commandExists } from '../system/exec';

jest.mock('../logger/index.ts');
jest.mock('../logger/index.ts', () => {
return {
logTask: jest.fn(),
logDebug: jest.fn(),
chalk: () => ({
rgb: jest.fn(),
}),
};
});

describe('Testing exec functions', () => {
beforeAll(() => {
Expand Down
57 changes: 43 additions & 14 deletions packages/core/src/system/exec.ts
Expand Up @@ -14,6 +14,36 @@ import { getApi } from '../api/provider';

const { exec, execSync } = require('child_process');

const FIRE_AND_FORGET: ExecOptions = {
stdio: 'ignore', // Disable child_process output
detached: true, // Killing rnv command will NOT kill process
silent: true, // Disable spinner
shell: true, // runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows
};

const INHERIT_OUTPUT_NO_SPINNER: ExecOptions = {
detached: false, // Killing command will kill process
silent: true, // silent: true => will not show execa spinner
stdio: 'inherit', // inherit will print during execution but no details in SUMMARY box
shell: true, // runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows
// mono: true,
};

const SPINNER_FULL_ERROR_SUMMARY: ExecOptions = {
detached: false, // Killing command will kill process
silent: false,
stdio: 'pipe', // pipe will print final error into SUMMARY box but nothing during execution
shell: true, // runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows
mono: false,
};

export const ExecOptionsPresets = {
// Do not await when using FIRE_AND_FORGET option
FIRE_AND_FORGET,
INHERIT_OUTPUT_NO_SPINNER,
SPINNER_FULL_ERROR_SUMMARY,
} as const;

/**
*
* Also accepts the Node's child_process exec/spawn options
Expand Down Expand Up @@ -42,11 +72,8 @@ const _execute = (c: RnvContext, command: string | Array<string>, opts: ExecOpti
mono: c.program?.mono || c.program?.json,
};

if (opts.interactive) {
defaultOpts.silent = true;
defaultOpts.stdio = 'inherit';
defaultOpts.shell = true;
}
const blue2 = chalk().rgb(50, 50, 255);

const mergedOpts = { ...defaultOpts, ...opts };

const printableEnv =
Expand All @@ -72,15 +99,14 @@ const _execute = (c: RnvContext, command: string | Array<string>, opts: ExecOpti
logMessage = replaceOverridesInString(commandAsString, privateParams, privateMask);
}

if (printableEnv) {
let logMsg = `${chalk().grey(printableEnv)} ${logMessage}`;
if (c.program.printExec) {
let logMsg = printableEnv ? `${chalk().grey(printableEnv)} ${logMessage}` : logMessage;
if (opts.cwd) {
logMsg = `cd ${opts.cwd} ${chalk().cyan('&&')} ${logMsg}`;
}
console.log(
`${chalk().green('✔')} Full exec command: ${chalk().green('>>>')}\n${logMsg}\n${chalk().green('<<<')}`
);
logRaw(`${blue2('[ exec ]')} ${blue2('<[')} ${logMsg} ${blue2(']>')}`);
}

logDebug(`_execute: ${logMessage}`);
const { silent, mono, maxErrorLength, ignoreErrors } = mergedOpts;
const spinner =
Expand All @@ -89,9 +115,9 @@ const _execute = (c: RnvContext, command: string | Array<string>, opts: ExecOpti
getApi()
.spinner({ text: `Executing: ${logMessage}` })
.start('');
if (opts.interactive) {
logRaw(`${chalk().green('✔')} Executing: ${logMessage}\n`);
}
// if (opts.interactive) {
// logRaw(`${chalk().green('✔')} Executing: ${logMessage}\n`);
// }

if (mono) {
interval = setInterval(() => {
Expand All @@ -106,7 +132,10 @@ const _execute = (c: RnvContext, command: string | Array<string>, opts: ExecOpti
} else {
child = execa.command(cleanCommand, mergedOpts);
}
c.runningProcesses.push(child);

if (!opts.detached) {
c.runningProcesses.push(child);
}

const MAX_OUTPUT_LENGTH = 200;

Expand Down
1 change: 0 additions & 1 deletion packages/core/src/system/types.ts
Expand Up @@ -8,7 +8,6 @@ export type ResolveOptions = {
};

export type ExecOptions = {
interactive?: boolean;
silent?: boolean;
stdio?: 'pipe' | 'inherit' | 'ignore';
shell?: boolean;
Expand Down
10 changes: 2 additions & 8 deletions packages/engine-rn-electron/src/sdk.ts
Expand Up @@ -37,6 +37,7 @@ import {
MACOS,
LINUX,
TASK_EXPORT,
ExecOptionsPresets,
} from '@rnv/core';
import { FileElectronPackage } from './types';
import { NpmPackageFile } from '@rnv/core/lib/configs/types';
Expand Down Expand Up @@ -364,14 +365,7 @@ const _runElectronSimulator = async (c: RnvContext) => {
}

const cmd = `node ${doResolve('electron')}/cli.js ${path.join(platformProjectDir, '/main.js')}`;
await executeAsync(c, cmd, {
interactive: true,
stdio: 'inherit',
// silent: true,
// env: {
// ...CoreEnvVars.BASE(),
// },
});
await executeAsync(c, cmd, ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER);
};

const _generateICNS = (c: RnvContext) =>
Expand Down
6 changes: 5 additions & 1 deletion packages/engine-rn-next/src/sdk.ts
Expand Up @@ -17,6 +17,7 @@ import {
copyAssetsFolder,
RnvPlatform,
CoreEnvVars,
ExecOptionsPresets,
} from '@rnv/core';
import { getDevServerHost, openBrowser, waitForHost } from '@rnv/sdk-utils';
import { EnvVars } from './env';
Expand Down Expand Up @@ -139,6 +140,9 @@ Dev server running at: ${url}
`);

const bundleAssets = getConfigProp(c, c.platform, 'bundleAssets', false);
const opts = !c.program?.json
? ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER
: ExecOptionsPresets.SPINNER_FULL_ERROR_SUMMARY;
return executeAsync(c, `npx next ${bundleAssets ? 'start' : 'dev'} --port ${c.runtime.port}`, {
env: {
...CoreEnvVars.BASE(),
Expand All @@ -147,7 +151,7 @@ Dev server running at: ${url}
...EnvVars.NEXT_BASE(),
...EnvVars.NODE_ENV(),
},
interactive: !c.program?.json,
...opts,
});
};

Expand Down
8 changes: 5 additions & 3 deletions packages/integration-docker/src/docker.ts
Expand Up @@ -14,6 +14,7 @@ import {
writeCleanFile,
fsExistsSync,
chalk,
ExecOptionsPresets,
} from '@rnv/core';

const rootPath = path.join(__dirname, './');
Expand Down Expand Up @@ -171,9 +172,10 @@ class Docker {
const appVersion = files.project.package.version;

logTask('docker:Dockerfile:login');
await executeAsync(`echo "${DOCKERHUB_PASS}" | docker login -u "${DOCKERHUB_USER}" --password-stdin`, {
interactive: true,
});
await executeAsync(
`echo "${DOCKERHUB_PASS}" | docker login -u "${DOCKERHUB_USER}" --password-stdin`,
ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER
);
logTask('docker:Dockerfile:push');
// tagging for versioning
await executeAsync(`docker tag ${imageName}:${appVersion} ${imageTag}:${appVersion}`);
Expand Down
27 changes: 16 additions & 11 deletions packages/sdk-android/src/deviceManager.ts
Expand Up @@ -26,6 +26,8 @@ import {
waitForExecCLI,
inquirerPrompt,
RnvPlatform,
executeAsync,
ExecOptionsPresets,
} from '@rnv/core';
import { CLI_ANDROID_EMULATOR, CLI_ANDROID_ADB, CLI_ANDROID_AVDMANAGER, CLI_ANDROID_SDKMANAGER } from './constants';

Expand Down Expand Up @@ -60,6 +62,7 @@ export const launchAndroidSimulator = async (
`target:${typeof target === 'object' ? target?.name : target} independentThread:${!!isIndependentThread}`
);
let newTarget: { name: string } | string;

if (target === true) {
const {
program: { device },
Expand All @@ -81,11 +84,13 @@ export const launchAndroidSimulator = async (

if (newTarget) {
const actualTarget = typeof newTarget === 'string' ? newTarget : newTarget.name;

if (isIndependentThread) {
execCLI(c, CLI_ANDROID_EMULATOR, `-avd "${actualTarget}"`, {
detached: isIndependentThread,
silent: true,
}).catch((err) => {
executeAsync(
c,
`${c.cli[CLI_ANDROID_EMULATOR]} -avd ${actualTarget}`,
ExecOptionsPresets.FIRE_AND_FORGET
).catch((err) => {
if (err.includes && err.includes('WHPX')) {
logWarning(err);
return logError(
Expand All @@ -97,10 +102,12 @@ export const launchAndroidSimulator = async (
});
return Promise.resolve();
}
return execCLI(c, CLI_ANDROID_EMULATOR, `-avd "${actualTarget}"`, {
detached: isIndependentThread,
silent: true,
});

return executeAsync(
c,
`${c.cli[CLI_ANDROID_EMULATOR]} -avd ${actualTarget}`,
ExecOptionsPresets.SPINNER_FULL_ERROR_SUMMARY
);
}
return Promise.reject('No simulator -t target name specified!');
};
Expand Down Expand Up @@ -611,9 +618,7 @@ const _createEmulator = (c: RnvContext, apiVersion: string, emuPlatform: string,
c,
CLI_ANDROID_AVDMANAGER,
`create avd -n ${emuName} -k "system-images;android-${apiVersion};${emuPlatform};x86"`,
{
interactive: true,
}
ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER
)
)
.catch((e) => logError(e, true));
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk-react-native/src/androidRunner.ts
Expand Up @@ -14,6 +14,7 @@ import {
DEFAULTS,
RnvPlatform,
CoreEnvVars,
ExecOptionsPresets,
} from '@rnv/core';
import { EnvVars } from './env';

Expand Down Expand Up @@ -112,8 +113,7 @@ export const runReactNativeAndroid = async (
},
cwd: appFolder,
//This is required to make rn cli logs visible in rnv executed terminal
interactive: true,
stdio: 'inherit',
...ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER,
});
};

Expand Down
5 changes: 2 additions & 3 deletions packages/sdk-webos/src/deviceManager.ts
Expand Up @@ -18,6 +18,7 @@ import {
RnvContext,
waitForExecCLI,
inquirerPrompt,
ExecOptionsPresets,
} from '@rnv/core';
import { WebosDevice } from './types';
import {
Expand Down Expand Up @@ -196,9 +197,7 @@ export const runWebosSimOrDevice = async (c: RnvContext) => {
logInfo(
'Please follow the instructions from http://webostv.developer.lge.com/develop/app-test/#installDevModeApp on how to setup the TV and the connection with the PC. Then follow the onscreen prompts\n'
);
await execCLI(c, CLI_WEBOS_ARES_SETUP_DEVICE, '', {
interactive: true,
});
await execCLI(c, CLI_WEBOS_ARES_SETUP_DEVICE, '', ExecOptionsPresets.INHERIT_OUTPUT_NO_SPINNER);

const newDeviceResponse = await execCLI(c, CLI_WEBOS_ARES_DEVICE_INFO, '-D');
const dev = await parseDevices(c, newDeviceResponse);
Expand Down

0 comments on commit 478051c

Please sign in to comment.