From 7b803f2a7329af131479527d8ca2fd11aead9324 Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 00:10:09 +0100 Subject: [PATCH 1/9] chore: update Podfile locks --- apps/tester-app/ios/Podfile.lock | 4 ++-- apps/tester-federation-v2/ios/Podfile.lock | 4 ++-- apps/tester-federation/ios/Podfile.lock | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/tester-app/ios/Podfile.lock b/apps/tester-app/ios/Podfile.lock index 6aa37aae3..794d6a02f 100644 --- a/apps/tester-app/ios/Podfile.lock +++ b/apps/tester-app/ios/Podfile.lock @@ -1,6 +1,6 @@ PODS: - boost (1.84.0) - - callstack-repack (5.0.0-rc.2): + - callstack-repack (5.0.0-rc.3): - DoubleConversion - glog - hermes-engine @@ -1942,7 +1942,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 1dca942403ed9342f98334bf4c3621f011aa7946 - callstack-repack: 3106db24c24f7a76a380230ff7794d225cecb760 + callstack-repack: 5219eedfb8cb06b905edecffaecf71af4a4ecdd6 DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 FBLazyVector: be7314029d6ec6b90f0f75ce1195b8130ed9ac4f fmt: 10c6e61f4be25dc963c36bd73fc7b1705fe975be diff --git a/apps/tester-federation-v2/ios/Podfile.lock b/apps/tester-federation-v2/ios/Podfile.lock index 0bddccaa7..7c7f7ba88 100644 --- a/apps/tester-federation-v2/ios/Podfile.lock +++ b/apps/tester-federation-v2/ios/Podfile.lock @@ -1,6 +1,6 @@ PODS: - boost (1.84.0) - - callstack-repack (5.0.0-rc.2): + - callstack-repack (5.0.0-rc.3): - DoubleConversion - glog - hermes-engine @@ -1895,7 +1895,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 1dca942403ed9342f98334bf4c3621f011aa7946 - callstack-repack: 3106db24c24f7a76a380230ff7794d225cecb760 + callstack-repack: 5219eedfb8cb06b905edecffaecf71af4a4ecdd6 DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 FBLazyVector: be7314029d6ec6b90f0f75ce1195b8130ed9ac4f fmt: 10c6e61f4be25dc963c36bd73fc7b1705fe975be diff --git a/apps/tester-federation/ios/Podfile.lock b/apps/tester-federation/ios/Podfile.lock index 0c93df42c..112f19369 100644 --- a/apps/tester-federation/ios/Podfile.lock +++ b/apps/tester-federation/ios/Podfile.lock @@ -1,6 +1,6 @@ PODS: - boost (1.84.0) - - callstack-repack (5.0.0-rc.2): + - callstack-repack (5.0.0-rc.3): - DoubleConversion - glog - hermes-engine @@ -1919,7 +1919,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 1dca942403ed9342f98334bf4c3621f011aa7946 - callstack-repack: 3106db24c24f7a76a380230ff7794d225cecb760 + callstack-repack: 5219eedfb8cb06b905edecffaecf71af4a4ecdd6 DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 FBLazyVector: be7314029d6ec6b90f0f75ce1195b8130ed9ac4f fmt: 10c6e61f4be25dc963c36bd73fc7b1705fe975be From 8357e3e182a79cde92c245cc8c7d3fd141b51489 Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 01:43:44 +0100 Subject: [PATCH 2/9] feat: wait-for-device before adb --- .../src/commands/common/runAdbReverse.ts | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/packages/repack/src/commands/common/runAdbReverse.ts b/packages/repack/src/commands/common/runAdbReverse.ts index 94ab039aa..11ebcc46b 100644 --- a/packages/repack/src/commands/common/runAdbReverse.ts +++ b/packages/repack/src/commands/common/runAdbReverse.ts @@ -1,35 +1,56 @@ +import path from 'node:path'; import execa from 'execa'; import type { Logger } from '../../types'; interface RunAdbReverseParams { + logger?: Logger; port: number; verbose?: boolean; - logger?: Logger; + wait?: boolean; +} + +function getAdbPath() { + const androidHome = process.env.ANDROID_HOME; + return androidHome + ? path.resolve(androidHome, 'platform-tools', 'adb') + : 'adb'; +} + +async function waitForDevice() { + const adbPath = getAdbPath(); + const command = `${adbPath} wait-for-device`; + return execa.command(command); +} + +async function reversePort(port: number) { + const adbPath = getAdbPath(); + const command = `${adbPath} reverse tcp:${port} tcp:${port}`; + return execa.command(command); } export async function runAdbReverse({ + logger = console, port, verbose = false, - logger = console, + wait = false, }: RunAdbReverseParams) { - const adbPath = process.env.ANDROID_HOME - ? `${process.env.ANDROID_HOME}/platform-tools/adb` - : 'adb'; - const command = `${adbPath} reverse tcp:${port} tcp:${port}`; - const info = JSON.stringify({ port, adbPath, command }); - try { - await execa.command(command); + if (wait) { + await waitForDevice(); + } + await reversePort(port); if (verbose) { logger.info('adb reverse success'); } - logger.debug(`adb reverse success: ${info}`); + logger.debug(`adb reverse success: ${{ port }}`); } catch (error) { - const message = - (error as Error).message.split('error:')[1] || (error as Error).message; + const errorMessage = (error as Error).message; + const message = errorMessage.includes('error:') + ? errorMessage.split('error:')[1].trim() + : errorMessage; if (verbose) { logger.warn(`adb reverse failed: "${message.trim()}"`); } - logger.debug(`adb reverse failed: "${message.trim()}" ${info}`); + logger.debug(`adb reverse failed: "${message.trim()}" ${{ port }}`); } } From 73e43d2d8defbd587412741520df2410f0a48fbe Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 01:45:08 +0100 Subject: [PATCH 3/9] feat: wait for device in start commands --- packages/repack/src/commands/rspack/start.ts | 2 +- packages/repack/src/commands/webpack/start.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/repack/src/commands/rspack/start.ts b/packages/repack/src/commands/rspack/start.ts index 0cdf455db..b58aba263 100644 --- a/packages/repack/src/commands/rspack/start.ts +++ b/packages/repack/src/commands/rspack/start.ts @@ -127,7 +127,7 @@ export async function start( } if (reversePort) { - void runAdbReverse({ port: serverPort, logger: ctx.log }); + void runAdbReverse({ logger: ctx.log, port: serverPort, wait: true }); } compiler.setDevServerContext(ctx); diff --git a/packages/repack/src/commands/webpack/start.ts b/packages/repack/src/commands/webpack/start.ts index 4c3ee07a8..02ae4badf 100644 --- a/packages/repack/src/commands/webpack/start.ts +++ b/packages/repack/src/commands/webpack/start.ts @@ -125,7 +125,7 @@ export async function start(_: string[], config: Config, args: StartArguments) { } if (reversePort) { - void runAdbReverse({ port: serverPort, logger: ctx.log }); + void runAdbReverse({ logger: ctx.log, port: serverPort, wait: true }); } const lastStats: Record = {}; From 5720c4ecb9974f2fffbc51e0617b1417a19b6b14 Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 01:54:20 +0100 Subject: [PATCH 4/9] chore: upgrade rnta --- apps/tester-app/package.json | 2 +- apps/tester-federation-v2/package.json | 2 +- apps/tester-federation/package.json | 2 +- pnpm-lock.yaml | 26 +++++++++++++------------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/tester-app/package.json b/apps/tester-app/package.json index d8604f377..6b70a79e6 100644 --- a/apps/tester-app/package.json +++ b/apps/tester-app/package.json @@ -43,7 +43,7 @@ "get-port": "^6.1.2", "globby": "^13.1.2", "http-server": "^14.1.1", - "react-native-test-app": "^4.0.4", + "react-native-test-app": "^4.0.7", "terser-webpack-plugin": "^5.3.10", "typescript": "^5.5.3", "vitest": "^2.0.5", diff --git a/apps/tester-federation-v2/package.json b/apps/tester-federation-v2/package.json index de257636e..4be23aad0 100644 --- a/apps/tester-federation-v2/package.json +++ b/apps/tester-federation-v2/package.json @@ -37,7 +37,7 @@ "get-port": "^6.1.2", "globby": "^13.1.2", "http-server": "^14.1.1", - "react-native-test-app": "^4.0.4", + "react-native-test-app": "^4.0.7", "terser-webpack-plugin": "^5.3.3", "typescript": "^5.5.3", "webpack": "^5.91.0" diff --git a/apps/tester-federation/package.json b/apps/tester-federation/package.json index 0845e7e75..3bccf21d0 100644 --- a/apps/tester-federation/package.json +++ b/apps/tester-federation/package.json @@ -44,7 +44,7 @@ "get-port": "^6.1.2", "globby": "^13.1.2", "http-server": "^14.1.1", - "react-native-test-app": "^4.0.4", + "react-native-test-app": "^4.0.7", "typescript": "^5.5.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aae7a7c32..a59f9015b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,8 +127,8 @@ importers: specifier: ^14.1.1 version: 14.1.1 react-native-test-app: - specifier: ^4.0.4 - version: 4.0.4(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) + specifier: ^4.0.7 + version: 4.0.7(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) terser-webpack-plugin: specifier: ^5.3.10 version: 5.3.10(webpack@5.94.0) @@ -218,8 +218,8 @@ importers: specifier: ^14.1.1 version: 14.1.1 react-native-test-app: - specifier: ^4.0.4 - version: 4.0.4(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) + specifier: ^4.0.7 + version: 4.0.7(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) typescript: specifier: ^5.5.3 version: 5.5.3 @@ -300,8 +300,8 @@ importers: specifier: ^14.1.1 version: 14.1.1 react-native-test-app: - specifier: ^4.0.4 - version: 4.0.4(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) + specifier: ^4.0.7 + version: 4.0.7(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) terser-webpack-plugin: specifier: ^5.3.3 version: 5.3.10(webpack@5.94.0) @@ -2205,8 +2205,8 @@ packages: resolution: {integrity: sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==} engines: {node: '>=14.0.0'} - '@rnx-kit/react-native-host@0.5.0': - resolution: {integrity: sha512-ZuHDl899uZyqk4qcBkGMRmVp2u6EXLikMAVd0ry7u2gWll0dZSfM2TbDHGq5Z0d8qpdAdSTRB0bYpvwmEznxVQ==} + '@rnx-kit/react-native-host@0.5.2': + resolution: {integrity: sha512-m3vZlQgQIVIogHKWUsukn+kiDQid3zen+C9UOlzZ6mMzNoZ0onL6cs6np4jBQoOaUtXPV9I8yueS02vwvhKjWA==} engines: {node: '>=16.17'} peerDependencies: react-native: '>=0.66' @@ -6169,8 +6169,8 @@ packages: react: '*' react-native: '*' - react-native-test-app@4.0.4: - resolution: {integrity: sha512-s+tsPoOuK9cMyCS5KXqfLIClwXz6Wpd1ObaEqx0CEOFcF7tFQTd8gTUyMUKwFmFPwx/OuzoyT0X3Qo8kqD9Xgg==} + react-native-test-app@4.0.7: + resolution: {integrity: sha512-dJrcq6aSVGEpYuM2EjB3jSeW6Cvm++XFx/Nc15q15UFnn1A4uoECVHwpmZd7AwwsXXyb1me/sOeo/tEePab27Q==} engines: {node: '>=16.17'} hasBin: true peerDependencies: @@ -9784,7 +9784,7 @@ snapshots: '@remix-run/router@1.20.0': {} - '@rnx-kit/react-native-host@0.5.0(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))': + '@rnx-kit/react-native-host@0.5.2(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))': dependencies: react-native: 0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1) @@ -14881,9 +14881,9 @@ snapshots: react-native: 0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1) warn-once: 0.1.1 - react-native-test-app@4.0.4(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1): + react-native-test-app@4.0.7(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1))(react@18.3.1): dependencies: - '@rnx-kit/react-native-host': 0.5.0(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1)) + '@rnx-kit/react-native-host': 0.5.2(react-native@0.76.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@react-native-community/cli-server-api@15.0.1)(@types/react@18.3.3)(react@18.3.1)) '@rnx-kit/tools-react-native': 2.0.3 ajv: 8.17.1 cliui: 8.0.1 From 1d2048698a699ed6f5f096c3123590c04b60795a Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 01:58:39 +0100 Subject: [PATCH 5/9] chore: add changeset --- .changeset/odd-teachers-repeat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/odd-teachers-repeat.md diff --git a/.changeset/odd-teachers-repeat.md b/.changeset/odd-teachers-repeat.md new file mode 100644 index 000000000..a5cdfa351 --- /dev/null +++ b/.changeset/odd-teachers-repeat.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack": minor +--- + +Wait for android device before running adb reverse when starting dev-server From ebe168dc795719bda7370092a0278eb9d113f2c3 Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 12:18:28 +0100 Subject: [PATCH 6/9] refactor: use path.join instead of path.resolve --- packages/repack/src/commands/common/runAdbReverse.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/repack/src/commands/common/runAdbReverse.ts b/packages/repack/src/commands/common/runAdbReverse.ts index 11ebcc46b..12e5be7d7 100644 --- a/packages/repack/src/commands/common/runAdbReverse.ts +++ b/packages/repack/src/commands/common/runAdbReverse.ts @@ -11,9 +11,7 @@ interface RunAdbReverseParams { function getAdbPath() { const androidHome = process.env.ANDROID_HOME; - return androidHome - ? path.resolve(androidHome, 'platform-tools', 'adb') - : 'adb'; + return androidHome ? path.join(androidHome, 'platform-tools', 'adb') : 'adb'; } async function waitForDevice() { From beb022bb22b28f9373c94f956f1bf8dee550772d Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Tue, 17 Dec 2024 23:21:39 +0100 Subject: [PATCH 7/9] feat: reverse on all available devices --- .../src/commands/common/runAdbReverse.ts | 78 +++++++++++++++---- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/packages/repack/src/commands/common/runAdbReverse.ts b/packages/repack/src/commands/common/runAdbReverse.ts index 12e5be7d7..ce92e3177 100644 --- a/packages/repack/src/commands/common/runAdbReverse.ts +++ b/packages/repack/src/commands/common/runAdbReverse.ts @@ -14,18 +14,64 @@ function getAdbPath() { return androidHome ? path.join(androidHome, 'platform-tools', 'adb') : 'adb'; } -async function waitForDevice() { - const adbPath = getAdbPath(); - const command = `${adbPath} wait-for-device`; - return execa.command(command); +function parseAdbError(error: unknown) { + const errorMessage = (error as Error).message; + const message = errorMessage.includes('error:') + ? errorMessage.split('error:')[1] + : errorMessage; + return message.trim(); } -async function reversePort(port: number) { +async function executeAdbCommand(command: string, logger: Logger) { const adbPath = getAdbPath(); - const command = `${adbPath} reverse tcp:${port} tcp:${port}`; - return execa.command(command); + try { + const result = await execa.command(`${adbPath} ${command}`); + logger.debug(`[ADB] "adb ${command}" executed successfully.`); + return result; + } catch (error) { + const message = parseAdbError(error); + logger.debug(`[ADB] "adb ${command}" failed: "${message}"`); + throw new Error(message); + } } +async function waitForDevice(logger: Logger) { + try { + await executeAdbCommand('wait-for-device', logger); + } catch (error) { + const message = (error as Error).message; + if (/more than one device\/emulator/.test(message)) { + return; + } + throw error; + } +} + +async function reversePort(port: number, device: string, logger: Logger) { + await executeAdbCommand( + `-s ${device} reverse tcp:${port} tcp:${port}`, + logger + ); +} + +async function getDevices(logger: Logger): Promise { + const { stdout } = await executeAdbCommand('devices', logger); + const devices = stdout + .split('\n') + .slice(1) + .map((line) => line.split('\t')[0]) + .filter(Boolean); + logger.debug(`[ADB] Found ${devices.length} devices/emulators.`); + return devices; +} + +/** + * Runs the adb reverse command to reverse the specified port on all available devices. + * Performs the following steps: + * 1. (Optional) Waits for the device to be available. + * 2. Get a list of all connected devices. + * 3. Attempts to reverse the specified port using adb for all devices. + */ export async function runAdbReverse({ logger = console, port, @@ -34,21 +80,19 @@ export async function runAdbReverse({ }: RunAdbReverseParams) { try { if (wait) { - await waitForDevice(); + await waitForDevice(logger); + } + const devices = await getDevices(logger); + for (const device of devices) { + await reversePort(port, device, logger); } - await reversePort(port); if (verbose) { - logger.info('adb reverse success'); + logger.info('[ADB] port reverse success'); } - logger.debug(`adb reverse success: ${{ port }}`); } catch (error) { - const errorMessage = (error as Error).message; - const message = errorMessage.includes('error:') - ? errorMessage.split('error:')[1].trim() - : errorMessage; + const message = (error as Error).message; if (verbose) { - logger.warn(`adb reverse failed: "${message.trim()}"`); + logger.warn(`[ADB] port reverse failed: "${message}"`); } - logger.debug(`adb reverse failed: "${message.trim()}" ${{ port }}`); } } From ca372b74f34bf0c1ae0c65b3040bc163b2a50243 Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Wed, 18 Dec 2024 15:17:09 +0100 Subject: [PATCH 8/9] chore: add 2nd changeset --- .changeset/khaki-days-call.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/khaki-days-call.md diff --git a/.changeset/khaki-days-call.md b/.changeset/khaki-days-call.md new file mode 100644 index 000000000..1361697ee --- /dev/null +++ b/.changeset/khaki-days-call.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack": minor +--- + +Run adb reverse for all available devices by default From d699586b83a397c4ebf0a0f56e2b6ad7c1dd6f21 Mon Sep 17 00:00:00 2001 From: Jakub Romanczyk Date: Wed, 18 Dec 2024 15:24:01 +0100 Subject: [PATCH 9/9] chore: add comment about error case in wait-for-device --- packages/repack/src/commands/common/runAdbReverse.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/repack/src/commands/common/runAdbReverse.ts b/packages/repack/src/commands/common/runAdbReverse.ts index ce92e3177..ad1194cef 100644 --- a/packages/repack/src/commands/common/runAdbReverse.ts +++ b/packages/repack/src/commands/common/runAdbReverse.ts @@ -40,6 +40,8 @@ async function waitForDevice(logger: Logger) { await executeAdbCommand('wait-for-device', logger); } catch (error) { const message = (error as Error).message; + // Ignore the error if there are multiple devices/emulators + // we only care about about at least 1 device being online if (/more than one device\/emulator/.test(message)) { return; }