react-native/react-native-git-upgrade/cliEntry.js

402 lines
13 KiB
JavaScript
Raw Normal View History

/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const fs = require('fs');
const os = require('os');
const assert = require('assert');
const path = require('path');
const shell = require('shelljs');
const Promise = require('promise');
const yeoman = require('yeoman-environment');
const TerminalAdapter = require('yeoman-environment/lib/adapter');
const log = require('npmlog');
const rimraf = require('rimraf');
const semver = require('semver');
const yarn = require('./yarn');
const {
checkDeclaredVersion,
checkMatchingVersions,
checkReactPeerDependency,
checkGitAvailable,
} = require('./checks');
log.heading = 'git-upgrade';
/**
* Promisify the callback-based shelljs function exec
* @param logOutput If true, log the stdout of the command.
✨ Colorize filenames with conflicts when upgrading Summary: Visually show files merged with conflicts when running `react-native-git-upgrade`. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> After running `react-native-git-upgrade`, files with conflicts are not immediately recognised visually. With this patch, files with conflicts are highlighted in red. ![image](https://user-images.githubusercontent.com/771989/36086385-fc183baa-1006-11e8-8862-0867b82b7ec1.png) <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> [CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Print files with conflicts in red. Closes https://github.com/facebook/react-native/pull/17947 Differential Revision: D6977042 Pulled By: hramos fbshipit-source-id: 3c67561ea3acbee227a7a0cf42857af4fb75c75c
2018-02-13 16:51:12 +00:00
* @param logger Custom logger to modify the output, invoked with the data and the stream.
* @returns {Promise}
*/
✨ Colorize filenames with conflicts when upgrading Summary: Visually show files merged with conflicts when running `react-native-git-upgrade`. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> After running `react-native-git-upgrade`, files with conflicts are not immediately recognised visually. With this patch, files with conflicts are highlighted in red. ![image](https://user-images.githubusercontent.com/771989/36086385-fc183baa-1006-11e8-8862-0867b82b7ec1.png) <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> [CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Print files with conflicts in red. Closes https://github.com/facebook/react-native/pull/17947 Differential Revision: D6977042 Pulled By: hramos fbshipit-source-id: 3c67561ea3acbee227a7a0cf42857af4fb75c75c
2018-02-13 16:51:12 +00:00
function exec(command, logOutput, logger = null) {
return new Promise((resolve, reject) => {
let stderr, stdout = '';
const child = shell.exec(command, {async: true, silent: true});
child.stdout.on('data', data => {
stdout += data;
if (logOutput) {
✨ Colorize filenames with conflicts when upgrading Summary: Visually show files merged with conflicts when running `react-native-git-upgrade`. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> After running `react-native-git-upgrade`, files with conflicts are not immediately recognised visually. With this patch, files with conflicts are highlighted in red. ![image](https://user-images.githubusercontent.com/771989/36086385-fc183baa-1006-11e8-8862-0867b82b7ec1.png) <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> [CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Print files with conflicts in red. Closes https://github.com/facebook/react-native/pull/17947 Differential Revision: D6977042 Pulled By: hramos fbshipit-source-id: 3c67561ea3acbee227a7a0cf42857af4fb75c75c
2018-02-13 16:51:12 +00:00
if (logger) {
logger(data, process.stdout);
} else {
process.stdout.write(data);
}
}
});
child.stderr.on('data', data => {
stderr += data;
✨ Colorize filenames with conflicts when upgrading Summary: Visually show files merged with conflicts when running `react-native-git-upgrade`. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> After running `react-native-git-upgrade`, files with conflicts are not immediately recognised visually. With this patch, files with conflicts are highlighted in red. ![image](https://user-images.githubusercontent.com/771989/36086385-fc183baa-1006-11e8-8862-0867b82b7ec1.png) <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> [CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Print files with conflicts in red. Closes https://github.com/facebook/react-native/pull/17947 Differential Revision: D6977042 Pulled By: hramos fbshipit-source-id: 3c67561ea3acbee227a7a0cf42857af4fb75c75c
2018-02-13 16:51:12 +00:00
if (logger) {
logger(data, process.stderr);
} else {
process.stderr.write(data);
}
});
child.on('exit', (code, signal) => {
if (code === 0) {
resolve(stdout);
} else if (code) {
reject(new Error(`Command '${command}' exited with code ${code}:
stderr: ${stderr}
stdout: ${stdout}`));
} else {
reject(new Error(`Command '${command}' terminated with signal '${signal}':
stderr: ${stderr}
stdout: ${stdout}`));
}
});
});
}
function parseJsonFile(path, useYarn) {
const installHint = useYarn ?
'Make sure you ran "yarn" and that you are inside a React Native project.' :
'Make sure you ran "npm install" and that you are inside a React Native project.';
let fileContents;
try {
fileContents = fs.readFileSync(path, 'utf8');
} catch (err) {
throw new Error('Cannot find "' + path + '". ' + installHint);
}
try {
return JSON.parse(fileContents);
} catch (err) {
throw new Error('Cannot parse "' + path + '": ' + err.message);
}
}
function readPackageFiles(useYarn) {
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'
);
return {
reactNativeNodeModulesPak: parseJsonFile(reactNativeNodeModulesPakPath),
reactNodeModulesPak: parseJsonFile(reactNodeModulesPakPath),
pak: parseJsonFile(pakPath)
};
}
function parseInformationJsonOutput(jsonOutput, requestedVersion) {
try {
const output = JSON.parse(jsonOutput);
const newVersion = output.version;
const peerDependencies = output.peerDependencies;
const newReactVersionRange = peerDependencies.react;
assert(semver.valid(newVersion));
return {newVersion, newReactVersionRange};
} catch (err) {
throw new Error(
'The specified version of React Native ' + requestedVersion + ' doesn\'t exist.\n' +
'Re-run the react-native-git-upgrade command with an existing version,\n' +
'for example: "react-native-git-upgrade 0.38.0",\n' +
'or without arguments to upgrade to the latest: "react-native-git-upgrade".'
);
}
}
function setupWorkingDir(tmpDir) {
return new Promise((resolve, reject) => {
rimraf(tmpDir, err => {
if (err) {
reject(err);
} else {
fs.mkdirSync(tmpDir);
resolve();
}
});
});
}
function configureGitEnv(tmpDir) {
/*
* The workflow inits a temporary Git repository. We don't want to interfere
* with an existing user's Git repository.
* Thanks to Git env vars, we can make Git use a different directory for its ".git" folder.
* See https://git-scm.com/book/tr/v2/Git-Internals-Environment-Variables
*/
process.env.GIT_DIR = path.resolve(tmpDir, '.gitrn');
process.env.GIT_WORK_TREE = '.';
}
Keep the ignored files during the upgrade process Summary: This PR fixes the issue #12237 relative to react-native-git-upgrade. When the user adds new files to the .gitignore file, those files are deleted during the upgrade process because it starts by creating a fresh .gitignore file without user's modification, so the user's ignored files are no longer ignored and they are deleted during the upgrading process. The best solution I've found to keep the user's ignored files... ignored, consists in appending the content of the .gitignore file in the `<TEMP DIR>/.git-rn/info/exclude` file. The user's ignored files are now ignored at the repository level, they no longer interfere with the upgrade process. Reminder: The tool uses a temporary local Git repository generated on the fly, so we can do whatever we want in it. - Publish react-native-git-upgrade to sinopia - `npm install -g react-native-git-upgrade` - Init a new project with an old version: `react-native init MyApp --version=0.50.0` - Create a new file named `dummy-ignored-file.json` in the project's root - Append `dummy-ignored-file.json` to the `.gitignore` file - Run `react-native-git-upgrade` 👉 The `dummy-ignored-file.json` is not deleted. [CLI][BUGFIX][react-native-git-upgrade] - Keep the user's ignored files while upgrading <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> Closes https://github.com/facebook/react-native/pull/17393 Differential Revision: D6839856 Pulled By: hramos fbshipit-source-id: e4e9d759b59790e3cbc52408cef8314bf0a9c772
2018-02-01 21:59:57 +00:00
function copyCurrentGitIgnoreFile(tmpDir) {
/*
* The user may have added new files or directories in the .gitignore file.
* We need to keep those files ignored during the process, otherwise they
* will be deleted.
* See https://github.com/facebook/react-native/issues/12237
*/
try {
const gitignorePath = path.resolve(process.cwd(), '.gitignore');
const repoExcludePath = path.resolve(tmpDir, process.env.GIT_DIR, 'info/exclude');
const content = fs.readFileSync(gitignorePath, 'utf8');
fs.appendFileSync(repoExcludePath, content);
} catch (err) {
if (err.code === 'ENOENT') {
log.info('No .gitignore file found, this step is a no-op');
return;
}
throw err;
}
}
function generateTemplates(generatorDir, appName, verbose) {
try {
const yeomanGeneratorEntryPoint = path.resolve(generatorDir, 'index.js');
// Try requiring the index.js (entry-point of Yeoman generators)
fs.accessSync(yeomanGeneratorEntryPoint);
return runYeomanGenerators(generatorDir, appName, verbose);
} catch (err) {
return runCopyAndReplace(generatorDir, appName);
}
}
function runCopyAndReplace(generatorDir, appName) {
const copyProjectTemplateAndReplacePath = path.resolve(generatorDir, 'copyProjectTemplateAndReplace');
/*
* This module is required twice during the process: for both old and new version
* of React Native.
* This file could have changed between these 2 versions. When generating the new template,
* we don't want to load the old version of the generator from the cache
*/
delete require.cache[require.resolve(copyProjectTemplateAndReplacePath)];
const copyProjectTemplateAndReplace = require(copyProjectTemplateAndReplacePath);
copyProjectTemplateAndReplace(
path.resolve(generatorDir, '..', 'templates', 'HelloWorld'),
process.cwd(),
appName,
{upgrade: true, force: true}
);
}
function runYeomanGenerators(generatorDir, appName, verbose) {
if (!verbose) {
// Yeoman output needs monkey-patching (no silent option)
TerminalAdapter.prototype.log = () => {};
TerminalAdapter.prototype.log.force = () => {};
TerminalAdapter.prototype.log.create = () => {};
}
const env = yeoman.createEnv();
env.register(generatorDir, 'react:app');
const generatorArgs = ['react:app', appName];
return new Promise((resolve) => env.run(generatorArgs, {upgrade: true, force: true}, resolve));
}
/**
* If there's a newer version of react-native-git-upgrade in npm, suggest to the user to upgrade.
*/
async function checkForUpdates() {
try {
log.info('Check for updates');
const lastGitUpgradeVersion = await exec('npm view react-native-git-upgrade@latest version');
const current = require('./package').version;
const latest = semver.clean(lastGitUpgradeVersion);
if (semver.gt(latest, current)) {
log.warn(
'A more recent version of "react-native-git-upgrade" has been found.\n' +
`Current: ${current}\n` +
`Latest: ${latest}\n` +
'Please run "npm install -g react-native-git-upgrade"'
);
}
} catch (err) {
log.warn('Check for latest version failed', err.message);
}
}
/**
* If true, use yarn instead of the npm client to upgrade the project.
*/
function shouldUseYarn(cliArgs, projectDir) {
if (cliArgs && cliArgs.npm) {
return false;
}
const yarnVersion = yarn.getYarnVersionIfAvailable();
if (yarnVersion && yarn.isProjectUsingYarn(projectDir)) {
log.info('Using yarn ' + yarnVersion);
return true;
}
return false;
}
/**
* @param requestedVersion The version argument, e.g. 'react-native-git-upgrade 0.38'.
* `undefined` if no argument passed.
* @param cliArgs Additional arguments parsed using minimist.
*/
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 {
await checkForUpdates();
const useYarn = shouldUseYarn(cliArgs, path.resolve(process.cwd()));
log.info('Read package.json files');
const {reactNativeNodeModulesPak, reactNodeModulesPak, pak} = readPackageFiles(useYarn);
const appName = pak.name;
const currentVersion = reactNativeNodeModulesPak.version;
const currentReactVersion = reactNodeModulesPak.version;
const declaredVersion = pak.dependencies['react-native'];
const declaredReactVersion = pak.dependencies.react;
const verbose = cliArgs.verbose;
log.info('Check declared version');
checkDeclaredVersion(declaredVersion);
log.info('Check matching versions');
checkMatchingVersions(currentVersion, declaredVersion, useYarn);
log.info('Check React peer dependency');
checkReactPeerDependency(currentVersion, declaredReactVersion);
log.info('Check that Git is installed');
checkGitAvailable();
log.info('Get information from NPM registry');
const viewCommand = 'npm view react-native@' + (requestedVersion || 'latest') + ' --json';
const jsonOutput = await exec(viewCommand, verbose);
const {newVersion, newReactVersionRange} = parseInformationJsonOutput(jsonOutput, requestedVersion);
// Print which versions we're upgrading to
log.info('Upgrading to React Native ' + newVersion + (newReactVersionRange ? ', React ' + newReactVersionRange : ''));
log.info('Setup temporary working directory');
await setupWorkingDir(tmpDir);
log.info('Configure Git environment');
configureGitEnv(tmpDir);
Keep the ignored files during the upgrade process Summary: This PR fixes the issue #12237 relative to react-native-git-upgrade. When the user adds new files to the .gitignore file, those files are deleted during the upgrade process because it starts by creating a fresh .gitignore file without user's modification, so the user's ignored files are no longer ignored and they are deleted during the upgrading process. The best solution I've found to keep the user's ignored files... ignored, consists in appending the content of the .gitignore file in the `<TEMP DIR>/.git-rn/info/exclude` file. The user's ignored files are now ignored at the repository level, they no longer interfere with the upgrade process. Reminder: The tool uses a temporary local Git repository generated on the fly, so we can do whatever we want in it. - Publish react-native-git-upgrade to sinopia - `npm install -g react-native-git-upgrade` - Init a new project with an old version: `react-native init MyApp --version=0.50.0` - Create a new file named `dummy-ignored-file.json` in the project's root - Append `dummy-ignored-file.json` to the `.gitignore` file - Run `react-native-git-upgrade` 👉 The `dummy-ignored-file.json` is not deleted. [CLI][BUGFIX][react-native-git-upgrade] - Keep the user's ignored files while upgrading <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> Closes https://github.com/facebook/react-native/pull/17393 Differential Revision: D6839856 Pulled By: hramos fbshipit-source-id: e4e9d759b59790e3cbc52408cef8314bf0a9c772
2018-02-01 21:59:57 +00:00
log.info('Init temporary Git repository');
await exec('git init', verbose);
Keep the ignored files during the upgrade process Summary: This PR fixes the issue #12237 relative to react-native-git-upgrade. When the user adds new files to the .gitignore file, those files are deleted during the upgrade process because it starts by creating a fresh .gitignore file without user's modification, so the user's ignored files are no longer ignored and they are deleted during the upgrading process. The best solution I've found to keep the user's ignored files... ignored, consists in appending the content of the .gitignore file in the `<TEMP DIR>/.git-rn/info/exclude` file. The user's ignored files are now ignored at the repository level, they no longer interfere with the upgrade process. Reminder: The tool uses a temporary local Git repository generated on the fly, so we can do whatever we want in it. - Publish react-native-git-upgrade to sinopia - `npm install -g react-native-git-upgrade` - Init a new project with an old version: `react-native init MyApp --version=0.50.0` - Create a new file named `dummy-ignored-file.json` in the project's root - Append `dummy-ignored-file.json` to the `.gitignore` file - Run `react-native-git-upgrade` 👉 The `dummy-ignored-file.json` is not deleted. [CLI][BUGFIX][react-native-git-upgrade] - Keep the user's ignored files while upgrading <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> Closes https://github.com/facebook/react-native/pull/17393 Differential Revision: D6839856 Pulled By: hramos fbshipit-source-id: e4e9d759b59790e3cbc52408cef8314bf0a9c772
2018-02-01 21:59:57 +00:00
log.info('Save current .gitignore file');
copyCurrentGitIgnoreFile(tmpDir);
log.info('Add all files to commit');
await exec('git add .', verbose);
log.info('Commit current project sources');
await exec('git commit -m "Project snapshot" --no-verify', verbose);
log.info('Create a tag before updating sources');
await exec('git tag project-snapshot', verbose);
projectBackupCreated = true;
log.info('Generate old version template');
await generateTemplates(generatorDir, appName, verbose);
log.info('Add updated files to commit');
await exec('git add .', verbose);
log.info('Commit old version template');
await exec('git commit -m "Old version" --allow-empty --no-verify', verbose);
log.info('Install the new version');
let installCommand;
if (useYarn) {
installCommand = 'yarn add';
} else {
installCommand = 'npm install --save --color=always';
}
installCommand += ' react-native@' + newVersion;
if (newReactVersionRange && !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);
log.info('Add updated files to commit');
await exec('git add .', verbose);
log.info('Commit new version template');
await exec('git commit -m "New version" --allow-empty --no-verify', verbose);
log.info('Generate the patch between the 2 versions');
const diffOutput = await exec('git diff --binary --no-color HEAD~1 HEAD', verbose);
log.info('Save the patch in temp directory');
const patchPath = path.resolve(tmpDir, `upgrade_${currentVersion}_${newVersion}.patch`);
fs.writeFileSync(patchPath, diffOutput);
log.info('Reset the 2 temporary commits');
await exec('git reset HEAD~2 --hard', verbose);
try {
log.info('Apply the patch');
✨ Colorize filenames with conflicts when upgrading Summary: Visually show files merged with conflicts when running `react-native-git-upgrade`. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> After running `react-native-git-upgrade`, files with conflicts are not immediately recognised visually. With this patch, files with conflicts are highlighted in red. ![image](https://user-images.githubusercontent.com/771989/36086385-fc183baa-1006-11e8-8862-0867b82b7ec1.png) <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAL ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> [CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Print files with conflicts in red. Closes https://github.com/facebook/react-native/pull/17947 Differential Revision: D6977042 Pulled By: hramos fbshipit-source-id: 3c67561ea3acbee227a7a0cf42857af4fb75c75c
2018-02-13 16:51:12 +00:00
await exec(`git apply --3way ${patchPath}`, true, (data, stream) => {
if (data.indexOf('conflicts') >= 0 || data.startsWith('U ')) {
stream.write(`\x1b[31m${data}\x1b[0m`);
} else {
stream.write(data);
}
});
} catch (err) {
log.warn(
'The upgrade process succeeded but there might be conflicts to be resolved. ' +
Suggest git apply --reject for failed upgrades Summary: The upgrade script uses `git apply --3way`: https://github.com/facebook/react-native/blob/4906f8d28cdbaf1b432494b473a4c61c1e193881/react-native-git-upgrade/cliEntry.js#L368-L369 If you've already upgraded something that React Native upgraded, this will silently fail. For example if you have already upgraded Gradle to the version available in the new version of React Native, the 3-way patch will fail. In this case, the upgraded version is installed into `node_modules` but `package.json` is not updated. More context, discussion, and information is in https://github.com/facebook/react-native/issues/12112#issuecomment-292619346. Until a more robust solution is implemented, this PR proposes to mitigate the effects of the problem by informing the user of the possible issue and instructing them of a workaround. In an affected project, I ran `react-native-git-upgrade` after applying my patch. As expected, I now receive the following output: ![image](https://user-images.githubusercontent.com/789577/38165770-6209ac68-34de-11e8-9d96-7c782e9ef7ce.png) After running the suggested command, `git status` now shows me the two rejections: ![image](https://user-images.githubusercontent.com/789577/38165796-d10ca7c8-34de-11e8-9037-8427513e3a84.png) And I can now [manually apply](https://stackoverflow.com/a/28569128/1445366) these changes. [CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Provide instructions for upgrading React Native when 3-way merges don't apply Closes https://github.com/facebook/react-native/pull/18636 Differential Revision: D7603073 Pulled By: hramos fbshipit-source-id: 32d387e1ee67d8b182d248c585cd33ba94808357
2018-04-12 18:40:33 +00:00
'See above for the list of files that have merge conflicts. ' +
'If you dont see the expected changes, try running:\n' +
`git apply --reject ${patchPath}`);
} finally {
log.info('Upgrade done');
if (cliArgs.verbose) {
log.info(`Temporary working directory: ${tmpDir}`);
}
}
} catch (err) {
log.error('An error occurred during upgrade:');
log.error(err.stack);
if (projectBackupCreated) {
log.error('Restore initial sources');
await exec('git checkout project-snapshot --no-verify', true);
}
}
}
module.exports = {
run: run,
};