@@ -18,6 +18,7 @@ const TerminalAdapter = require('yeoman-environment/lib/adapter');
18
18
const log = require ( 'npmlog' ) ;
19
19
const rimraf = require ( 'rimraf' ) ;
20
20
const semver = require ( 'semver' ) ;
21
+ const yarn = require ( './yarn' ) ;
21
22
22
23
const {
23
24
checkDeclaredVersion,
@@ -31,8 +32,7 @@ log.heading = 'git-upgrade';
31
32
32
33
/**
33
34
* Promisify the callback-based shelljs function exec
34
- * @param command
35
- * @param logOutput
35
+ * @param logOutput If true, log the stdout of the command.
36
36
* @returns {Promise }
37
37
*/
38
38
function exec ( command , logOutput ) {
@@ -62,42 +62,37 @@ stdout: ${stdout}`));
62
62
} )
63
63
}
64
64
65
- /**
66
- + * Returns two objects:
67
- + * - Parsed node_modules/react-native/package.json
68
- + * - Parsed package.json
69
- + */
70
- function readPackageFiles ( ) {
65
+ function parseJsonFile ( path , useYarn ) {
66
+ const installHint = useYarn ?
67
+ 'Make sure you ran "yarn" and that you are inside a React Native project.' :
68
+ 'Make sure you ran "npm install" and that you are inside a React Native project.' ;
69
+ let fileContents ;
70
+ try {
71
+ fileContents = fs . readFileSync ( path , 'utf8' ) ;
72
+ } catch ( err ) {
73
+ throw new Error ( 'Cannot find "' + path + '". ' + installHint ) ;
74
+ }
75
+ try {
76
+ return JSON . parse ( fileContents ) ;
77
+ } catch ( err ) {
78
+ throw new Error ( 'Cannot parse "' + path + '": ' + err . message ) ;
79
+ }
80
+ }
81
+
82
+ function readPackageFiles ( useYarn ) {
71
83
const reactNativeNodeModulesPakPath = path . resolve (
72
- process . cwd ( ) ,
73
- 'node_modules' ,
74
- 'react-native' ,
75
- 'package.json'
84
+ process . cwd ( ) , 'node_modules' , 'react-native' , 'package.json'
76
85
) ;
77
-
78
86
const reactNodeModulesPakPath = path . resolve (
79
- process . cwd ( ) ,
80
- 'node_modules' ,
81
- 'react' ,
82
- 'package.json'
87
+ process . cwd ( ) , 'node_modules' , 'react' , 'package.json'
83
88
) ;
84
-
85
89
const pakPath = path . resolve (
86
- process . cwd ( ) ,
87
- 'package.json'
90
+ process . cwd ( ) , 'package.json'
88
91
) ;
89
-
90
- try {
91
- const reactNativeNodeModulesPak = JSON . parse ( fs . readFileSync ( reactNativeNodeModulesPakPath , 'utf8' ) ) ;
92
- const reactNodeModulesPak = JSON . parse ( fs . readFileSync ( reactNodeModulesPakPath , 'utf8' ) ) ;
93
- const pak = JSON . parse ( fs . readFileSync ( pakPath , 'utf8' ) ) ;
94
-
95
- return { reactNativeNodeModulesPak, reactNodeModulesPak, pak} ;
96
- } catch ( err ) {
97
- throw new Error (
98
- 'Unable to find one of "' + pakPath + '", "' + rnPakPath + '" or "' + reactPakPath + '". ' +
99
- 'Make sure you ran "npm install" and that you are inside a React Native project.'
100
- )
92
+ return {
93
+ reactNativeNodeModulesPak : parseJsonFile ( reactNativeNodeModulesPakPath ) ,
94
+ reactNodeModulesPak : parseJsonFile ( reactNodeModulesPakPath ) ,
95
+ pak : parseJsonFile ( pakPath )
101
96
}
102
97
}
103
98
@@ -191,6 +186,21 @@ async function checkForUpdates() {
191
186
}
192
187
}
193
188
189
+ /**
190
+ * If true, use yarn instead of the npm client to upgrade the project.
191
+ */
192
+ function shouldUseYarn ( cliArgs , projectDir ) {
193
+ if ( cliArgs && cliArgs . npm ) {
194
+ return false ;
195
+ }
196
+ const yarnVersion = yarn . getYarnVersionIfAvailable ( ) ;
197
+ if ( yarnVersion && yarn . isProjectUsingYarn ( projectDir ) ) {
198
+ log . info ( 'Using yarn ' + yarnVersion ) ;
199
+ return true ;
200
+ }
201
+ return false ;
202
+ }
203
+
194
204
/**
195
205
* @param requestedVersion The version argument, e.g. 'react-native-git-upgrade 0.38'.
196
206
* `undefined` if no argument passed.
@@ -204,8 +214,10 @@ async function run(requestedVersion, cliArgs) {
204
214
try {
205
215
await checkForUpdates ( ) ;
206
216
217
+ const useYarn = shouldUseYarn ( cliArgs , path . resolve ( process . cwd ( ) ) ) ;
218
+
207
219
log . info ( 'Read package.json files' ) ;
208
- const { reactNativeNodeModulesPak, reactNodeModulesPak, pak} = readPackageFiles ( ) ;
220
+ const { reactNativeNodeModulesPak, reactNodeModulesPak, pak} = readPackageFiles ( useYarn ) ;
209
221
const appName = pak . name ;
210
222
const currentVersion = reactNativeNodeModulesPak . version ;
211
223
const currentReactVersion = reactNodeModulesPak . version ;
@@ -218,7 +230,7 @@ async function run(requestedVersion, cliArgs) {
218
230
checkDeclaredVersion ( declaredVersion ) ;
219
231
220
232
log . info ( 'Check matching versions' ) ;
221
- checkMatchingVersions ( currentVersion , declaredVersion ) ;
233
+ checkMatchingVersions ( currentVersion , declaredVersion , useYarn ) ;
222
234
223
235
log . info ( 'Check React peer dependency' ) ;
224
236
checkReactPeerDependency ( currentVersion , declaredReactVersion ) ;
@@ -231,6 +243,8 @@ async function run(requestedVersion, cliArgs) {
231
243
const viewOutput = await exec ( viewCommand , verbose ) . then ( JSON . parse ) ;
232
244
const newVersion = viewOutput . version ;
233
245
const newReactVersionRange = viewOutput [ 'peerDependencies.react' ] ;
246
+ // Print which versions we're upgrading to
247
+ log . info ( 'Upgrading to React Native ' + newVersion + ( newReactVersionRange ? ', React ' + newReactVersionRange : '' ) ) ;
234
248
235
249
log . info ( 'Check new version' ) ;
236
250
checkNewVersionValid ( newVersion , requestedVersion ) ;
@@ -264,9 +278,14 @@ async function run(requestedVersion, cliArgs) {
264
278
await exec ( 'git commit -m "Old version" --allow-empty' , verbose ) ;
265
279
266
280
log . info ( 'Install the new version' ) ;
267
- let installCommand = 'npm install --save --color=always' ;
281
+ let installCommand ;
282
+ if ( useYarn ) {
283
+ installCommand = 'yarn add' ;
284
+ } else {
285
+ installCommand = 'npm install --save --color=always' ;
286
+ }
268
287
installCommand += ' react-native@' + newVersion ;
269
- if ( ! semver . satisfies ( currentReactVersion , newReactVersionRange ) ) {
288
+ if ( newReactVersionRange && ! semver . satisfies ( currentReactVersion , newReactVersionRange ) ) {
270
289
// Install React as well to avoid unmet peer dependency
271
290
installCommand += ' react@' + newReactVersionRange ;
272
291
}
@@ -296,8 +315,8 @@ async function run(requestedVersion, cliArgs) {
296
315
await exec ( `git apply --3way ${ patchPath } ` , true ) ;
297
316
} catch ( err ) {
298
317
log . warn (
299
- 'The upgrade process succeeded but there might be conflicts to be resolved.\n ' +
300
- 'See above for the list of files that had merge conflicts.' ) ;
318
+ 'The upgrade process succeeded but there might be conflicts to be resolved. ' +
319
+ 'See above for the list of files that have merge conflicts.' ) ;
301
320
} finally {
302
321
log . info ( 'Upgrade done' ) ;
303
322
if ( cliArgs . verbose ) {
0 commit comments