From b8481611afca83e8b4751cc063c0215aba19d674 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 10:18:37 +0200 Subject: [PATCH 01/25] Add iOS build phase --- bin/xcode.sh | 56 ++++++++++++++++++++++++++++++++++++++++++++ src/commands/init.js | 55 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100755 bin/xcode.sh diff --git a/bin/xcode.sh b/bin/xcode.sh new file mode 100755 index 00000000..ebf87671 --- /dev/null +++ b/bin/xcode.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# Bundles React Native code and image for offline use. +# +# This script is supposed to be called as a part of Xcode build process +# and relies on its environment variables. +# +# Adopted from: +# https://github.com/facebook/react-native/blob/master/packager/react-native-xcode.sh + +case "$CONFIGURATION" in + Debug) + if [[ "$PLATFORM_NAME" == *simulator ]]; then + echo "Skipping bundling for Simulator platform" + exit 0; + fi + + DEV=true + ;; + "") + echo "$0 must be invoked by Xcode" + exit 1 + ;; + *) + DEV=false + ;; +esac + +# Locate absolute path to Haul directory +HAUL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +# Move two levels up to React Native project +cd "${HAUL_DIR}"/../.. + +# Path to folder where to save assets and bundle +DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH + +# In Debug mode for non simulators, automatically detect IP address +if [[ "$CONFIGURATION" = "Debug" && ! "$PLATFORM_NAME" == *simulator ]]; then + PLISTBUDDY='/usr/libexec/PlistBuddy' + PLIST=$TARGET_BUILD_DIR/$INFOPLIST_PATH + IP=$(ipconfig getifaddr en0) + if [ -z "$IP" ]; then + IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}') + fi + $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:localhost:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" + $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:$IP.xip.io:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" + echo "$IP.xip.io" > "$DEST/ip.txt" +fi + +# Execute Haul +"$HAUL_DIR/bin/cli.js" bundle \ + --platform ios \ + --dev $DEV \ + --bundle-output "$DEST/main.jsbundle" \ + --assets-dest "$DEST" \ No newline at end of file diff --git a/src/commands/init.js b/src/commands/init.js index a812630a..86a303e0 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -125,6 +125,8 @@ async function init() { progress.warn(messages.gitNotFound()); } + await addHaulToiOSBuild(cwd); + progress = ora(messages.generatingConfig()).start(); await new Promise(resolve => setTimeout(resolve, 1000)); @@ -140,6 +142,59 @@ async function init() { progress.succeed(messages.generatedConfig()); } +const sleep = (time: number = 1000) => + new Promise(resolve => setTimeout(resolve, time)); + +// Adds Haul to iOS build pipeline +const addHaulToiOSBuild = async (cwd: string) => { + let entry; + + // Does `ios/*.xcodeproj` exist? + const iosPath = path.join(cwd, 'ios'); + if (fs.existsSync(iosPath)) { + const list = fs + .readdirSync(path.join(cwd, 'ios')) + .filter(file => file.includes('.xcodeproj')); + + // Do nothing if multiple projects were found + if (list.length === 1) { + entry = path.join(iosPath, list[0]); + } + } + + // Otherwise, ask for path to a file + if (!entry) { + const result = await inquirer.prompt([ + { + type: 'input', + name: 'entry', + message: 'Enter full path to your .xcodeproj file', + validate: pathToFile => + fs.existsSync(pathToFile) && pathToFile.includes('.xcodeproj') + ? true + : `${pathToFile} doesn't exist`, + }, + ]); + + entry = path.join(cwd, result.entry); + } + + const progress = ora('Adding `haul` to iOS build pipeline'); + + await sleep(); + + let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); + + project = project.replace( + /export NODE_BINARY=node\\n\.\.\/node_modules\/react-native\/packager\/react-native-xcode\.sh/g, + '../node_modules/haul/bin/xcode.sh', + ); + + fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); + + progress.succeed('Added `haul` to iOS build'); +}; + module.exports = { name: 'init', description: 'Generates necessary configuration files', From f2d0e66cb5eee4cd38026235b1146951a8b8541e Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 10:20:00 +0200 Subject: [PATCH 02/25] Fix typo --- bin/xcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/xcode.sh b/bin/xcode.sh index ebf87671..5b9cac23 100755 --- a/bin/xcode.sh +++ b/bin/xcode.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Bundles React Native code and image for offline use. +# Bundles React Native code and images for offline use. # # This script is supposed to be called as a part of Xcode build process # and relies on its environment variables. From 74c73e1a16016d8723476f5688782fdd3eed0a8c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 10:47:40 +0200 Subject: [PATCH 03/25] Miscs --- src/commands/init.js | 8 ++++---- src/messages/addedToBuildPipeline.js | 8 ++++++++ src/messages/addingToBuildPipeline.js | 8 ++++++++ src/messages/enterXcodeProjectFileName.js | 8 ++++++++ src/messages/index.js | 4 ++++ src/messages/xcodeProjectNotFound.js | 9 +++++++++ 6 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/messages/addedToBuildPipeline.js create mode 100644 src/messages/addingToBuildPipeline.js create mode 100644 src/messages/enterXcodeProjectFileName.js create mode 100644 src/messages/xcodeProjectNotFound.js diff --git a/src/commands/init.js b/src/commands/init.js index 86a303e0..d36e0d36 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -168,18 +168,18 @@ const addHaulToiOSBuild = async (cwd: string) => { { type: 'input', name: 'entry', - message: 'Enter full path to your .xcodeproj file', + message: messages.enterXcodeProjectFileName(), validate: pathToFile => fs.existsSync(pathToFile) && pathToFile.includes('.xcodeproj') ? true - : `${pathToFile} doesn't exist`, + : messages.xcodeProjectNotFound(pathToFile), }, ]); entry = path.join(cwd, result.entry); } - const progress = ora('Adding `haul` to iOS build pipeline'); + const progress = ora(messages.addingToBuildPipeline()); await sleep(); @@ -192,7 +192,7 @@ const addHaulToiOSBuild = async (cwd: string) => { fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); - progress.succeed('Added `haul` to iOS build'); + progress.succeed(messages.addedToBuildPipeline()); }; module.exports = { diff --git a/src/messages/addedToBuildPipeline.js b/src/messages/addedToBuildPipeline.js new file mode 100644 index 00000000..37d0e36d --- /dev/null +++ b/src/messages/addedToBuildPipeline.js @@ -0,0 +1,8 @@ +/** + * Copyright 2017-present, Callstack. + * All rights reserved. + * + * @flow + */ + +module.exports = () => `Adding haul to your native build pipeline`; diff --git a/src/messages/addingToBuildPipeline.js b/src/messages/addingToBuildPipeline.js new file mode 100644 index 00000000..bdaabede --- /dev/null +++ b/src/messages/addingToBuildPipeline.js @@ -0,0 +1,8 @@ +/** + * Copyright 2017-present, Callstack. + * All rights reserved. + * + * @flow + */ + +module.exports = () => `Added haul to your native build pipeline`; diff --git a/src/messages/enterXcodeProjectFileName.js b/src/messages/enterXcodeProjectFileName.js new file mode 100644 index 00000000..734c8143 --- /dev/null +++ b/src/messages/enterXcodeProjectFileName.js @@ -0,0 +1,8 @@ +/** + * Copyright 2017-present, Callstack. + * All rights reserved. + * + * @flow + */ + +module.exports = () => `Enter the name of the .xcodeproj file`; diff --git a/src/messages/index.js b/src/messages/index.js index 40e92c64..6d3ec1ad 100644 --- a/src/messages/index.js +++ b/src/messages/index.js @@ -6,6 +6,8 @@ */ module.exports = { + addingToBuildPipeline: require('./addingToBuildPipeline'), + addedToBuildPipeline: require('./addedToBuildPipeline'), webpackConfigNotFound: require('./webpackConfigNotFound'), initialStartInformation: require('./initialStartInformation'), initialBundleInformation: require('./initialBundleInformation'), @@ -15,6 +17,7 @@ module.exports = { commandNotImplemented: require('./commandNotImplemented'), commandNotFound: require('./commandNotFound'), commandFailed: require('./commandFailed'), + enterXcodeProjectFileName: require('./enterXcodeProjectFileName'), invalidOption: require('./invalidOption'), haulHelp: require('./haulHelp'), haulCommandHelp: require('./haulCommandHelp'), @@ -33,4 +36,5 @@ module.exports = { gitAddedEntries: require('./gitAddedEntries'), gitAlreadyAdded: require('./gitAlreadyAdded'), gitNotFound: require('./gitNotFound'), + xcodeProjectNotFound: require('./xcodeProjectNotFound'), }; diff --git a/src/messages/xcodeProjectNotFound.js b/src/messages/xcodeProjectNotFound.js new file mode 100644 index 00000000..3d13c246 --- /dev/null +++ b/src/messages/xcodeProjectNotFound.js @@ -0,0 +1,9 @@ +/** + * Copyright 2017-present, Callstack. + * All rights reserved. + * + * @flow + */ + +module.exports = (pathToFile: string) => + `Xcode project wasn't found at ${pathToFile}`; From de841712ec3e38594b08aba33c6e032355348a77 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 10:50:16 +0200 Subject: [PATCH 04/25] Tweaks --- src/commands/init.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index d36e0d36..ec006e47 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -125,7 +125,7 @@ async function init() { progress.warn(messages.gitNotFound()); } - await addHaulToiOSBuild(cwd); + await addToXcodeBuild(cwd); progress = ora(messages.generatingConfig()).start(); @@ -145,8 +145,11 @@ async function init() { const sleep = (time: number = 1000) => new Promise(resolve => setTimeout(resolve, time)); -// Adds Haul to iOS build pipeline -const addHaulToiOSBuild = async (cwd: string) => { +/** + * Adds Haul to native iOS build pipeline by: + * 1) replacing all calls to `react-native-xcode.sh` with Haul own run script + */ +const addToXcodeBuild = async (cwd: string) => { let entry; // Does `ios/*.xcodeproj` exist? From 280d69a5b963712c767688849afb76e293d29c3a Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 11:08:45 +0200 Subject: [PATCH 05/25] Use vendored copy --- bin/xcode.sh | 56 --------------------- src/commands/init.js | 2 +- vendor/react-native-xcode.sh | 96 ++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 57 deletions(-) delete mode 100755 bin/xcode.sh create mode 100644 vendor/react-native-xcode.sh diff --git a/bin/xcode.sh b/bin/xcode.sh deleted file mode 100755 index 5b9cac23..00000000 --- a/bin/xcode.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -# Bundles React Native code and images for offline use. -# -# This script is supposed to be called as a part of Xcode build process -# and relies on its environment variables. -# -# Adopted from: -# https://github.com/facebook/react-native/blob/master/packager/react-native-xcode.sh - -case "$CONFIGURATION" in - Debug) - if [[ "$PLATFORM_NAME" == *simulator ]]; then - echo "Skipping bundling for Simulator platform" - exit 0; - fi - - DEV=true - ;; - "") - echo "$0 must be invoked by Xcode" - exit 1 - ;; - *) - DEV=false - ;; -esac - -# Locate absolute path to Haul directory -HAUL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -# Move two levels up to React Native project -cd "${HAUL_DIR}"/../.. - -# Path to folder where to save assets and bundle -DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH - -# In Debug mode for non simulators, automatically detect IP address -if [[ "$CONFIGURATION" = "Debug" && ! "$PLATFORM_NAME" == *simulator ]]; then - PLISTBUDDY='/usr/libexec/PlistBuddy' - PLIST=$TARGET_BUILD_DIR/$INFOPLIST_PATH - IP=$(ipconfig getifaddr en0) - if [ -z "$IP" ]; then - IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}') - fi - $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:localhost:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" - $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:$IP.xip.io:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" - echo "$IP.xip.io" > "$DEST/ip.txt" -fi - -# Execute Haul -"$HAUL_DIR/bin/cli.js" bundle \ - --platform ios \ - --dev $DEV \ - --bundle-output "$DEST/main.jsbundle" \ - --assets-dest "$DEST" \ No newline at end of file diff --git a/src/commands/init.js b/src/commands/init.js index ec006e47..75295fe8 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -190,7 +190,7 @@ const addToXcodeBuild = async (cwd: string) => { project = project.replace( /export NODE_BINARY=node\\n\.\.\/node_modules\/react-native\/packager\/react-native-xcode\.sh/g, - '../node_modules/haul/bin/xcode.sh', + '../node_modules/haul/vendor/react-native-xcode.sh', ); fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); diff --git a/vendor/react-native-xcode.sh b/vendor/react-native-xcode.sh new file mode 100644 index 00000000..100184bd --- /dev/null +++ b/vendor/react-native-xcode.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +#### +# Taken from https://github.com/callstack-io/haul/pull/90 +#### + +case "$CONFIGURATION" in + Debug) + # Speed up build times by skipping the creation of the offline package for debug + # builds on the simulator since the packager is supposed to be running anyways. + # if [[ "$PLATFORM_NAME" == *simulator ]]; then + # echo "Skipping bundling for Simulator platform" + # exit 0; + # fi + + DEV=true + ;; + "") + echo "$0 must be invoked by Xcode" + exit 1 + ;; + *) + DEV=false + ;; +esac + +# Path to react-native folder inside node_modules +REACT_NATIVE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +# Xcode project file for React Native apps is located in ios/ subfolder +cd "${REACT_NATIVE_DIR}"/../.. + +# Define NVM_DIR and source the nvm.sh setup script +[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm" + +# Define entry file +ENTRY_FILE=${1:-index.ios.js} + +if [[ -s "$HOME/.nvm/nvm.sh" ]]; then + . "$HOME/.nvm/nvm.sh" +elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then + . "$(brew --prefix nvm)/nvm.sh" +fi + +# Set up the nodenv node version manager if present +if [[ -x "$HOME/.nodenv/bin/nodenv" ]]; then + eval "$("$HOME/.nodenv/bin/nodenv" init -)" +fi + +[ -z "$NODE_BINARY" ] && export NODE_BINARY="node" + +[ -z "$CLI_PATH" ] && export CLI_PATH="$REACT_NATIVE_DIR/local-cli/cli.js" + +nodejs_not_found() +{ + echo "error: Can't find '$NODE_BINARY' binary to build React Native bundle" >&2 + echo "If you have non-standard nodejs installation, select your project in Xcode," >&2 + echo "find 'Build Phases' - 'Bundle React Native code and images'" >&2 + echo "and change NODE_BINARY to absolute path to your node executable" >&2 + echo "(you can find it by invoking 'which node' in the terminal)" >&2 + exit 2 +} + +type $NODE_BINARY >/dev/null 2>&1 || nodejs_not_found + +# Print commands before executing them (useful for troubleshooting) +set -x +DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH + +if [[ "$CONFIGURATION" = "Debug" && ! "$PLATFORM_NAME" == *simulator ]]; then + PLISTBUDDY='/usr/libexec/PlistBuddy' + PLIST=$TARGET_BUILD_DIR/$INFOPLIST_PATH + IP=$(ipconfig getifaddr en0) + if [ -z "$IP" ]; then + IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}') + fi + $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:localhost:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" + $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:$IP.xip.io:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" + echo "$IP.xip.io" > "$DEST/ip.txt" +fi + +BUNDLE_FILE="$DEST/main.jsbundle" + +$NODE_BINARY $CLI_PATH bundle \ + --entry-file "$ENTRY_FILE" \ + --platform ios \ + --dev $DEV \ + --reset-cache \ + --bundle-output "$BUNDLE_FILE" \ + --assets-dest "$DEST" + +if [[ ! $DEV && ! -f "$BUNDLE_FILE" ]]; then + echo "error: File $BUNDLE_FILE does not exist. This must be a bug with" >&2 + echo "React Native, please report it here: https://github.com/facebook/react-native/issues" + exit 2 +fi From 20e047e7a3813eb9966acce297f95cda5c71ac49 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 11:10:15 +0200 Subject: [PATCH 06/25] Uncomment terminal --- vendor/react-native-xcode.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vendor/react-native-xcode.sh b/vendor/react-native-xcode.sh index 100184bd..58bec7c5 100644 --- a/vendor/react-native-xcode.sh +++ b/vendor/react-native-xcode.sh @@ -8,10 +8,10 @@ case "$CONFIGURATION" in Debug) # Speed up build times by skipping the creation of the offline package for debug # builds on the simulator since the packager is supposed to be running anyways. - # if [[ "$PLATFORM_NAME" == *simulator ]]; then - # echo "Skipping bundling for Simulator platform" - # exit 0; - # fi + if [[ "$PLATFORM_NAME" == *simulator ]]; then + echo "Skipping bundling for Simulator platform" + exit 0; + fi DEV=true ;; From 8db7f08ed8e50968b91eeec41d14e2aeb59ef133 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 11:11:47 +0200 Subject: [PATCH 07/25] Dont replace exports --- src/commands/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/init.js b/src/commands/init.js index 75295fe8..b4627920 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -189,7 +189,7 @@ const addToXcodeBuild = async (cwd: string) => { let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); project = project.replace( - /export NODE_BINARY=node\\n\.\.\/node_modules\/react-native\/packager\/react-native-xcode\.sh/g, + /\.\.\/node_modules\/react-native\/packager\/react-native-xcode\.sh/g, '../node_modules/haul/vendor/react-native-xcode.sh', ); From 93653f4abe7b1f2eb33d6b73495856b2817d5f38 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 11:52:24 +0200 Subject: [PATCH 08/25] Add env automatically --- src/commands/init.js | 10 ++-- vendor/react-native-xcode.sh | 96 ------------------------------------ 2 files changed, 6 insertions(+), 100 deletions(-) delete mode 100644 vendor/react-native-xcode.sh diff --git a/src/commands/init.js b/src/commands/init.js index b4627920..99febce8 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -146,8 +146,7 @@ const sleep = (time: number = 1000) => new Promise(resolve => setTimeout(resolve, time)); /** - * Adds Haul to native iOS build pipeline by: - * 1) replacing all calls to `react-native-xcode.sh` with Haul own run script + * Adds Haul to native iOS build pipeline */ const addToXcodeBuild = async (cwd: string) => { let entry; @@ -188,11 +187,14 @@ const addToXcodeBuild = async (cwd: string) => { let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); + // Vendor `react-native-xcode.sh` for backwards compatibility project = project.replace( - /\.\.\/node_modules\/react-native\/packager\/react-native-xcode\.sh/g, - '../node_modules/haul/vendor/react-native-xcode.sh', + /buildSettings = {/g, + 'buildSettings = {\n CLI_PATH = ./node_modules/haul/bin/cli.js;', ); + // Set environmental variables + fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); progress.succeed(messages.addedToBuildPipeline()); diff --git a/vendor/react-native-xcode.sh b/vendor/react-native-xcode.sh deleted file mode 100644 index 58bec7c5..00000000 --- a/vendor/react-native-xcode.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/bash - -#### -# Taken from https://github.com/callstack-io/haul/pull/90 -#### - -case "$CONFIGURATION" in - Debug) - # Speed up build times by skipping the creation of the offline package for debug - # builds on the simulator since the packager is supposed to be running anyways. - if [[ "$PLATFORM_NAME" == *simulator ]]; then - echo "Skipping bundling for Simulator platform" - exit 0; - fi - - DEV=true - ;; - "") - echo "$0 must be invoked by Xcode" - exit 1 - ;; - *) - DEV=false - ;; -esac - -# Path to react-native folder inside node_modules -REACT_NATIVE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -# Xcode project file for React Native apps is located in ios/ subfolder -cd "${REACT_NATIVE_DIR}"/../.. - -# Define NVM_DIR and source the nvm.sh setup script -[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm" - -# Define entry file -ENTRY_FILE=${1:-index.ios.js} - -if [[ -s "$HOME/.nvm/nvm.sh" ]]; then - . "$HOME/.nvm/nvm.sh" -elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then - . "$(brew --prefix nvm)/nvm.sh" -fi - -# Set up the nodenv node version manager if present -if [[ -x "$HOME/.nodenv/bin/nodenv" ]]; then - eval "$("$HOME/.nodenv/bin/nodenv" init -)" -fi - -[ -z "$NODE_BINARY" ] && export NODE_BINARY="node" - -[ -z "$CLI_PATH" ] && export CLI_PATH="$REACT_NATIVE_DIR/local-cli/cli.js" - -nodejs_not_found() -{ - echo "error: Can't find '$NODE_BINARY' binary to build React Native bundle" >&2 - echo "If you have non-standard nodejs installation, select your project in Xcode," >&2 - echo "find 'Build Phases' - 'Bundle React Native code and images'" >&2 - echo "and change NODE_BINARY to absolute path to your node executable" >&2 - echo "(you can find it by invoking 'which node' in the terminal)" >&2 - exit 2 -} - -type $NODE_BINARY >/dev/null 2>&1 || nodejs_not_found - -# Print commands before executing them (useful for troubleshooting) -set -x -DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH - -if [[ "$CONFIGURATION" = "Debug" && ! "$PLATFORM_NAME" == *simulator ]]; then - PLISTBUDDY='/usr/libexec/PlistBuddy' - PLIST=$TARGET_BUILD_DIR/$INFOPLIST_PATH - IP=$(ipconfig getifaddr en0) - if [ -z "$IP" ]; then - IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}') - fi - $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:localhost:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" - $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:$IP.xip.io:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" - echo "$IP.xip.io" > "$DEST/ip.txt" -fi - -BUNDLE_FILE="$DEST/main.jsbundle" - -$NODE_BINARY $CLI_PATH bundle \ - --entry-file "$ENTRY_FILE" \ - --platform ios \ - --dev $DEV \ - --reset-cache \ - --bundle-output "$BUNDLE_FILE" \ - --assets-dest "$DEST" - -if [[ ! $DEV && ! -f "$BUNDLE_FILE" ]]; then - echo "error: File $BUNDLE_FILE does not exist. This must be a bug with" >&2 - echo "React Native, please report it here: https://github.com/facebook/react-native/issues" - exit 2 -fi From 77b436716d4bec52c1fdcf153654cbd375931b0a Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 12:11:14 +0200 Subject: [PATCH 09/25] Update init.js --- src/commands/init.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/commands/init.js b/src/commands/init.js index 99febce8..3d0c7c23 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -187,7 +187,6 @@ const addToXcodeBuild = async (cwd: string) => { let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); - // Vendor `react-native-xcode.sh` for backwards compatibility project = project.replace( /buildSettings = {/g, 'buildSettings = {\n CLI_PATH = ./node_modules/haul/bin/cli.js;', From 987b65d68b6425ab2a1fd57f1ce9ac8235233a13 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 14:08:51 +0200 Subject: [PATCH 10/25] Add vendored files --- vendor/packager/haul-integrate.sh | 20 ++++++ vendor/packager/packager.sh | 12 ++++ vendor/packager/react-native-xcode.sh | 100 ++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100755 vendor/packager/haul-integrate.sh create mode 100644 vendor/packager/packager.sh create mode 100644 vendor/packager/react-native-xcode.sh diff --git a/vendor/packager/haul-integrate.sh b/vendor/packager/haul-integrate.sh new file mode 100755 index 00000000..584070f6 --- /dev/null +++ b/vendor/packager/haul-integrate.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# React Native adds few scripts into Xcode build phase. Some of them +# are defined internally inside React.xcodeproj which makes it impossible +# to receive environmental variables set. +# +# To customise those scripts and make them run `Haul` instead of `packager`, +# we copy our custom versions every time user hits run. + +THIS_DIR=$(dirname $0) + +PACKAGER_DIR="$(cd "${THIS_DIR}/../../../react-native/packager" && pwd)" + +# Copy files +cp -f ${THIS_DIR}/packager.sh ${PACKAGER_DIR}/packager.sh +cp -f ${THIS_DIR}/react-native-xcode.sh ${PACKAGER_DIR}/react-native-xcode.sh + +# Set executable permissions +chmod 755 ${PACKAGER_DIR}/packager.sh +chmod 755 ${PACKAGER_DIR}/react-native-xcode.sh \ No newline at end of file diff --git a/vendor/packager/packager.sh b/vendor/packager/packager.sh new file mode 100644 index 00000000..5bd5e141 --- /dev/null +++ b/vendor/packager/packager.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# +# This script is invoked by `launchPackager.command` and will +# start Haul automatically when you run project from Xcode +# +# This file lives under: node_modules/react-native/packager/packager.sh + +# Go to root of the project +cd ../../../ + +# Execute Haul +node "./node_modules/.bin/haul" start --platform ios "$@" \ No newline at end of file diff --git a/vendor/packager/react-native-xcode.sh b/vendor/packager/react-native-xcode.sh new file mode 100644 index 00000000..5d9d9133 --- /dev/null +++ b/vendor/packager/react-native-xcode.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# Copyright (c) 2015-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +# Bundle React Native app's code and image assets. +# This script is supposed to be invoked as part of Xcode build process +# and relies on environment variables (including PWD) set by Xcode + +case "$CONFIGURATION" in + Debug) + # Speed up build times by skipping the creation of the offline package for debug + # builds on the simulator since the packager is supposed to be running anyways. + if [[ "$PLATFORM_NAME" == *simulator ]]; then + echo "Skipping bundling for Simulator platform" + exit 0; + fi + + DEV=true + ;; + "") + echo "$0 must be invoked by Xcode" + exit 1 + ;; + *) + DEV=false + ;; +esac + +# Path to react-native folder inside node_modules +REACT_NATIVE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +# Xcode project file for React Native apps is located in ios/ subfolder +cd "${REACT_NATIVE_DIR}"/../.. + +# Define NVM_DIR and source the nvm.sh setup script +[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm" + +# Define entry file +ENTRY_FILE=${1:-index.ios.js} + +if [[ -s "$HOME/.nvm/nvm.sh" ]]; then + . "$HOME/.nvm/nvm.sh" +elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then + . "$(brew --prefix nvm)/nvm.sh" +fi + +# Set up the nodenv node version manager if present +if [[ -x "$HOME/.nodenv/bin/nodenv" ]]; then + eval "$("$HOME/.nodenv/bin/nodenv" init -)" +fi + +[ -z "$NODE_BINARY" ] && export NODE_BINARY="node" + +nodejs_not_found() +{ + echo "error: Can't find '$NODE_BINARY' binary to build React Native bundle" >&2 + echo "If you have non-standard nodejs installation, select your project in Xcode," >&2 + echo "find 'Build Phases' - 'Bundle React Native code and images'" >&2 + echo "and change NODE_BINARY to absolute path to your node executable" >&2 + echo "(you can find it by invoking 'which node' in the terminal)" >&2 + exit 2 +} + +type $NODE_BINARY >/dev/null 2>&1 || nodejs_not_found + +# Print commands before executing them (useful for troubleshooting) +set -x +DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH + +if [[ "$CONFIGURATION" = "Debug" && ! "$PLATFORM_NAME" == *simulator ]]; then + PLISTBUDDY='/usr/libexec/PlistBuddy' + PLIST=$TARGET_BUILD_DIR/$INFOPLIST_PATH + IP=$(ipconfig getifaddr en0) + if [ -z "$IP" ]; then + IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}') + fi + $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:localhost:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" + $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:$IP.xip.io:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" + echo "$IP.xip.io" > "$DEST/ip.txt" +fi + +BUNDLE_FILE="$DEST/main.jsbundle" + +$NODE_BINARY "./node_modules/.bin/haul" bundle \ + --entry-file "$ENTRY_FILE" \ + --platform ios \ + --dev $DEV \ + --reset-cache \ + --bundle-output "$BUNDLE_FILE" \ + --assets-dest "$DEST" + +if [[ ! $DEV && ! -f "$BUNDLE_FILE" ]]; then + echo "error: File $BUNDLE_FILE does not exist. This must be a bug with" >&2 + echo "React Native, please report it here: https://github.com/facebook/react-native/issues" + exit 2 +fi \ No newline at end of file From c3cbfd4fcfada2565fce1d73738789b300e6e1f9 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 14:53:22 +0200 Subject: [PATCH 11/25] Working solution --- src/commands/init.js | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 3d0c7c23..297e576c 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -187,12 +187,39 @@ const addToXcodeBuild = async (cwd: string) => { let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); + // 1. Define buildPhase project = project.replace( - /buildSettings = {/g, - 'buildSettings = {\n CLI_PATH = ./node_modules/haul/bin/cli.js;', + '/* Begin PBXShellScriptBuildPhase section */', + dedent` + /* Begin PBXShellScriptBuildPhase section */ + AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "bash ../node_modules/haul/vendor/packager/haul-integrate.sh"; + };`, ); - // Set environmental variables + // 2. Add build phase to React Native targets + project = project.replace(/buildPhases = \(\n(?:.*,\n)*\s*\);/g, match => { + if (!match.includes('React Native')) { + return match; + } + return match.replace( + 'buildPhases = (', + dedent` + buildPhases = ( + AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */, + `, + ); + }); fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); From 3ed308087719ddcd0924d6d247bb1d09e9c69d3e Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 14:53:50 +0200 Subject: [PATCH 12/25] Change indent --- src/commands/init.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 297e576c..a90a8472 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -215,9 +215,9 @@ const addToXcodeBuild = async (cwd: string) => { return match.replace( 'buildPhases = (', dedent` - buildPhases = ( - AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */, - `, + buildPhases = ( + AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */, + `, ); }); From 7131935d45fce14f9b4bc962659dc54dd1e92c1f Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:00:48 +0200 Subject: [PATCH 13/25] Detect if already added --- src/commands/init.js | 14 +++++++++----- src/messages/addedToBuildPipeline.js | 2 +- src/messages/addingToBuildPipeline.js | 2 +- src/messages/alreadyAddedToBuildPipeline.js | 8 ++++++++ src/messages/index.js | 1 + 5 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 src/messages/alreadyAddedToBuildPipeline.js diff --git a/src/commands/init.js b/src/commands/init.js index a90a8472..d4997a88 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -187,7 +187,13 @@ const addToXcodeBuild = async (cwd: string) => { let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); - // 1. Define buildPhase + // If xcode-project already contains our uuid + if (project.includes('AD0CE2C91E925489006FC317')) { + progress.info(messages.alreadyAddedToBuildPipeline()); + return; + } + + // Define Haul build phase project = project.replace( '/* Begin PBXShellScriptBuildPhase section */', dedent` @@ -207,11 +213,9 @@ const addToXcodeBuild = async (cwd: string) => { };`, ); - // 2. Add build phase to React Native targets + // Add run script to phases that already contain `react-native-xcode.sh` project = project.replace(/buildPhases = \(\n(?:.*,\n)*\s*\);/g, match => { - if (!match.includes('React Native')) { - return match; - } + if (!match.includes('React Native')) return match; return match.replace( 'buildPhases = (', dedent` diff --git a/src/messages/addedToBuildPipeline.js b/src/messages/addedToBuildPipeline.js index 37d0e36d..bdaabede 100644 --- a/src/messages/addedToBuildPipeline.js +++ b/src/messages/addedToBuildPipeline.js @@ -5,4 +5,4 @@ * @flow */ -module.exports = () => `Adding haul to your native build pipeline`; +module.exports = () => `Added haul to your native build pipeline`; diff --git a/src/messages/addingToBuildPipeline.js b/src/messages/addingToBuildPipeline.js index bdaabede..37d0e36d 100644 --- a/src/messages/addingToBuildPipeline.js +++ b/src/messages/addingToBuildPipeline.js @@ -5,4 +5,4 @@ * @flow */ -module.exports = () => `Added haul to your native build pipeline`; +module.exports = () => `Adding haul to your native build pipeline`; diff --git a/src/messages/alreadyAddedToBuildPipeline.js b/src/messages/alreadyAddedToBuildPipeline.js new file mode 100644 index 00000000..37cb1cdc --- /dev/null +++ b/src/messages/alreadyAddedToBuildPipeline.js @@ -0,0 +1,8 @@ +/** + * Copyright 2017-present, Callstack. + * All rights reserved. + * + * @flow + */ + +module.exports = () => `Haul is already part of your build pipeline`; diff --git a/src/messages/index.js b/src/messages/index.js index 6d3ec1ad..3718130e 100644 --- a/src/messages/index.js +++ b/src/messages/index.js @@ -7,6 +7,7 @@ module.exports = { addingToBuildPipeline: require('./addingToBuildPipeline'), + alreadyAddedToBuildPipeline: require('./alreadyAddedToBuildPipeline'), addedToBuildPipeline: require('./addedToBuildPipeline'), webpackConfigNotFound: require('./webpackConfigNotFound'), initialStartInformation: require('./initialStartInformation'), From d7514b85491d24464758dfd92c74fa116d4eaac9 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:08:20 +0200 Subject: [PATCH 14/25] Improve comments --- src/commands/init.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index d4997a88..4c356942 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -187,13 +187,18 @@ const addToXcodeBuild = async (cwd: string) => { let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); - // If xcode-project already contains our uuid + // Are we already integrated? if (project.includes('AD0CE2C91E925489006FC317')) { progress.info(messages.alreadyAddedToBuildPipeline()); return; } - // Define Haul build phase + /** + * Define Haul integration script in the PBXShellScriptBuildPhase section. + * + * This is done by prepending our predefined script phase to the list + * of all phases. + */ project = project.replace( '/* Begin PBXShellScriptBuildPhase section */', dedent` @@ -201,6 +206,7 @@ const addToXcodeBuild = async (cwd: string) => { AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; + name = "Integrate Haul with React Native"; files = ( ); inputPaths = ( @@ -213,7 +219,22 @@ const addToXcodeBuild = async (cwd: string) => { };`, ); - // Add run script to phases that already contain `react-native-xcode.sh` + /** + * Add Haul integration to build phases that already contain `react-native-xcode.sh` + * + * We are typically trying to match the following: + * + * ``` + * buildPhases = ( + * 13B07F871A680F5B00A75B9A \/* Sources *\/, + * 13B07F8C1A680F5B00A75B9A \/* Frameworks *\/, + * 13B07F8E1A680F5B00A75B9A \/* Resources *\/, + * 00DD1BFF1BD5951E006B06BC \/* Bundle React Native code and images *\/, + * ); + * ``` + * + * and prepend our build phase to the beginning. + */ project = project.replace(/buildPhases = \(\n(?:.*,\n)*\s*\);/g, match => { if (!match.includes('React Native')) return match; return match.replace( From e69ed9c71c8326f35594f8d56cb2ea3ff69ed683 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:18:07 +0200 Subject: [PATCH 15/25] Error if we fail to detect React native script --- src/commands/init.js | 11 ++++++++--- src/messages/failedToAddToBuildPipeline.js | 9 +++++++++ src/messages/index.js | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 src/messages/failedToAddToBuildPipeline.js diff --git a/src/commands/init.js b/src/commands/init.js index 4c356942..f24ce0ea 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -235,8 +235,10 @@ const addToXcodeBuild = async (cwd: string) => { * * and prepend our build phase to the beginning. */ + let sectionsCount = 0; project = project.replace(/buildPhases = \(\n(?:.*,\n)*\s*\);/g, match => { if (!match.includes('React Native')) return match; + sectionsCount++; return match.replace( 'buildPhases = (', dedent` @@ -246,9 +248,12 @@ const addToXcodeBuild = async (cwd: string) => { ); }); - fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); - - progress.succeed(messages.addedToBuildPipeline()); + if (sectionsCount > 0) { + fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); + progress.succeed(messages.addedToBuildPipeline()); + } else { + progress.fail(messages.failedToAddToBuildPipeline()); + } }; module.exports = { diff --git a/src/messages/failedToAddToBuildPipeline.js b/src/messages/failedToAddToBuildPipeline.js new file mode 100644 index 00000000..78726d43 --- /dev/null +++ b/src/messages/failedToAddToBuildPipeline.js @@ -0,0 +1,9 @@ +/** + * Copyright 2017-present, Callstack. + * All rights reserved. + * + * @flow + */ + +module.exports = () => + `Failed to add Haul to your build pipeline. See docs for manual instructions.`; diff --git a/src/messages/index.js b/src/messages/index.js index 3718130e..5df18ddf 100644 --- a/src/messages/index.js +++ b/src/messages/index.js @@ -9,6 +9,7 @@ module.exports = { addingToBuildPipeline: require('./addingToBuildPipeline'), alreadyAddedToBuildPipeline: require('./alreadyAddedToBuildPipeline'), addedToBuildPipeline: require('./addedToBuildPipeline'), + failedToAddToBuildPipeline: require('./failedToAddToBuildPipeline'), webpackConfigNotFound: require('./webpackConfigNotFound'), initialStartInformation: require('./initialStartInformation'), initialBundleInformation: require('./initialBundleInformation'), From b4e411e696a14c1e84d4f89913577035a01f0cf2 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:19:28 +0200 Subject: [PATCH 16/25] Fix indent --- src/commands/init.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index f24ce0ea..45ab9f01 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -220,21 +220,21 @@ const addToXcodeBuild = async (cwd: string) => { ); /** - * Add Haul integration to build phases that already contain `react-native-xcode.sh` - * - * We are typically trying to match the following: - * - * ``` - * buildPhases = ( - * 13B07F871A680F5B00A75B9A \/* Sources *\/, - * 13B07F8C1A680F5B00A75B9A \/* Frameworks *\/, - * 13B07F8E1A680F5B00A75B9A \/* Resources *\/, - * 00DD1BFF1BD5951E006B06BC \/* Bundle React Native code and images *\/, - * ); - * ``` - * - * and prepend our build phase to the beginning. - */ + * Add Haul integration to build phases that already contain `react-native-xcode.sh` + * + * We are typically trying to match the following: + * + * ``` + * buildPhases = ( + * 13B07F871A680F5B00A75B9A \/* Sources *\/, + * 13B07F8C1A680F5B00A75B9A \/* Frameworks *\/, + * 13B07F8E1A680F5B00A75B9A \/* Resources *\/, + * 00DD1BFF1BD5951E006B06BC \/* Bundle React Native code and images *\/, + * ); + * ``` + * + * and prepend our build phase to the beginning. + */ let sectionsCount = 0; project = project.replace(/buildPhases = \(\n(?:.*,\n)*\s*\);/g, match => { if (!match.includes('React Native')) return match; From a16847430560e17b37281d482b0858f56f1867d1 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:38:38 +0200 Subject: [PATCH 17/25] Replace in-place --- vendor/packager/haul-integrate.sh | 16 ++--- vendor/packager/react-native-xcode.sh | 100 -------------------------- 2 files changed, 6 insertions(+), 110 deletions(-) delete mode 100644 vendor/packager/react-native-xcode.sh diff --git a/vendor/packager/haul-integrate.sh b/vendor/packager/haul-integrate.sh index 584070f6..290364c6 100755 --- a/vendor/packager/haul-integrate.sh +++ b/vendor/packager/haul-integrate.sh @@ -3,18 +3,14 @@ # React Native adds few scripts into Xcode build phase. Some of them # are defined internally inside React.xcodeproj which makes it impossible # to receive environmental variables set. -# -# To customise those scripts and make them run `Haul` instead of `packager`, -# we copy our custom versions every time user hits run. THIS_DIR=$(dirname $0) -PACKAGER_DIR="$(cd "${THIS_DIR}/../../../react-native/packager" && pwd)" +SRC="$(cd "${THIS_DIR}/../../../react-native/packager" && pwd)" -# Copy files -cp -f ${THIS_DIR}/packager.sh ${PACKAGER_DIR}/packager.sh -cp -f ${THIS_DIR}/react-native-xcode.sh ${PACKAGER_DIR}/react-native-xcode.sh +# Replace local-cli with Haul in `react-native-xcode.sh` +sed -i -e 's/$REACT_NATIVE_DIR\/local-cli\/cli.js/.\/node_modules\/.bin\/haul' ${SRC}/react-native-xcode.sh -# Set executable permissions -chmod 755 ${PACKAGER_DIR}/packager.sh -chmod 755 ${PACKAGER_DIR}/react-native-xcode.sh \ No newline at end of file +# Copy files +cp -f ${THIS_DIR}/packager.sh ${SRC}/packager.sh +chmod 755 ${SRC}/packager.sh \ No newline at end of file diff --git a/vendor/packager/react-native-xcode.sh b/vendor/packager/react-native-xcode.sh deleted file mode 100644 index 5d9d9133..00000000 --- a/vendor/packager/react-native-xcode.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# Copyright (c) 2015-present, Facebook, Inc. -# All rights reserved. -# -# This source code is licensed under the BSD-style license found in the -# LICENSE file in the root directory of this source tree. An additional grant -# of patent rights can be found in the PATENTS file in the same directory. - -# Bundle React Native app's code and image assets. -# This script is supposed to be invoked as part of Xcode build process -# and relies on environment variables (including PWD) set by Xcode - -case "$CONFIGURATION" in - Debug) - # Speed up build times by skipping the creation of the offline package for debug - # builds on the simulator since the packager is supposed to be running anyways. - if [[ "$PLATFORM_NAME" == *simulator ]]; then - echo "Skipping bundling for Simulator platform" - exit 0; - fi - - DEV=true - ;; - "") - echo "$0 must be invoked by Xcode" - exit 1 - ;; - *) - DEV=false - ;; -esac - -# Path to react-native folder inside node_modules -REACT_NATIVE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -# Xcode project file for React Native apps is located in ios/ subfolder -cd "${REACT_NATIVE_DIR}"/../.. - -# Define NVM_DIR and source the nvm.sh setup script -[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm" - -# Define entry file -ENTRY_FILE=${1:-index.ios.js} - -if [[ -s "$HOME/.nvm/nvm.sh" ]]; then - . "$HOME/.nvm/nvm.sh" -elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then - . "$(brew --prefix nvm)/nvm.sh" -fi - -# Set up the nodenv node version manager if present -if [[ -x "$HOME/.nodenv/bin/nodenv" ]]; then - eval "$("$HOME/.nodenv/bin/nodenv" init -)" -fi - -[ -z "$NODE_BINARY" ] && export NODE_BINARY="node" - -nodejs_not_found() -{ - echo "error: Can't find '$NODE_BINARY' binary to build React Native bundle" >&2 - echo "If you have non-standard nodejs installation, select your project in Xcode," >&2 - echo "find 'Build Phases' - 'Bundle React Native code and images'" >&2 - echo "and change NODE_BINARY to absolute path to your node executable" >&2 - echo "(you can find it by invoking 'which node' in the terminal)" >&2 - exit 2 -} - -type $NODE_BINARY >/dev/null 2>&1 || nodejs_not_found - -# Print commands before executing them (useful for troubleshooting) -set -x -DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH - -if [[ "$CONFIGURATION" = "Debug" && ! "$PLATFORM_NAME" == *simulator ]]; then - PLISTBUDDY='/usr/libexec/PlistBuddy' - PLIST=$TARGET_BUILD_DIR/$INFOPLIST_PATH - IP=$(ipconfig getifaddr en0) - if [ -z "$IP" ]; then - IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}') - fi - $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:localhost:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" - $PLISTBUDDY -c "Add NSAppTransportSecurity:NSExceptionDomains:$IP.xip.io:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" "$PLIST" - echo "$IP.xip.io" > "$DEST/ip.txt" -fi - -BUNDLE_FILE="$DEST/main.jsbundle" - -$NODE_BINARY "./node_modules/.bin/haul" bundle \ - --entry-file "$ENTRY_FILE" \ - --platform ios \ - --dev $DEV \ - --reset-cache \ - --bundle-output "$BUNDLE_FILE" \ - --assets-dest "$DEST" - -if [[ ! $DEV && ! -f "$BUNDLE_FILE" ]]; then - echo "error: File $BUNDLE_FILE does not exist. This must be a bug with" >&2 - echo "React Native, please report it here: https://github.com/facebook/react-native/issues" - exit 2 -fi \ No newline at end of file From 3d4b77c8c6a63366fcfc3e3fcae07e1003a1ee32 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:53:27 +0200 Subject: [PATCH 18/25] Use one file instead of vendoring --- src/commands/init.js | 2 +- {vendor/packager => src/utils}/haul-integrate.sh | 8 ++++---- vendor/packager/packager.sh | 12 ------------ 3 files changed, 5 insertions(+), 17 deletions(-) rename {vendor/packager => src/utils}/haul-integrate.sh (54%) delete mode 100644 vendor/packager/packager.sh diff --git a/src/commands/init.js b/src/commands/init.js index 45ab9f01..37f8e9a2 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -215,7 +215,7 @@ const addToXcodeBuild = async (cwd: string) => { ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "bash ../node_modules/haul/vendor/packager/haul-integrate.sh"; + shellScript = "bash ../node_modules/haul/src/utils/haul-integrate.sh"; };`, ); diff --git a/vendor/packager/haul-integrate.sh b/src/utils/haul-integrate.sh similarity index 54% rename from vendor/packager/haul-integrate.sh rename to src/utils/haul-integrate.sh index 290364c6..e328f1cc 100755 --- a/vendor/packager/haul-integrate.sh +++ b/src/utils/haul-integrate.sh @@ -9,8 +9,8 @@ THIS_DIR=$(dirname $0) SRC="$(cd "${THIS_DIR}/../../../react-native/packager" && pwd)" # Replace local-cli with Haul in `react-native-xcode.sh` -sed -i -e 's/$REACT_NATIVE_DIR\/local-cli\/cli.js/.\/node_modules\/.bin\/haul' ${SRC}/react-native-xcode.sh +sed -i -e 's|$REACT_NATIVE_DIR/local-cli/cli.js|./node_modules/.bin/haul|' ${SRC}/react-native-xcode.sh -# Copy files -cp -f ${THIS_DIR}/packager.sh ${SRC}/packager.sh -chmod 755 ${SRC}/packager.sh \ No newline at end of file +# Replace `react-native start` in `packager.sh` +PACKAGER_CONTENT="cd ../../../ && node \"./node_modules/.bin/haul\" start --platform ios \"\$@\"" +echo "$PACKAGER_CONTENT" > ${SRC}/packager.sh \ No newline at end of file diff --git a/vendor/packager/packager.sh b/vendor/packager/packager.sh deleted file mode 100644 index 5bd5e141..00000000 --- a/vendor/packager/packager.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# -# This script is invoked by `launchPackager.command` and will -# start Haul automatically when you run project from Xcode -# -# This file lives under: node_modules/react-native/packager/packager.sh - -# Go to root of the project -cd ../../../ - -# Execute Haul -node "./node_modules/.bin/haul" start --platform ios "$@" \ No newline at end of file From bfa3e4de04c08840407f93749a2017431b623bad Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 15:55:35 +0200 Subject: [PATCH 19/25] Remove comment --- src/utils/haul-integrate.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/utils/haul-integrate.sh b/src/utils/haul-integrate.sh index e328f1cc..bb7c83ae 100755 --- a/src/utils/haul-integrate.sh +++ b/src/utils/haul-integrate.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -# -# React Native adds few scripts into Xcode build phase. Some of them -# are defined internally inside React.xcodeproj which makes it impossible -# to receive environmental variables set. THIS_DIR=$(dirname $0) From 62044a181a34ff101e7ef928dc23951297aae60c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 16:08:32 +0200 Subject: [PATCH 20/25] Define messages in-place --- src/commands/init.js | 12 +++++++----- src/messages/addedToBuildPipeline.js | 8 -------- src/messages/addingToBuildPipeline.js | 8 -------- src/messages/alreadyAddedToBuildPipeline.js | 8 -------- src/messages/enterXcodeProjectFileName.js | 8 -------- src/messages/failedToAddToBuildPipeline.js | 9 --------- src/messages/index.js | 6 ------ src/messages/xcodeProjectNotFound.js | 9 --------- 8 files changed, 7 insertions(+), 61 deletions(-) delete mode 100644 src/messages/addedToBuildPipeline.js delete mode 100644 src/messages/addingToBuildPipeline.js delete mode 100644 src/messages/alreadyAddedToBuildPipeline.js delete mode 100644 src/messages/enterXcodeProjectFileName.js delete mode 100644 src/messages/failedToAddToBuildPipeline.js delete mode 100644 src/messages/xcodeProjectNotFound.js diff --git a/src/commands/init.js b/src/commands/init.js index 37f8e9a2..70f872d6 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -170,7 +170,7 @@ const addToXcodeBuild = async (cwd: string) => { { type: 'input', name: 'entry', - message: messages.enterXcodeProjectFileName(), + message: 'Enter the name of the .xcodeproj file', validate: pathToFile => fs.existsSync(pathToFile) && pathToFile.includes('.xcodeproj') ? true @@ -181,7 +181,7 @@ const addToXcodeBuild = async (cwd: string) => { entry = path.join(cwd, result.entry); } - const progress = ora(messages.addingToBuildPipeline()); + const progress = ora('Adding haul to your native build pipeline'); await sleep(); @@ -189,7 +189,7 @@ const addToXcodeBuild = async (cwd: string) => { // Are we already integrated? if (project.includes('AD0CE2C91E925489006FC317')) { - progress.info(messages.alreadyAddedToBuildPipeline()); + progress.info('Haul is already part of your build pipeline'); return; } @@ -250,9 +250,11 @@ const addToXcodeBuild = async (cwd: string) => { if (sectionsCount > 0) { fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); - progress.succeed(messages.addedToBuildPipeline()); + progress.succeed('Added haul to your native build pipeline'); } else { - progress.fail(messages.failedToAddToBuildPipeline()); + progress.fail( + 'Failed to add Haul to your build pipeline. See docs for manual instructions.', + ); } }; diff --git a/src/messages/addedToBuildPipeline.js b/src/messages/addedToBuildPipeline.js deleted file mode 100644 index bdaabede..00000000 --- a/src/messages/addedToBuildPipeline.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright 2017-present, Callstack. - * All rights reserved. - * - * @flow - */ - -module.exports = () => `Added haul to your native build pipeline`; diff --git a/src/messages/addingToBuildPipeline.js b/src/messages/addingToBuildPipeline.js deleted file mode 100644 index 37d0e36d..00000000 --- a/src/messages/addingToBuildPipeline.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright 2017-present, Callstack. - * All rights reserved. - * - * @flow - */ - -module.exports = () => `Adding haul to your native build pipeline`; diff --git a/src/messages/alreadyAddedToBuildPipeline.js b/src/messages/alreadyAddedToBuildPipeline.js deleted file mode 100644 index 37cb1cdc..00000000 --- a/src/messages/alreadyAddedToBuildPipeline.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright 2017-present, Callstack. - * All rights reserved. - * - * @flow - */ - -module.exports = () => `Haul is already part of your build pipeline`; diff --git a/src/messages/enterXcodeProjectFileName.js b/src/messages/enterXcodeProjectFileName.js deleted file mode 100644 index 734c8143..00000000 --- a/src/messages/enterXcodeProjectFileName.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright 2017-present, Callstack. - * All rights reserved. - * - * @flow - */ - -module.exports = () => `Enter the name of the .xcodeproj file`; diff --git a/src/messages/failedToAddToBuildPipeline.js b/src/messages/failedToAddToBuildPipeline.js deleted file mode 100644 index 78726d43..00000000 --- a/src/messages/failedToAddToBuildPipeline.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Copyright 2017-present, Callstack. - * All rights reserved. - * - * @flow - */ - -module.exports = () => - `Failed to add Haul to your build pipeline. See docs for manual instructions.`; diff --git a/src/messages/index.js b/src/messages/index.js index 5df18ddf..40e92c64 100644 --- a/src/messages/index.js +++ b/src/messages/index.js @@ -6,10 +6,6 @@ */ module.exports = { - addingToBuildPipeline: require('./addingToBuildPipeline'), - alreadyAddedToBuildPipeline: require('./alreadyAddedToBuildPipeline'), - addedToBuildPipeline: require('./addedToBuildPipeline'), - failedToAddToBuildPipeline: require('./failedToAddToBuildPipeline'), webpackConfigNotFound: require('./webpackConfigNotFound'), initialStartInformation: require('./initialStartInformation'), initialBundleInformation: require('./initialBundleInformation'), @@ -19,7 +15,6 @@ module.exports = { commandNotImplemented: require('./commandNotImplemented'), commandNotFound: require('./commandNotFound'), commandFailed: require('./commandFailed'), - enterXcodeProjectFileName: require('./enterXcodeProjectFileName'), invalidOption: require('./invalidOption'), haulHelp: require('./haulHelp'), haulCommandHelp: require('./haulCommandHelp'), @@ -38,5 +33,4 @@ module.exports = { gitAddedEntries: require('./gitAddedEntries'), gitAlreadyAdded: require('./gitAlreadyAdded'), gitNotFound: require('./gitNotFound'), - xcodeProjectNotFound: require('./xcodeProjectNotFound'), }; diff --git a/src/messages/xcodeProjectNotFound.js b/src/messages/xcodeProjectNotFound.js deleted file mode 100644 index 3d13c246..00000000 --- a/src/messages/xcodeProjectNotFound.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Copyright 2017-present, Callstack. - * All rights reserved. - * - * @flow - */ - -module.exports = (pathToFile: string) => - `Xcode project wasn't found at ${pathToFile}`; From 6e0c3e51abd24c4291a7117d1dbebbd86af47e13 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 16:12:13 +0200 Subject: [PATCH 21/25] Fix message --- src/commands/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/init.js b/src/commands/init.js index 70f872d6..525a0528 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -174,7 +174,7 @@ const addToXcodeBuild = async (cwd: string) => { validate: pathToFile => fs.existsSync(pathToFile) && pathToFile.includes('.xcodeproj') ? true - : messages.xcodeProjectNotFound(pathToFile), + : `${pathToFile} is not a valid .xcodeproj`, }, ]); From b6d7803f61c5fbe3b3cbdb6f9c07733bcdaa63f4 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 16:25:39 +0200 Subject: [PATCH 22/25] Use path.resolve for absolute/relative --- src/commands/init.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 525a0528..1b97f91f 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -170,7 +170,7 @@ const addToXcodeBuild = async (cwd: string) => { { type: 'input', name: 'entry', - message: 'Enter the name of the .xcodeproj file', + message: 'Enter path to the .xcodeproj file', validate: pathToFile => fs.existsSync(pathToFile) && pathToFile.includes('.xcodeproj') ? true @@ -178,7 +178,7 @@ const addToXcodeBuild = async (cwd: string) => { }, ]); - entry = path.join(cwd, result.entry); + entry = path.resolve(cwd, result.entry); } const progress = ora('Adding haul to your native build pipeline'); From 028ed1c3abcf69ce2857e27eae6e147aec192be2 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 16:37:22 +0200 Subject: [PATCH 23/25] Fix some nitpicking --- src/commands/init.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 1b97f91f..00cbbaab 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -181,15 +181,17 @@ const addToXcodeBuild = async (cwd: string) => { entry = path.resolve(cwd, result.entry); } - const progress = ora('Adding haul to your native build pipeline'); + const progress = ora('Adding haul to your Xcode build scripts'); await sleep(); let project = fs.readFileSync(path.join(entry, 'project.pbxproj')).toString(); + const haulScriptKey = 'AD0CE2C91E925489006FC317'; + // Are we already integrated? - if (project.includes('AD0CE2C91E925489006FC317')) { - progress.info('Haul is already part of your build pipeline'); + if (project.includes(haulScriptKey)) { + progress.info('Haul is already part of your build scripts'); return; } @@ -203,7 +205,7 @@ const addToXcodeBuild = async (cwd: string) => { '/* Begin PBXShellScriptBuildPhase section */', dedent` /* Begin PBXShellScriptBuildPhase section */ - AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */ = { + ${haulScriptKey} /* Integrate Haul with React Native */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; name = "Integrate Haul with React Native"; @@ -243,17 +245,17 @@ const addToXcodeBuild = async (cwd: string) => { 'buildPhases = (', dedent` buildPhases = ( - AD0CE2C91E925489006FC317 /* Integrate Haul with React Native */, + ${haulScriptKey} /* Integrate Haul with React Native */, `, ); }); if (sectionsCount > 0) { fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); - progress.succeed('Added haul to your native build pipeline'); + progress.succeed('Added haul to your Xcode build scripts'); } else { progress.fail( - 'Failed to add Haul to your build pipeline. See docs for manual instructions.', + 'Failed to add Haul to your Xcode build scripts. See docs for manual instructions.', ); } }; From 9dfff1f083a12539ae7b9fc628eca27529dfd293 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 16:43:57 +0200 Subject: [PATCH 24/25] Create Configuring Your Project.md --- docs/Configuring Your Project.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/Configuring Your Project.md diff --git a/docs/Configuring Your Project.md b/docs/Configuring Your Project.md new file mode 100644 index 00000000..9cba608b --- /dev/null +++ b/docs/Configuring Your Project.md @@ -0,0 +1,3 @@ +# Configuring your project + +## Integrating with Xcode From afd93e1b42c050b9690d81419464e5ceb819ffb2 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Mon, 3 Apr 2017 16:52:30 +0200 Subject: [PATCH 25/25] Add working link --- src/commands/init.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 00cbbaab..8f339e7b 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -9,6 +9,7 @@ const path = require('path'); const fs = require('fs'); const dedent = require('dedent'); const ora = require('ora'); +const chalk = require('chalk'); const inquirer = require('inquirer'); const messages = require('../messages'); @@ -250,12 +251,12 @@ const addToXcodeBuild = async (cwd: string) => { ); }); - if (sectionsCount > 0) { + if (sectionsCount === 0) { fs.writeFileSync(path.join(entry, 'project.pbxproj'), project); progress.succeed('Added haul to your Xcode build scripts'); } else { progress.fail( - 'Failed to add Haul to your Xcode build scripts. See docs for manual instructions.', + `Failed to add Haul to your Xcode build scripts. See: ${chalk.grey('https://github.com/callstack-io/haul/blob/master/docs/Configuring%20Your%20Project.md#integrating-with-xcode')} for manual instructions`, ); } };