From 5c3b84b794834a8429feb8a61ddca958232fafb6 Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Wed, 2 Aug 2023 15:48:22 +0200 Subject: [PATCH] fix: move logic to `run-ios/android` commands --- .../src/commands/runAndroid/index.ts | 61 ++++++++++++++---- .../src/commands/runIOS/index.ts | 62 +++++++++++++++---- .../cli-plugin-metro/src/commands/index.ts | 1 - .../src/commands/start/index.ts | 6 -- .../src/commands/start/runServer.ts | 61 ++++++------------ .../src/tools/askForPortChange.ts | 15 ----- .../src/tools/askForProcessKill.ts | 20 ------ .../src/tools/getProcessIdFromPort.ts | 27 -------- .../src => cli-tools}/launchPackager.bat | 0 .../src => cli-tools}/launchPackager.command | 0 .../tools => cli-tools/src}/getNextPort.ts | 2 +- packages/cli-tools/src/index.ts | 3 + packages/cli-tools/src/port.ts | 24 +++++++ .../src}/startServerInNewWindow.ts | 17 ++--- 14 files changed, 156 insertions(+), 143 deletions(-) delete mode 100644 packages/cli-plugin-metro/src/tools/askForPortChange.ts delete mode 100644 packages/cli-plugin-metro/src/tools/askForProcessKill.ts delete mode 100644 packages/cli-plugin-metro/src/tools/getProcessIdFromPort.ts rename packages/{cli-plugin-metro/src => cli-tools}/launchPackager.bat (100%) rename packages/{cli-plugin-metro/src => cli-tools}/launchPackager.command (100%) rename packages/{cli-plugin-metro/src/tools => cli-tools/src}/getNextPort.ts (91%) create mode 100644 packages/cli-tools/src/port.ts rename packages/{cli-plugin-metro/src/commands/start => cli-tools/src}/startServerInNewWindow.ts (90%) diff --git a/packages/cli-platform-android/src/commands/runAndroid/index.ts b/packages/cli-platform-android/src/commands/runAndroid/index.ts index 8e1a5a44f1..065021c953 100644 --- a/packages/cli-platform-android/src/commands/runAndroid/index.ts +++ b/packages/cli-platform-android/src/commands/runAndroid/index.ts @@ -18,6 +18,12 @@ import { CLIError, link, getDefaultUserTerminal, + isPackagerRunning, + getNextPort, + logAlreadyRunningBundler, + askForPortChange, + logChangePortInstructions, + startServerInNewWindow, } from '@react-native-community/cli-tools'; import {getAndroidProject} from '../../config/getAndroidProject'; import listAndroidDevices from './listAndroidDevices'; @@ -28,7 +34,6 @@ import {build, BuildFlags, options} from '../buildAndroid'; import {promptForTaskSelection} from './listAndroidTasks'; import {getTaskNames} from './getTaskNames'; import {checkUsers, promptForUser} from './listAndroidUsers'; -import execa from 'execa'; export interface Flags extends BuildFlags { appId: string; @@ -51,6 +56,50 @@ export type AndroidProject = NonNullable; async function runAndroid(_argv: Array, config: Config, args: Flags) { link.setPlatform('android'); + let {packager, port} = args; + + const packagerStatus = await isPackagerRunning(port); + + const handleSomethingRunningOnPort = async () => { + const {nextPort, start} = await getNextPort(port, config.root); + if (!start) { + packager = false; + logAlreadyRunningBundler(nextPort); + } else { + const {change} = await askForPortChange(nextPort); + + if (change) { + port = nextPort; + } else { + packager = false; + logChangePortInstructions(port); + } + } + }; + + if ( + typeof packagerStatus === 'object' && + packagerStatus.status === 'running' + ) { + if (packagerStatus.root === config.root) { + packager = false; + logAlreadyRunningBundler(port); + } else { + await handleSomethingRunningOnPort(); + } + } else if (packagerStatus === 'unrecognized') { + await handleSomethingRunningOnPort(); + } + + if (packager) { + await startServerInNewWindow( + port, + config.root, + config.reactNativePath, + args.terminal, + ); + } + if (config.reactNativeVersion !== 'unknown') { link.setVersion(config.reactNativeVersion); } @@ -74,16 +123,6 @@ async function runAndroid(_argv: Array, config: Config, args: Flags) { } const androidProject = getAndroidProject(config); - if (args.packager && args.terminal) { - await execa('node', [ - path.join(config.reactNativePath, 'cli.js'), - 'start', - '--port', - args.port.toString(), - '--terminal', - args.terminal, - ]); - } return buildAndRun(args, androidProject); } diff --git a/packages/cli-platform-ios/src/commands/runIOS/index.ts b/packages/cli-platform-ios/src/commands/runIOS/index.ts index 421ea17a6e..1213731077 100644 --- a/packages/cli-platform-ios/src/commands/runIOS/index.ts +++ b/packages/cli-platform-ios/src/commands/runIOS/index.ts @@ -17,6 +17,12 @@ import { CLIError, link, getDefaultUserTerminal, + startServerInNewWindow, + isPackagerRunning, + getNextPort, + askForPortChange, + logAlreadyRunningBundler, + logChangePortInstructions, } from '@react-native-community/cli-tools'; import {BuildFlags, buildProject} from '../buildIOS/buildProject'; import {iosBuildOptions} from '../buildIOS'; @@ -28,7 +34,6 @@ import {getConfigurationScheme} from '../../tools/getConfigurationScheme'; import {selectFromInteractiveMode} from '../../tools/selectFromInteractiveMode'; import {promptForDeviceSelection} from '../../tools/prompts'; import getSimulators from '../../tools/getSimulators'; -import execa from 'execa'; export interface FlagsT extends BuildFlags { simulator?: string; @@ -47,6 +52,50 @@ export interface FlagsT extends BuildFlags { async function runIOS(_: Array, ctx: Config, args: FlagsT) { link.setPlatform('ios'); + let {packager, port} = args; + + const packagerStatus = await isPackagerRunning(port); + + const handleSomethingRunningOnPort = async () => { + const {nextPort, start} = await getNextPort(port, ctx.root); + if (!start) { + packager = false; + logAlreadyRunningBundler(nextPort); + } else { + const {change} = await askForPortChange(nextPort); + + if (change) { + port = nextPort; + } else { + packager = false; + logChangePortInstructions(port); + } + } + }; + + if ( + typeof packagerStatus === 'object' && + packagerStatus.status === 'running' + ) { + if (packagerStatus.root === ctx.root) { + packager = false; + logAlreadyRunningBundler(port); + } else { + await handleSomethingRunningOnPort(); + } + } else if (packagerStatus === 'unrecognized') { + await handleSomethingRunningOnPort(); + } + + if (packager) { + await startServerInNewWindow( + port, + ctx.root, + ctx.reactNativePath, + args.terminal, + ); + } + if (ctx.reactNativeVersion !== 'unknown') { link.setVersion(ctx.reactNativeVersion); } @@ -126,17 +175,6 @@ async function runIOS(_: Array, ctx: Config, args: FlagsT) { } "${chalk.bold(xcodeProject.name)}"`, ); - if (args.packager && args.terminal) { - await execa('node', [ - path.join(ctx.reactNativePath, 'cli.js'), - 'start', - '--port', - args.port.toString(), - '--terminal', - args.terminal, - ]); - } - const availableDevices = await listIOSDevices(); if (modifiedArgs.listDevices || modifiedArgs.interactive) { if (modifiedArgs.device || modifiedArgs.udid) { diff --git a/packages/cli-plugin-metro/src/commands/index.ts b/packages/cli-plugin-metro/src/commands/index.ts index eb9237091e..0b9ffd88ff 100644 --- a/packages/cli-plugin-metro/src/commands/index.ts +++ b/packages/cli-plugin-metro/src/commands/index.ts @@ -4,4 +4,3 @@ import startCommand from './start'; export default [bundleCommand, ramBundleCommand, startCommand]; export {buildBundleWithConfig} from './bundle'; export type {CommandLineArgs} from './bundle'; -export {startServerInNewWindow} from './start'; diff --git a/packages/cli-plugin-metro/src/commands/start/index.ts b/packages/cli-plugin-metro/src/commands/start/index.ts index 6ff4b71267..accfa96eba 100644 --- a/packages/cli-plugin-metro/src/commands/start/index.ts +++ b/packages/cli-plugin-metro/src/commands/start/index.ts @@ -88,11 +88,5 @@ export default { name: '--no-interactive', description: 'Disables interactive mode', }, - { - name: '--terminal', - description: 'Specify terminal app to use for running Metro', - }, ], }; - -export {startServerInNewWindow} from './startServerInNewWindow'; diff --git a/packages/cli-plugin-metro/src/commands/start/runServer.ts b/packages/cli-plugin-metro/src/commands/start/runServer.ts index ddc0cbb90b..be3e1bbc33 100644 --- a/packages/cli-plugin-metro/src/commands/start/runServer.ts +++ b/packages/cli-plugin-metro/src/commands/start/runServer.ts @@ -21,14 +21,12 @@ import { isPackagerRunning, logger, version, + getNextPort, + askForPortChange, + logAlreadyRunningBundler, + logChangePortInstructions, } from '@react-native-community/cli-tools'; import enableWatchMode from './watchMode'; -import {startServerInNewWindow} from './startServerInNewWindow'; -import getNextPort from '../../tools/getNextPort'; -import askForPortChange from '../../tools/askForPortChange'; -import askForProcessKill from '../../tools/askForProcessKill'; -import getProcessIdFromPort from '../../tools/getProcessIdFromPort'; -import execa from 'execa'; import chalk from 'chalk'; export type Args = { @@ -46,52 +44,29 @@ export type Args = { transformer?: string; watchFolders?: string[]; config?: string; - terminal?: string; projectRoot?: string; interactive: boolean; }; -function logAlreadyRunningBundler(port: number) { - logger.info(`Metro Bundler is already for this project on port ${port}.`); -} - -function logChangePortInstructions(port: number) { - logger.info( - `Please close the other packager running on port ${port}, or select another port with "--port".`, - ); -} - async function runServer(_argv: Array, ctx: Config, args: Args) { let port = args.port ?? 8081; - - if (args.terminal) { - startServerInNewWindow(port, ctx.root, ctx.reactNativePath, args.terminal); - return; - } + console.log({port}); const packagerStatus = await isPackagerRunning(port); - + console.log({packagerStatus}); const handleSomethingRunningOnPort = async () => { - const {change: kill} = await askForProcessKill(port); - if (kill) { - const pid = await getProcessIdFromPort(port); - - if (pid) { - execa.sync('kill', [pid]); - } + const {nextPort, start} = await getNextPort(port, ctx.root); + if (!start) { + logAlreadyRunningBundler(nextPort); + process.exit(); } else { - const {nextPort, start} = await getNextPort(port, ctx.root); - if (!start) { - logAlreadyRunningBundler(nextPort); + const {change} = await askForPortChange(nextPort); + console.log('halo'); + if (change) { + port = nextPort; } else { - const {change} = await askForPortChange(nextPort); - - if (change) { - port = nextPort; - } else { - logChangePortInstructions(port); - return; - } + logChangePortInstructions(port); + process.exit(); } } }; @@ -102,7 +77,7 @@ async function runServer(_argv: Array, ctx: Config, args: Args) { ) { if (packagerStatus.root === ctx.root) { logAlreadyRunningBundler(port); - return; + process.exit(); } else { await handleSomethingRunningOnPort(); } @@ -110,6 +85,8 @@ async function runServer(_argv: Array, ctx: Config, args: Args) { await handleSomethingRunningOnPort(); } + console.log('----'); + let reportEvent: ((event: any) => void) | undefined; const terminal = new Terminal(process.stdout); const ReporterImpl = getReporterImpl(args.customLogReporterPath); diff --git a/packages/cli-plugin-metro/src/tools/askForPortChange.ts b/packages/cli-plugin-metro/src/tools/askForPortChange.ts deleted file mode 100644 index 0d85359369..0000000000 --- a/packages/cli-plugin-metro/src/tools/askForPortChange.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {prompt} from '@react-native-community/cli-tools'; - -const askForPortChange = async (port: number) => { - return await prompt({ - name: 'change', - type: 'select', - message: `Use port ${port} instead?`, - choices: [ - {title: 'Yes', value: true}, - {title: 'No', value: false}, - ], - }); -}; - -export default askForPortChange; diff --git a/packages/cli-plugin-metro/src/tools/askForProcessKill.ts b/packages/cli-plugin-metro/src/tools/askForProcessKill.ts deleted file mode 100644 index 2d6c46c258..0000000000 --- a/packages/cli-plugin-metro/src/tools/askForProcessKill.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {logger, prompt} from '@react-native-community/cli-tools'; -import chalk from 'chalk'; - -const askForProcessKill = async (port: number) => { - logger.info( - `Metro is already running on port ${chalk.bold(port)} in another project.`, - ); - - return await prompt({ - name: 'change', - type: 'select', - message: 'Do you want to terminate this process?', - choices: [ - {title: 'Yes', value: true}, - {title: 'No', value: false}, - ], - }); -}; - -export default askForProcessKill; diff --git a/packages/cli-plugin-metro/src/tools/getProcessIdFromPort.ts b/packages/cli-plugin-metro/src/tools/getProcessIdFromPort.ts deleted file mode 100644 index 4896e4d578..0000000000 --- a/packages/cli-plugin-metro/src/tools/getProcessIdFromPort.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {execFileSync} from 'child_process'; - -/** - * @param port The port to find the process id for - * @returns The process id for the port or null if not found - */ - -const getProcessIdFromPort = async (port: number): Promise => { - try { - const result = execFileSync( - 'lsof', - [`-i:${port}`, '-P', '-t', '-sTCP:LISTEN'], - { - encoding: 'utf8', - stdio: ['pipe', 'pipe', 'ignore'], - }, - ) - .split('\n')[0] - .trim(); - - return result; - } catch (error) { - return null; - } -}; - -export default getProcessIdFromPort; diff --git a/packages/cli-plugin-metro/src/launchPackager.bat b/packages/cli-tools/launchPackager.bat similarity index 100% rename from packages/cli-plugin-metro/src/launchPackager.bat rename to packages/cli-tools/launchPackager.bat diff --git a/packages/cli-plugin-metro/src/launchPackager.command b/packages/cli-tools/launchPackager.command similarity index 100% rename from packages/cli-plugin-metro/src/launchPackager.command rename to packages/cli-tools/launchPackager.command diff --git a/packages/cli-plugin-metro/src/tools/getNextPort.ts b/packages/cli-tools/src/getNextPort.ts similarity index 91% rename from packages/cli-plugin-metro/src/tools/getNextPort.ts rename to packages/cli-tools/src/getNextPort.ts index 656beecc36..374fe13c73 100644 --- a/packages/cli-plugin-metro/src/tools/getNextPort.ts +++ b/packages/cli-tools/src/getNextPort.ts @@ -1,4 +1,4 @@ -import {isPackagerRunning} from '@react-native-community/cli-tools'; +import isPackagerRunning from './isPackagerRunning'; type Result = { start: boolean; diff --git a/packages/cli-tools/src/index.ts b/packages/cli-tools/src/index.ts index cc618ab7b1..92d9428bad 100644 --- a/packages/cli-tools/src/index.ts +++ b/packages/cli-tools/src/index.ts @@ -14,5 +14,8 @@ export {default as printRunDoctorTip} from './printRunDoctorTip'; export {default as getPidFromPort} from './getPidFromPort'; export * from './prompt'; export * as link from './doclink'; +export {default as startServerInNewWindow} from './startServerInNewWindow'; +export {default as getNextPort} from './getNextPort'; +export * from './port'; export * from './errors'; diff --git a/packages/cli-tools/src/port.ts b/packages/cli-tools/src/port.ts new file mode 100644 index 0000000000..2b1ba49403 --- /dev/null +++ b/packages/cli-tools/src/port.ts @@ -0,0 +1,24 @@ +import {prompt} from './prompt'; +import logger from './logger'; + +export const askForPortChange = async (port: number) => { + return await prompt({ + name: 'change', + type: 'select', + message: `Use port ${port} instead?`, + choices: [ + {title: 'Yes', value: true}, + {title: 'No', value: false}, + ], + }); +}; + +export const logAlreadyRunningBundler = (port: number) => { + logger.info(`Metro Bundler is already for this project on port ${port}.`); +}; + +export const logChangePortInstructions = (port: number) => { + logger.info( + `Please close the other packager running on port ${port}, or select another port with "--port".`, + ); +}; diff --git a/packages/cli-plugin-metro/src/commands/start/startServerInNewWindow.ts b/packages/cli-tools/src/startServerInNewWindow.ts similarity index 90% rename from packages/cli-plugin-metro/src/commands/start/startServerInNewWindow.ts rename to packages/cli-tools/src/startServerInNewWindow.ts index ad61cb2062..01b67f40b6 100644 --- a/packages/cli-plugin-metro/src/commands/start/startServerInNewWindow.ts +++ b/packages/cli-tools/src/startServerInNewWindow.ts @@ -1,13 +1,11 @@ import path from 'path'; import fs from 'fs'; import execa from 'execa'; -import { - CLIError, - logger, - resolveNodeModuleDir, -} from '@react-native-community/cli-tools'; +import {CLIError} from './errors'; +import resolveNodeModuleDir from './resolveNodeModuleDir'; +import logger from './logger'; -export function startServerInNewWindow( +function startServerInNewWindow( port: number, projectRoot: string, reactNativePath: string, @@ -33,7 +31,7 @@ export function startServerInNewWindow( const nodeModulesPath = resolveNodeModuleDir(projectRoot, '.bin'); const cliPluginMetroPath = path.join( path.dirname( - require.resolve('@react-native-community/cli-plugin-metro/package.json'), + require.resolve('@react-native-community/cli-tools/package.json'), ), 'build', ); @@ -75,8 +73,9 @@ export function startServerInNewWindow( ); } } catch (error) { + console.log('error', error); return new CLIError( - `Couldn't copy the script for running bundler. Please check if the "${scriptFile}" file exists in the "node_modules/@react-native-community/cli-plugin-metro" folder and try again.`, + `Couldn't copy the script for running bundler. Please check if the "${scriptFile}" file exists in the "node_modules/@react-native-community/cli-tools" folder and try again.`, error as any, ); } @@ -116,3 +115,5 @@ export function startServerInNewWindow( ); return; } + +export default startServerInNewWindow;