Upgrade React and React Native at the same time

Summary:
**Motivation**
As NoelBroda pointed out in https://github.com/facebook/react-native/pull/11104 and https://github.com/facebook/react-native/pull/11123, NPM often produces an unmet peerDependency when upgrading React Native. It causes a failure when running "npm install" with NPM2.

During the git-upgrade, we have to take care of the `react` peerDep: this PR checks if the installed `react` package matches the `react` peerDep of the new `react-native` version. If so, R & RN are upgraded at the same time (in the same `npm install`).

**Test plan**
- Publish `react-native-git-upgrade` to Sinopia,
- Run `react-native-git-upgrade` inside a RN project with version < 0.37,
- Verify that no "unmet peer dependency" warning is displayed
- Open the `package.json` and verify that both R & RN have been updated
Closes https://github.com/facebook/react-native/pull/11226

Differential Revision: D4258007

Pulled By: mkonicek

fbshipit-source-id: cff466d4710807d97fc6161f47bb974097b75261
This commit is contained in:
Nicolas Cuillery 2016-12-01 03:35:45 -08:00 committed by Facebook Github Bot
parent c5da1068f8
commit a0f3a93f0b
1 changed files with 29 additions and 14 deletions

View File

@ -68,27 +68,35 @@ stdout: ${stdout}`));
+ * - Parsed package.json
+ */
function readPackageFiles() {
const nodeModulesPakPath = path.resolve(
const reactNativeNodeModulesPakPath = path.resolve(
process.cwd(),
'node_modules',
'react-native',
'package.json'
);
const reactNodeModulesPakPath = path.resolve(
process.cwd(),
'node_modules',
'react',
'package.json'
);
const pakPath = path.resolve(
process.cwd(),
'package.json'
);
try {
const nodeModulesPak = JSON.parse(fs.readFileSync(nodeModulesPakPath, 'utf8'));
const reactNativeNodeModulesPak = JSON.parse(fs.readFileSync(reactNativeNodeModulesPakPath, 'utf8'));
const reactNodeModulesPak = JSON.parse(fs.readFileSync(reactNodeModulesPakPath, 'utf8'));
const pak = JSON.parse(fs.readFileSync(pakPath, 'utf8'));
return {nodeModulesPak, pak};
return {reactNativeNodeModulesPak, reactNodeModulesPak, pak};
} catch (err) {
throw new Error(
'Unable to find "' + pakPath + '" or "' + nodeModulesPakPath + '". ' +
'Make sure you ran "npm install" and that you are inside a React Native project.'
'Unable to find one of "' + pakPath + '", "' + rnPakPath + '" or "' + reactPakPath + '". ' +
'Make sure you ran "npm install" and that you are inside a React Native project.'
)
}
}
@ -191,16 +199,16 @@ async function checkForUpdates() {
async function run(requestedVersion, cliArgs) {
const tmpDir = path.resolve(os.tmpdir(), 'react-native-git-upgrade');
const generatorDir = path.resolve(process.cwd(), 'node_modules', 'react-native', 'local-cli', 'generator');
let projectBackupCreated = false;
try {
let projectBackupCreated = false;
await checkForUpdates();
log.info('Read package.json files');
const {nodeModulesPak, pak} = readPackageFiles();
const {reactNativeNodeModulesPak, reactNodeModulesPak, pak} = readPackageFiles();
const appName = pak.name;
const currentVersion = nodeModulesPak.version;
const currentVersion = reactNativeNodeModulesPak.version;
const currentReactVersion = reactNodeModulesPak.version;
const declaredVersion = pak.dependencies['react-native'];
const declaredReactVersion = pak.dependencies.react;
@ -218,10 +226,11 @@ async function run(requestedVersion, cliArgs) {
log.info('Check that Git is installed');
checkGitAvailable();
log.info('Get react-native version from NPM registry');
const versionOutput = await exec('npm view react-native@' + (requestedVersion || 'latest') + ' version', verbose);
const newVersion = semver.clean(versionOutput);
log.info('Upgrading to React Native ' + newVersion);
log.info('Get information from NPM registry');
const viewCommand = 'npm view react-native@' + (requestedVersion || 'latest') + ' peerDependencies.react version --json';
const viewOutput = await exec(viewCommand, verbose).then(JSON.parse);
const newVersion = viewOutput.version;
const newReactVersionRange = viewOutput['peerDependencies.react'];
log.info('Check new version');
checkNewVersionValid(newVersion, requestedVersion);
@ -255,7 +264,13 @@ async function run(requestedVersion, cliArgs) {
await exec('git commit -m "Old version" --allow-empty', verbose);
log.info('Install the new version');
await exec('npm install --save react-native@' + newVersion + ' --color=always', verbose);
let installCommand = 'npm install --save --color=always';
installCommand += ' react-native@' + newVersion;
if (!semver.satisfies(currentReactVersion, newReactVersionRange)) {
// Install React as well to avoid unmet peer dependency
installCommand += ' react@' + newReactVersionRange;
}
await exec(installCommand, verbose);
log.info('Generate new version template');
await generateTemplates(generatorDir, appName, verbose);