4
4
5
5
// Copies the contents of the new fork into the old fork
6
6
7
+ const chalk = require ( 'chalk' ) ;
7
8
const { promisify} = require ( 'util' ) ;
8
9
const glob = promisify ( require ( 'glob' ) ) ;
9
- const { spawnSync} = require ( 'child_process' ) ;
10
+ const { execSync , spawnSync} = require ( 'child_process' ) ;
10
11
const fs = require ( 'fs' ) ;
11
12
const minimist = require ( 'minimist' ) ;
12
13
@@ -18,31 +19,71 @@ const argv = minimist(process.argv.slice(2), {
18
19
} ) ;
19
20
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
+
21
53
const oldFilenames = await glob ( 'packages/react-reconciler/**/*.old.js' ) ;
22
54
await Promise . all ( oldFilenames . map ( unforkFile ) ) ;
23
55
24
56
// Use ESLint to autofix imports
25
- spawnSync ( 'yarn' , [ 'linc' , '--fix' ] , {
57
+ const command = spawnSync ( 'yarn' , [ 'linc' , '--fix' ] , {
26
58
stdio : [ 'inherit' , 'inherit' , 'pipe' ] ,
27
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 ) ) ;
42
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
+ }
46
87
}
47
88
48
89
async function unforkFile ( oldFilename ) {
0 commit comments