diff --git a/local-cli/cli.js b/local-cli/cli.js index e0bb17270..a07ebce80 100644 --- a/local-cli/cli.js +++ b/local-cli/cli.js @@ -26,13 +26,16 @@ var runAndroid = require('../private-cli/src/runAndroid/runAndroid'); var server = require('../private-cli/src/server/server'); var TerminalAdapter = require('yeoman-environment/lib/adapter.js'); var yeoman = require('yeoman-environment'); +var upgrade = require('../private-cli/src/upgrade/upgrade'); var documentedCommands = { 'start': [server, 'starts the webserver'], 'bundle': [bundle, 'builds the javascript bundle for offline use'], 'new-library': [library, 'generates a native library bridge'], 'android': [generateWrapper, 'generates an Android project for your app'], - 'run-android': [runAndroid, 'builds your app and starts it on a connected Android emulator or device'] + 'run-android': [runAndroid, 'builds your app and starts it on a connected Android emulator or device'], + 'upgrade': [upgrade, 'upgrade your app\'s template files to the latest version; run this after ' + + 'updating the react-native version in your package.json and running npm install'] }; var undocumentedCommands = { diff --git a/local-cli/generator-android/index.js b/local-cli/generator-android/index.js index 55e440a8a..eb4a43944 100644 --- a/local-cli/generator-android/index.js +++ b/local-cli/generator-android/index.js @@ -29,6 +29,11 @@ module.exports = yeoman.generators.NamedBase.extend({ type: String, defaults: 'com.' + this.name.toLowerCase() }); + this.option('upgrade', { + desc: 'Specify an upgrade', + type: Boolean, + defaults: false + }); }, initializing: function() { @@ -42,15 +47,29 @@ module.exports = yeoman.generators.NamedBase.extend({ package: this.options.package, name: this.name }; - this.fs.copyTpl( - this.templatePath(path.join('src', '**')), - this.destinationPath('android'), - templateParams - ); - this.fs.copy( - this.templatePath(path.join('bin', '**')), - this.destinationPath('android') - ); + if (!this.options.upgrade) { + this.fs.copyTpl( + this.templatePath(path.join('src', '**')), + this.destinationPath('android'), + templateParams + ); + this.fs.copy( + this.templatePath(path.join('bin', '**')), + this.destinationPath('android') + ); + } else { + this.fs.copyTpl( + this.templatePath(path.join('src', '*')), + this.destinationPath('android'), + templateParams + ); + this.fs.copyTpl( + this.templatePath(path.join('src', 'app', '*')), + this.destinationPath(path.join('android', 'app')), + templateParams + ); + } + var javaPath = path.join.apply( null, ['android', 'app', 'src', 'main', 'java'].concat(this.options.package.split('.')) diff --git a/local-cli/generator/index.js b/local-cli/generator/index.js index 6a1b6ac00..dadbd7a17 100644 --- a/local-cli/generator/index.js +++ b/local-cli/generator/index.js @@ -26,16 +26,21 @@ module.exports = yeoman.generators.NamedBase.extend({ type: Boolean, defaults: false }); + this.option('upgrade', { + desc: 'Specify an upgrade', + type: Boolean, + defaults: false + }); // this passes command line arguments down to the composed generators - var args = arguments[0]; + var args = {args: arguments[0], options: this.options}; if (!this.options['skip-ios']) { - this.composeWith('react:ios', {args: args}, { + this.composeWith('react:ios', args, { local: require.resolve(path.resolve(__dirname, '..', 'generator-ios')) }); } if (!this.options['skip-android']) { - this.composeWith('react:android', {args: args}, { + this.composeWith('react:android', args, { local: require.resolve(path.resolve(__dirname, '..', 'generator-android')) }); } @@ -59,6 +64,10 @@ module.exports = yeoman.generators.NamedBase.extend({ }, writing: function() { + if (this.options.upgrade) { + // never upgrade index.*.js files + return; + } if (!this.options['skip-ios']) { this.fs.copyTpl( this.templatePath('index.ios.js'), diff --git a/private-cli/src/cli.js b/private-cli/src/cli.js index 0c6b20e03..7d3bc0413 100644 --- a/private-cli/src/cli.js +++ b/private-cli/src/cli.js @@ -13,11 +13,13 @@ const Config = require('./util/Config'); const dependencies = require('./dependencies/dependencies'); const Promise = require('promise'); const server = require('./server/server'); +const upgrade = require('./upgrade/upgrade'); const documentedCommands = { bundle: bundle, dependencies: dependencies, server: server, + upgrade, }; const hiddenCommands = { diff --git a/private-cli/src/upgrade/upgrade.js b/private-cli/src/upgrade/upgrade.js new file mode 100644 index 000000000..222b6cd31 --- /dev/null +++ b/private-cli/src/upgrade/upgrade.js @@ -0,0 +1,24 @@ +/** + * 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. + */ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const Promise = require('promise'); +const yeoman = require('yeoman-environment'); + +module.exports = function upgrade(args, config) { + args = args || process.argv; + let env = yeoman.createEnv(); + let name = JSON.parse(fs.readFileSync('package.json', 'utf8')).name; + let generatorPath = path.join(__dirname, '..', '..', '..', 'local-cli', 'generator'); + env.register(generatorPath, 'react:app'); + let generatorArgs = ['react:app', name].concat(args); + return new Promise((resolve) => env.run(generatorArgs, {upgrade: true}, resolve)); +};