From 1dbe4faffe6a80ebbd646b6cc3d104e864a6e0bd Mon Sep 17 00:00:00 2001 From: "Michael S. Kazmier" Date: Mon, 2 Oct 2017 10:39:46 -0600 Subject: [PATCH] # This is a combination of 6 commits. # This is the 1st commit message: adds --port option to `react-native run-ios` as well as patches port option with run-android to properly detect and start the packager # This is the commit message #2: refactor iOS build to use preprocessor variable set from env variable; clean up sytle issues # This is the commit message #3: add ifndef for default ports and change name of env var to RCT_METRO_PORT # This is the commit message #4: move defines to RCTDefines.h # This is the commit message #5: add new line # This is the commit message #6: fix code formating issue --- .../RCTWebSocket.xcodeproj/project.pbxproj | 6 +++++ Libraries/WebSocket/RCTWebSocketExecutor.m | 2 +- React/Base/RCTBundleURLProvider.m | 2 +- React/Base/RCTDefines.h | 7 ++++++ React/React.xcodeproj/project.pbxproj | 14 +++++++++-- local-cli/runAndroid/runAndroid.js | 14 +++++++---- local-cli/runIOS/runIOS.js | 24 ++++++++++++------- local-cli/server/server.js | 2 +- local-cli/util/isPackagerRunning.js | 4 ++-- scripts/packager.sh | 1 + 10 files changed, 56 insertions(+), 20 deletions(-) diff --git a/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj b/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj index fbe9c9b97e7d62..8121ed0c108179 100644 --- a/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj +++ b/Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj @@ -433,6 +433,11 @@ isa = XCBuildConfiguration; buildSettings = { EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + "RCT_METRO_PORT=${RCT_METRO_PORT}", + ); GCC_TREAT_WARNINGS_AS_ERRORS = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -443,6 +448,7 @@ isa = XCBuildConfiguration; buildSettings = { EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = "RCT_METRO_PORT=${RCT_METRO_PORT}"; GCC_TREAT_WARNINGS_AS_ERRORS = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Libraries/WebSocket/RCTWebSocketExecutor.m b/Libraries/WebSocket/RCTWebSocketExecutor.m index cb70fc33f3292c..9747730df0d0fc 100644 --- a/Libraries/WebSocket/RCTWebSocketExecutor.m +++ b/Libraries/WebSocket/RCTWebSocketExecutor.m @@ -54,7 +54,7 @@ - (instancetype)initWithURL:(NSURL *)URL - (void)setUp { if (!_url) { - NSInteger port = [[[_bridge bundleURL] port] integerValue] ?: 8081; + NSInteger port = [[[_bridge bundleURL] port] integerValue] ?: RCT_METRO_PORT; NSString *host = [[_bridge bundleURL] host] ?: @"localhost"; NSString *URLString = [NSString stringWithFormat:@"http://%@:%lld/debugger-proxy?role=client", host, (long long)port]; _url = [RCTConvert NSURL:URLString]; diff --git a/React/Base/RCTBundleURLProvider.m b/React/Base/RCTBundleURLProvider.m index 39eb34abc223c5..f6fb3ce8af29fe 100644 --- a/React/Base/RCTBundleURLProvider.m +++ b/React/Base/RCTBundleURLProvider.m @@ -14,7 +14,7 @@ NSString *const RCTBundleURLProviderUpdatedNotification = @"RCTBundleURLProviderUpdatedNotification"; -const NSUInteger kRCTBundleURLProviderDefaultPort = 8081; +const NSUInteger kRCTBundleURLProviderDefaultPort = RCT_METRO_PORT; static NSString *const kRCTJsLocationKey = @"RCT_jsLocation"; static NSString *const kRCTEnableLiveReloadKey = @"RCT_enableLiveReload"; diff --git a/React/Base/RCTDefines.h b/React/Base/RCTDefines.h index a79f76b30554a5..f700e0335080fa 100644 --- a/React/Base/RCTDefines.h +++ b/React/Base/RCTDefines.h @@ -99,3 +99,10 @@ _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \ RCT_EXTERN NSException *_RCTNotImplementedException(SEL, Class); \ method NS_UNAVAILABLE { @throw _RCTNotImplementedException(_cmd, [self class]); } \ _Pragma("clang diagnostic pop") + +/** + * Add the default Metro packager port number + */ +#ifndef RCT_METRO_PORT +#define RCT_METRO_PORT 8081 +#endif diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index ba9fa4daa29280..7e6ed8c1ec8e8a 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -3957,7 +3957,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi"; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:-8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi"; showEnvVarsInLog = 0; }; 142C4F7F1B582EA6001F0B58 /* Include RCTJSCProfiler */ = { @@ -5100,6 +5100,13 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_STATIC_ANALYZER_MODE = deep; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "RCT_DEBUG=1", + "RCT_DEV=1", + "RCT_NSASSERT=1", + "RCT_METRO_PORT=${RCT_METRO_PORT}", + ); GCC_WARN_ABOUT_MISSING_NEWLINE = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5114,7 +5121,10 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_STATIC_ANALYZER_MODE = deep; - GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "RCT_METRO_PORT=${RCT_METRO_PORT}", + ); GCC_WARN_ABOUT_MISSING_NEWLINE = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/local-cli/runAndroid/runAndroid.js b/local-cli/runAndroid/runAndroid.js index 22f0a627ae9ac4..d88235d1c40a18 100644 --- a/local-cli/runAndroid/runAndroid.js +++ b/local-cli/runAndroid/runAndroid.js @@ -45,7 +45,7 @@ function runAndroid(argv, config, args) { return buildAndRun(args); } - return isPackagerRunning().then(result => { + return isPackagerRunning(args.port).then(result => { if (result === 'running') { console.log(chalk.bold('JS server already running.')); } else if (result === 'unrecognized') { @@ -53,7 +53,7 @@ function runAndroid(argv, config, args) { } else { // result == 'not_running' console.log(chalk.bold('Starting JS server...')); - startServerInNewWindow(); + startServerInNewWindow(args.port); } return buildAndRun(args); }); @@ -262,7 +262,7 @@ function runOnAllDevices(args, cmd, packageNameWithSuffix, packageName, adbPath) } } -function startServerInNewWindow() { +function startServerInNewWindow(port) { const scriptFile = /^win/.test(process.platform) ? 'launchPackager.bat' : 'launchPackager.command'; @@ -271,6 +271,12 @@ function startServerInNewWindow() { const procConfig = {cwd: scriptsDir}; const terminal = process.env.REACT_TERMINAL; + // setup the .packager.env file to ensure the packager starts on the right port + const packagerEnvFile = path.join(__dirname, '..', '..', 'scripts', '.packager.env'); + const content = `export RCT_METRO_PORT=${port}`; + // ensure we overwrite file by passing the 'w' flag + fs.writeFileSync(packagerEnvFile, content, {encoding: 'utf8', flag: 'w'}); + if (process.platform === 'darwin') { if (terminal) { return child_process.spawnSync('open', ['-a', terminal, launchPackagerScript], procConfig); @@ -333,7 +339,7 @@ module.exports = { description: 'Do not launch packager while building', }, { command: '--port [number]', - default: 8081, + default: process.env.RCT_METRO_PORT || 8081, parse: (val: string) => Number(val), }], }; diff --git a/local-cli/runIOS/runIOS.js b/local-cli/runIOS/runIOS.js index cfa9ac630db2bc..1dce9c2939420b 100644 --- a/local-cli/runIOS/runIOS.js +++ b/local-cli/runIOS/runIOS.js @@ -78,7 +78,7 @@ function runIOS(argv, config, args) { function runOnDeviceByUdid(args, scheme, xcodeProject, devices) { const selectedDevice = matchingDeviceByUdid(devices, args.udid); if (selectedDevice) { - return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose); + return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose, args.port); } else { if (devices && devices.length > 0) { console.log('Could not find device with the udid: "' + args.udid + '".'); @@ -115,7 +115,7 @@ function runOnSimulator(xcodeProject, args, scheme) { } resolve(selectedSimulator.udid); }) - .then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager, args.verbose)) + .then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager, args.verbose, args.port)) .then((appName) => { if (!appName) { appName = scheme; @@ -135,8 +135,8 @@ function runOnSimulator(xcodeProject, args, scheme) { }); } -function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager, verbose) { - return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager, verbose) +function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager, verbose, port) { + return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager, verbose, port) .then((appName) => { if (!appName) { appName = scheme; @@ -159,7 +159,7 @@ function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launch }); } -function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false, verbose) { +function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false, verbose, port) { return new Promise((resolve,reject) => { var xcodebuildArgs = [ @@ -174,7 +174,7 @@ function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launc if (!verbose) { xcpretty = xcprettyAvailable() && child_process.spawn('xcpretty', [], { stdio: ['pipe', process.stdout, process.stderr] }); } - const buildProcess = child_process.spawn('xcodebuild', xcodebuildArgs, getProcessOptions(launchPackager)); + const buildProcess = child_process.spawn('xcodebuild', xcodebuildArgs, getProcessOptions(launchPackager, port)); let buildOutput = ''; buildProcess.stdout.on('data', function(data) { buildOutput += data.toString(); @@ -232,13 +232,15 @@ function printFoundDevices(devices) { } } -function getProcessOptions(launchPackager) { +function getProcessOptions(launchPackager, port) { if (launchPackager) { - return {}; + return { + env: { ...process.env, RCT_METRO_PORT: port } + }; } return { - env: Object.assign({}, process.env, { RCT_NO_LAUNCH_PACKAGER: true }), + env: { ...process.env, RCT_NO_LAUNCH_PACKAGER: true }, }; } @@ -287,5 +289,9 @@ module.exports = { }, { command: '--verbose', description: 'Do not use xcpretty even if installed', + },{ + command: '--port [number]', + default: process.env.RCT_METRO_PORT || 8081, + parse: (val: string) => Number(val), }], }; diff --git a/local-cli/server/server.js b/local-cli/server/server.js index e3498835cb20a3..df4fd22a2c7f85 100644 --- a/local-cli/server/server.js +++ b/local-cli/server/server.js @@ -60,7 +60,7 @@ module.exports = { description: 'starts the webserver', options: [{ command: '--port [number]', - default: 8081, + default: process.env.RCT_METRO_PORT || 8081, parse: (val: string) => Number(val), }, { command: '--host [string]', diff --git a/local-cli/util/isPackagerRunning.js b/local-cli/util/isPackagerRunning.js index 82828c1afd5f89..fbdebd08d255f9 100644 --- a/local-cli/util/isPackagerRunning.js +++ b/local-cli/util/isPackagerRunning.js @@ -19,8 +19,8 @@ const fetch = require('node-fetch'); * - `unrecognized`: one other process is running on the port we expect the * packager to be running. */ -function isPackagerRunning() { - return fetch('http://localhost:8081/status').then( +function isPackagerRunning(packagerPort = (process.env.RCT_METRO_PORT || 8081)) { + return fetch(`http://localhost:${packagerPort}/status`).then( res => res.text().then(body => body === 'packager-status:running' ? 'running' : 'unrecognized' ), diff --git a/scripts/packager.sh b/scripts/packager.sh index 2f5bc15a05fa6f..f7ce245a42403d 100755 --- a/scripts/packager.sh +++ b/scripts/packager.sh @@ -8,5 +8,6 @@ # of patent rights can be found in the PATENTS file in the same directory. THIS_DIR=$(dirname "$0") +source "${THIS_DIR}/.packager.env" cd "$THIS_DIR/.." node "./local-cli/cli.js" start "$@"