@samitouri / QOS-React-2 / commits / 57e4d6872f

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

Brian Vaughn committed Sep 20, 2021 at 11:10 UTC 57e4d6872fe5786220d23aa4781ff33af65ffeaa
1 file changed +60 -19
scripts/merge-fork/replace-fork.js
+60 -19
@@ -4,9 +4,10 @@
4
5 // Copies the contents of the new fork into the old fork
6
7 +const chalk = require('chalk');
8 const {promisify} = require('util');
9 const glob = promisify(require('glob'));
9 -const {spawnSync} = require('child_process');
10 +const {execSync, spawnSync} = require('child_process');
11 const fs = require('fs');
12 const minimist = require('minimist');
13
@@ -18,31 +19,71 @@ const argv = minimist(process.argv.slice(2), {
19 });
20
21 async function main() {
22 + const status = execSync('git status').toString();
23 + const hadUnstagedChanges = status.includes('Changes not staged for commit');
24 + if (hadUnstagedChanges) {
25 + const readline = require('readline');
26 + const rl = readline.createInterface({
27 + input: process.stdin,
28 + output: process.stdout,
29 + });
30 +
31 + await new Promise(resolve => {
32 + rl.question(
33 + `\n${chalk.yellow.bold(
34 + 'Unstaged changes were found in repository.'
35 + )} Do you want to continue? (Y/n) `,
36 + input => {
37 + switch (input.trim().toLowerCase()) {
38 + case '':
39 + case 'y':
40 + case 'yes':
41 + resolve();
42 + break;
43 + default:
44 + console.log('No modifications were made.');
45 + process.exit(0);
46 + break;
47 + }
48 + }
49 + );
50 + });
51 + }
52 +
53 const oldFilenames = await glob('packages/react-reconciler/**/*.old.js');
54 await Promise.all(oldFilenames.map(unforkFile));
55
56 // Use ESLint to autofix imports
25 - spawnSync('yarn', ['linc', '--fix'], {
57 + const command = spawnSync('yarn', ['linc', '--fix'], {
58 stdio: ['inherit', 'inherit', 'pipe'],
59 });
28 - // TODO: If eslint crashes, it may not have successfully fixed all
29 - // the imports, which would leave the reconciler files in an inconsistent
30 - // state. So we used to crash and reset the working directory. But that
31 - // solution assumed that the working directory was clean before you run the
32 - // command — if it wasn't, it'll not only reset the synced reconciler files,
33 - // but all the other uncommitted changes.
34 - //
35 - // We need a different strategy to prevent loss of work. For example, we could
36 - // exit early if the working directory is not clean before you run the script.
37 - //
38 - // Until we think of something better, I've commmented out this branch to
39 - // prevent work from accidentally being lost.
40 - // if (spawn.stderr.toString() !== '') {
41 - // spawnSync('git', ['checkout', '.']);
60 + if (command.status === 1) {
61 + console.log(
62 + chalk.bold.red('\nreplace-fork script failed with the following error:')
63 + );
64 + console.error(Error(command.stderr));
65
43 - // console.log(Error(spawn.stderr));
44 - // process.exitCode = 1;
45 - // }
66 + // If eslint crashes, it may not have successfully fixed all the imports,
67 + // which would leave the reconciler files in an inconsistent stat.
68 + // It would be nice to clean up the working directory in this case,
69 + // but it's only safe to do that if we aren't going to override any previous changes.
70 + if (!hadUnstagedChanges) {
71 + spawnSync('git', ['checkout', '.']);
72 + } else {
73 + console.log(
74 + `\n${chalk.yellow.bold(
75 + 'Unstaged changes were present when `replace-fork` was run.'
76 + )} ` +
77 + `To cleanup the repository run:\n ${chalk.bold(
78 + 'git checkout packages/react-reconciler'
79 + )}`
80 + );
81 + }
82 +
83 + process.exit(1);
84 + } else {
85 + process.exit(0);
86 + }
87 }
88
89 async function unforkFile(oldFilename) {