Skip to content

replace-fork: Cleanup after failure if no unstaged changes #22364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 60 additions & 19 deletions scripts/merge-fork/replace-fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

// Copies the contents of the new fork into the old fork

const chalk = require('chalk');
const {promisify} = require('util');
const glob = promisify(require('glob'));
const {spawnSync} = require('child_process');
const {execSync, spawnSync} = require('child_process');
const fs = require('fs');
const minimist = require('minimist');

Expand All @@ -18,31 +19,71 @@ const argv = minimist(process.argv.slice(2), {
});

async function main() {
const status = execSync('git status').toString();
const hadUnstagedChanges = status.includes('Changes not staged for commit');
if (hadUnstagedChanges) {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

await new Promise(resolve => {
rl.question(
`\n${chalk.yellow.bold(
'Unstaged changes were found in repository.'
)} Do you want to continue? (Y/n) `,
input => {
switch (input.trim().toLowerCase()) {
case '':
case 'y':
case 'yes':
resolve();
break;
default:
console.log('No modifications were made.');
process.exit(0);
break;
}
}
);
});
}

const oldFilenames = await glob('packages/react-reconciler/**/*.old.js');
await Promise.all(oldFilenames.map(unforkFile));

// Use ESLint to autofix imports
spawnSync('yarn', ['linc', '--fix'], {
const command = spawnSync('yarn', ['linc', '--fix'], {
stdio: ['inherit', 'inherit', 'pipe'],
});
// TODO: If eslint crashes, it may not have successfully fixed all
// the imports, which would leave the reconciler files in an inconsistent
// state. So we used to crash and reset the working directory. But that
// solution assumed that the working directory was clean before you run the
// command — if it wasn't, it'll not only reset the synced reconciler files,
// but all the other uncommitted changes.
//
// We need a different strategy to prevent loss of work. For example, we could
// exit early if the working directory is not clean before you run the script.
//
// Until we think of something better, I've commmented out this branch to
// prevent work from accidentally being lost.
// if (spawn.stderr.toString() !== '') {
// spawnSync('git', ['checkout', '.']);
if (command.status === 1) {
console.log(
chalk.bold.red('\nreplace-fork script failed with the following error:')
);
console.error(Error(command.stderr));

// console.log(Error(spawn.stderr));
// process.exitCode = 1;
// }
// If eslint crashes, it may not have successfully fixed all the imports,
// which would leave the reconciler files in an inconsistent stat.
// It would be nice to clean up the working directory in this case,
// but it's only safe to do that if we aren't going to override any previous changes.
if (!hadUnstagedChanges) {
spawnSync('git', ['checkout', '.']);
} else {
console.log(
`\n${chalk.yellow.bold(
'Unstaged changes were present when `replace-fork` was run.'
)} ` +
`To cleanup the repository run:\n ${chalk.bold(
'git checkout packages/react-reconciler'
)}`
);
}

process.exit(1);
} else {
process.exit(0);
}
}

async function unforkFile(oldFilename) {
Expand Down