Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
implement script to generate CodePushified React Native apps (microso…
Browse files Browse the repository at this point in the history
…ft#958)

* implement fully automatic script to generate CodePushified React Native apps

* fix compatibility issues, remove generate-app.sh

* update docs, improve react-native version detection
  • Loading branch information
sergey-akhalkov authored Aug 9, 2017
1 parent 416af9b commit 6f6f145
Show file tree
Hide file tree
Showing 3 changed files with 571 additions and 63 deletions.
178 changes: 178 additions & 0 deletions Examples/create-app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
The script serves to generate CodePushified React Native app to reproduce issues or for testing purposes.
Requirements:
1. npm i -g react-native-cli
2. npm i -g code-push-cli
3. code-push register
Usage: node create-app.js <appName> <reactNativeVersion> <reactNativeCodePushVersion>
1. node create-app.js
2. node create-app.js myapp
3. node create-app.js myapp [email protected] [email protected]
4. node create-app.js myapp react-native@latest Microsoft/react-native-code-push
Parameters:
1. <appName> - CodePushDemoAppTest
2. <reactNativeVersion> - react-native@latest
3. <reactNativeCodePushVersion> - react-native-code-push@latest
*/

let fs = require('fs');
let path = require('path');
let nexpect = require('./nexpect');
let child_proces = require('child_process');
let execSync = child_proces.execSync;

let args = process.argv.slice(2);
let appName = args[0] || 'CodePushDemoAppTest';

if (fs.existsSync(appName)) {
console.error(`Folder with name "${appName}" already exists! Please delete`);
process.exit();
}

let appNameAndroid = `${appName}-android`;
let appNameIOS = `${appName}-ios`;
let reactNativeVersion = args[1] || `react-native@${execSync('npm view react-native version')}`.trim();
let reactNativeCodePushVersion = args[2] || `react-native-code-push@${execSync('npm view react-native-code-push version')}`.trim();

console.log(`App name: ${appName}`);
console.log(`React Native version: ${reactNativeVersion}`);
console.log(`React Native Module for CodePush version: ${reactNativeCodePushVersion} \n`);

let androidStagingDeploymentKey = null;
let iosStagingDeploymentKey = null;



//GENERATE START
createCodePushApp(appNameAndroid, 'android');
createCodePushApp(appNameIOS, 'ios');

generatePlainReactNativeApp(appName, reactNativeVersion);
process.chdir(appName);
installCodePush(reactNativeCodePushVersion);
linkCodePush(androidStagingDeploymentKey, iosStagingDeploymentKey);
//GENERATE END



function createCodePushApp(name, platform) {
try {
console.log(`Creating CodePush app "${name}" to release updates for ${platform}...`);
execSync(`code-push app add ${name} ${platform} react-native`);
console.log(`App "${name}" has been created \n`);
} catch (e) {
console.log(`App "${name}" already exists \n`);
}
let deploymentKeys = JSON.parse(execSync(`code-push deployment ls ${name} -k --format json`));
let stagingDeploymentKey = deploymentKeys[1].key;
console.log(`Deployment key for ${platform}: ${stagingDeploymentKey}`);
console.log(`Use "code-push release-react ${name} ${platform}" command to release updates for ${platform} \n`);

switch (platform) {
case 'android':
androidStagingDeploymentKey = stagingDeploymentKey;
break;
case 'ios':
iosStagingDeploymentKey = stagingDeploymentKey;
break;
}
}

function generatePlainReactNativeApp(appName, reactNativeVersion) {
console.log(`Installing React Native...`);
execSync(`react-native init ${appName} --version ${reactNativeVersion}`);
console.log(`React Native has been installed \n`);
}

function installCodePush(reactNativeCodePushVersion) {
console.log(`Installing React Native Module for CodePush...`);
execSync(`npm i --save ${reactNativeCodePushVersion}`);
console.log(`React Native Module for CodePush has been installed \n`);
}

function linkCodePush(androidStagingDeploymentKey, iosStagingDeploymentKey) {
console.log(`Linking React Native Module for CodePush...`);
nexpect.spawn(`react-native link react-native-code-push`)
.wait("What is your CodePush deployment key for Android (hit <ENTER> to ignore)")
.sendline(androidStagingDeploymentKey)
.wait("What is your CodePush deployment key for iOS (hit <ENTER> to ignore)")
.sendline(iosStagingDeploymentKey)
.run(function (err) {
if (!err) {
console.log(`React Native Module for CodePush has been linked \n`);
setupAssets();
}
else {
console.log(err);
}
});
}

function setupAssets() {
fs.unlinkSync('./index.ios.js');
fs.unlinkSync('./index.android.js');

fs.writeFileSync('demo.js', fs.readFileSync('../CodePushDemoApp/demo.js'));
fs.writeFileSync('index.ios.js', fs.readFileSync('../CodePushDemoApp/index.ios.js'));
fs.writeFileSync('index.android.js', fs.readFileSync('../CodePushDemoApp/index.android.js'));

copyRecursiveSync('../CodePushDemoApp/images', './images');

fs.readFile('demo.js', 'utf8', function (err, data) {
if (err) {
return console.error(err);
}
var result = data.replace(/CodePushDemoApp/g, appName);

fs.writeFile('demo.js', result, 'utf8', function (err) {
if (err) return console.error(err);

if (!/^win/.test(process.platform)) {
optimizeToTestInDebugMode();
process.chdir('../');
grantAccess(appName);
}
console.log(`\nReact Native app "${appName}" has been generated and CodePushified!`);
process.exit();
});
});
}

function optimizeToTestInDebugMode() {
let rnXcodeShLocationFolder = 'scripts';
try {
let rnVersions = JSON.parse(execSync(`npm view react-native versions --json`));
let currentRNversion = JSON.parse(fs.readFileSync('./package.json'))['dependencies']['react-native'];
if (rnVersions.indexOf(currentRNversion) > -1 &&
rnVersions.indexOf(currentRNversion) < rnVersions.indexOf("0.46.0-rc.0")) {
rnXcodeShLocationFolder = 'packager';
}
} catch(e) {}

execSync(`perl -i -p0e 's/#ifdef DEBUG.*?#endif/jsCodeLocation = [CodePush bundleURL];/s' ios/${appName}/AppDelegate.m`);
execSync(`sed -ie '17,20d' node_modules/react-native/${rnXcodeShLocationFolder}/react-native-xcode.sh`);
execSync(`sed -ie 's/targetName.toLowerCase().contains("release")$/true/' node_modules/react-native/react.gradle`);
}

function grantAccess(folderPath) {
execSync('chown -R `whoami` ' + folderPath);
execSync('chmod -R 755 ' + folderPath);
}

function copyRecursiveSync(src, dest) {
var exists = fs.existsSync(src);
var stats = exists && fs.statSync(src);
var isDirectory = exists && stats.isDirectory();
if (exists && isDirectory) {
fs.mkdirSync(dest);
fs.readdirSync(src).forEach(function (childItemName) {
copyRecursiveSync(path.join(src, childItemName),
path.join(dest, childItemName));
});
} else {
fs.linkSync(src, dest);
}
}
63 changes: 0 additions & 63 deletions Examples/generate-app.sh

This file was deleted.

Loading

0 comments on commit 6f6f145

Please sign in to comment.