diff --git a/cli.js b/cli.js index 99a3b24e0e..4746bdbc8f 100644 --- a/cli.js +++ b/cli.js @@ -1,48 +1,16 @@ + /** * Copyright 2004-present Facebook. All Rights Reserved. */ 'use strict'; -var spawn = require('child_process').spawn; -var path = require('path'); - -function printUsage() { - console.log([ - 'Usage: react-native ', - '', - 'Commands:', - ' start: starts the webserver', - ].join('\n')); - process.exit(1); -} +var cli = require('./local-cli/cli.js'); function run() { - var args = process.argv.slice(2); - if (args.length === 0) { - printUsage(); - } - - switch (args[0]) { - case 'start': - spawn('sh', [ - path.resolve(__dirname, 'packager', 'packager.sh'), - '--projectRoots', - process.cwd(), - ], {stdio: 'inherit'}); - break; - default: - console.error('Command `%s` unrecognized', args[0]); - printUsage(); - } - // Here goes any cli commands we need to -} - -function init(root, projectName) { - spawn(path.resolve(__dirname, 'init.sh'), [projectName], {stdio:'inherit'}); + cli.run(); } module.exports = { - run: run, - init: init, + run: run }; diff --git a/local-cli/cli.js b/local-cli/cli.js new file mode 100644 index 0000000000..5319ceb754 --- /dev/null +++ b/local-cli/cli.js @@ -0,0 +1,53 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + */ + +'use strict'; + +var spawn = require('child_process').spawn; +var path = require('path'); +var install = require('./install.js'); + +function printUsage() { + console.log([ + 'Usage: react-native ', + '', + 'Commands:', + ' start: starts the webserver', + ' install: installs npm react components' + ].join('\n')); + process.exit(1); +} + +function run() { + var args = process.argv.slice(2); + if (args.length === 0) { + printUsage(); + } + + switch (args[0]) { + case 'start': + spawn('sh', [ + path.resolve(__dirname, 'packager', 'packager.sh'), + '--projectRoots', + process.cwd(), + ], {stdio: 'inherit'}); + break; + case 'install': + install.init(); + break; + default: + console.error('Command `%s` unrecognized', args[0]); + printUsage(); + } + // Here goes any cli commands we need to +} + +function init(root, projectName) { + spawn(path.resolve(__dirname, 'init.sh'), [projectName], {stdio:'inherit'}); +} + +module.exports = { + run: run, + init: init, +}; diff --git a/local-cli/install.js b/local-cli/install.js new file mode 100644 index 0000000000..c3de98aef6 --- /dev/null +++ b/local-cli/install.js @@ -0,0 +1,123 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + */ + + 'use strict'; + +var fs = require('fs'); +var exec = require('child_process').exec; + +var NODE_MODULE_PATH = './node_modules'; + +var PODFILE_PATH = './Podfile'; + +function addDependency(name, path) { + console.log('Found dependency: ' + name); + + var podfileText; + try { + podfileText = fs.readFileSync(PODFILE_PATH, 'utf8'); + } catch(e) {} + + if (podfileText.indexOf('pod \'' + name + '\'') === -1) { + var indexOfReactComponents = podfileText.indexOf('#') - 1; + + var insertedDependency = '\npod \'' + name + '\', :path => \'' + path + '\'\n'; + var newPodfileText = [podfileText.slice(0, indexOfReactComponents), + insertedDependency, + podfileText.slice(indexOfReactComponents)].join(''); + + fs.writeFileSync(PODFILE_PATH, newPodfileText); + console.log('Added ' + name + ' to Podfile.'); + } else { + console.log(name + ' already in Podfile'); + } +} + +function installDependecies() { + console.log('Installing dependencies...'); + exec('pod install', function(error, stdout, stderr) { + if (!stderr) { + console.log('Installed Pod dependencies.'); + } else { + console.error('Error installing Pod dependencies.', stderr); + } + process.exit(1); + }); +} + +module.exports = { + setupPodfile: function() { + var podfileText; + try { + podfileText = fs.readFileSync(PODFILE_PATH, 'utf8'); + } catch(e) {} + + var openingReactTag = '#'; + var closingReactTag = '\n#'; + var reactPodfileBoilerplate = openingReactTag + closingReactTag; + + if (!podfileText) { + fs.appendFileSync(PODFILE_PATH, reactPodfileBoilerplate); + } else { + if (podfileText.indexOf(openingReactTag) === -1 || podfileText.indexOf(closingReactTag) === -1) { + fs.appendFileSync(PODFILE_PATH, reactPodfileBoilerplate); + } + } + + try { + podfileText = fs.readFileSync(PODFILE_PATH, 'utf8'); + } catch(e) {} + + if (podfileText.indexOf('pod \'React\'') === -1) { + var indexOfReactComponents = podfileText.indexOf(openingReactTag) + openingReactTag.length; + + var insertedReactDependency = '\npod \'React\', :path => \'node_modules/react-native\'\n'; + try { + var newPodfileText = [podfileText.slice(0, indexOfReactComponents), + insertedReactDependency, + podfileText.slice(indexOfReactComponents)].join(''); + + fs.writeFileSync(PODFILE_PATH, newPodfileText); + } catch(e) { + throw e; + } + } + }, + init: function(arguement) { + // arguement is available for future arguement commands + console.log('Searching for installable React Native components...'); + this.setupPodfile(); + + var nodeModuleList = fs.readdirSync(NODE_MODULE_PATH); + + if (nodeModuleList.length > 0) { + nodeModuleList.forEach(function(nodeModule) { + // Module would not start with '.' hidden file identifier + if (nodeModule.charAt(0) !== '.') { + var modulePath = './node_modules/' + nodeModule; + + var nodeModulePackage; + try { + nodeModulePackage = fs.readFileSync(modulePath + '/package.json', 'utf8'); + } catch(error) { + console.error('Error reading Node Module: `%s` package.json', nodeModule); + throw error; + } + + var packageJSON = JSON.parse(nodeModulePackage); + console.log(packageJSON.hasOwnProperty('react-native-component')); + if (packageJSON.hasOwnProperty('react-native-component')) { + addDependency(nodeModule, modulePath); + } + } + }); + + installDependecies(); + } else { + console.error('./node_modules directory contains 0 modules'); + console.log('No React Native components found.'); + process.exit(1); + } + } +}; diff --git a/package.json b/package.json index 274a9ffdd7..eef77648d0 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "Examples/SampleApp", "Libraries", "packager", + "local-cli", "cli.js", "init.sh", "LICENSE", diff --git a/react-native-cli/index.js b/react-native-cli/index.js index 5742067f8b..7bd237e021 100755 --- a/react-native-cli/index.js +++ b/react-native-cli/index.js @@ -33,7 +33,8 @@ if (cli) { process.exit(1); } - if (args[0] === 'init') { + switch (args[0]) { + case 'init': if (args[1]) { init(args[1]); } else { @@ -42,13 +43,15 @@ if (cli) { ); process.exit(1); } - } else { + break; + default: console.error( 'Command `%s` unrecognized. ' + 'Did you mean to run this inside a react-native project?', args[0] ); process.exit(1); + break; } }