149 lines
4.5 KiB
JavaScript
149 lines
4.5 KiB
JavaScript
/**
|
|
* 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 Promise = require('promise');
|
|
|
|
const chalk = require('chalk');
|
|
const copyProjectTemplateAndReplace = require('../generator/copyProjectTemplateAndReplace');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const printRunInstructions = require('../generator/printRunInstructions');
|
|
const semver = require('semver');
|
|
const yarn = require('../util/yarn');
|
|
|
|
/**
|
|
* Migrate application to a new version of React Native.
|
|
* See http://facebook.github.io/react-native/docs/upgrading.html
|
|
*
|
|
* IMPORTANT: Assumes the cwd() is the project directory.
|
|
* The code here must only be invoked via the CLI:
|
|
* $ cd MyAwesomeApp
|
|
* $ react-native upgrade
|
|
*/
|
|
function validateAndUpgrade() {
|
|
const projectDir = process.cwd();
|
|
|
|
const packageJSON = JSON.parse(
|
|
fs.readFileSync(path.resolve(projectDir, 'package.json'), 'utf8')
|
|
);
|
|
|
|
const projectName = packageJSON.name;
|
|
if (!projectName) {
|
|
warn(
|
|
"Your project needs to have a name, declared in package.json, " +
|
|
"such as \"name\": \"AwesomeApp\". Please add a project name. Aborting."
|
|
);
|
|
return;
|
|
}
|
|
|
|
const version = packageJSON.dependencies['react-native'];
|
|
if (!version) {
|
|
warn(
|
|
"Your 'package.json' file doesn't seem to declare 'react-native' as " +
|
|
"a dependency. Nothing to upgrade. Aborting."
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (version === 'latest' || version === '*') {
|
|
warn(
|
|
"Some major releases introduce breaking changes.\n" +
|
|
"Please use a caret version number in your 'package.json' file \n" +
|
|
"to avoid breakage. Use e.g. react-native: ^0.38.0. Aborting."
|
|
);
|
|
return;
|
|
}
|
|
|
|
const installed = JSON.parse(
|
|
fs.readFileSync(
|
|
path.resolve(projectDir, 'node_modules/react-native/package.json'),
|
|
'utf8'
|
|
)
|
|
);
|
|
|
|
if (!semver.satisfies(installed.version, version)) {
|
|
warn(
|
|
"react-native version in 'package.json' doesn't match the installed version in 'node_modules'.\n" +
|
|
"Try running 'npm install' to fix this. Aborting."
|
|
);
|
|
return;
|
|
}
|
|
|
|
const v = version.replace(/^(~|\^|=)/, '').replace(/x/i, '0');
|
|
|
|
if (!semver.valid(v)) {
|
|
warn(
|
|
"A valid version number for 'react-native' is not specified in your " +
|
|
"'package.json' file. Aborting."
|
|
);
|
|
return;
|
|
}
|
|
|
|
console.log(
|
|
'Upgrading project to react-native v' + installed.version + '\n' +
|
|
'Check out the release notes and breaking changes: ' +
|
|
'https://github.com/facebook/react-native/releases/tag/v' + semver.major(v) + '.' + semver.minor(v) + '.0'
|
|
);
|
|
|
|
// >= v0.21.0, we require react to be a peer dependency
|
|
if (semver.gte(v, '0.21.0') && !packageJSON.dependencies.react) {
|
|
warn(
|
|
"Your 'package.json' file doesn't seem to have 'react' as a dependency.\n" +
|
|
"'react' was changed from a dependency to a peer dependency in react-native v0.21.0.\n" +
|
|
"Therefore, it's necessary to include 'react' in your project's dependencies.\n" +
|
|
"Please run 'npm install --save react', then re-run 'react-native upgrade'.\n"
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (semver.satisfies(v, '~0.26.0')) {
|
|
warn(
|
|
"React Native 0.26 introduced some breaking changes to the native files on iOS. You can\n" +
|
|
"perform them manually by checking the release notes or use \'rnpm\' to do it automatically.\n" +
|
|
"Just run:\n" +
|
|
"\'npm install -g rnpm && npm install rnpm-plugin-upgrade@0.26 --save-dev\', then run \'rnpm upgrade\'"
|
|
);
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
upgradeProjectFiles(projectDir, projectName);
|
|
console.log(
|
|
'Successfully upgraded this project to react-native v' + installed.version
|
|
);
|
|
resolve();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Once all checks passed, upgrade the project files.
|
|
*/
|
|
function upgradeProjectFiles(projectDir, projectName) {
|
|
// Just owerwrite
|
|
copyProjectTemplateAndReplace(
|
|
path.resolve('node_modules', 'react-native', 'local-cli', 'templates', 'HelloWorld'),
|
|
projectDir,
|
|
projectName,
|
|
{upgrade: true}
|
|
);
|
|
}
|
|
|
|
function warn(message) {
|
|
console.warn(chalk.yellow(message));
|
|
}
|
|
|
|
const upgradeCommand = {
|
|
name: 'upgrade',
|
|
description: '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',
|
|
func: validateAndUpgrade,
|
|
};
|
|
|
|
module.exports = upgradeCommand;
|