Skip to content

Commit

Permalink
Upgrade React and React Native at the same time
Browse files Browse the repository at this point in the history
Summary:
**Motivation**
As NoelBroda pointed out in #11104 and #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 #11226

Differential Revision: D4258007

Pulled By: mkonicek

fbshipit-source-id: cff466d4710807d97fc6161f47bb974097b75261
  • Loading branch information
ncuillery authored and Facebook Github Bot committed Dec 1, 2016
1 parent c5da106 commit a0f3a93
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions react-native-git-upgrade/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.'
)
}
}
Expand Down Expand Up @@ -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');

This comment has been minimized.

Copy link
@fungilation

fungilation Jan 5, 2017

Is this considering yarn use? package.json doesn't change in yarn on upgrades, only yarn.lock changes.

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;

Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit a0f3a93

Please sign in to comment.