@@ -14,8 +14,9 @@ type FlagsT = {
1414 legacy : boolean ,
1515} ;
1616
17- const rnDiffPurgeUrl =
18- 'https://github.com/react-native-community/rn-diff-purge' ;
17+ const webDiffUrl = 'https://react-native-community.github.io/upgrade-helper' ;
18+ const rawDiffUrl =
19+ 'https://raw.githubusercontent.com/react-native-community/rn-diff-purge/diffs/diffs' ;
1920
2021const getLatestRNVersion = async ( ) : Promise < string > => {
2122 logger. info ( 'No version passed. Fetching latest...' ) ;
@@ -45,9 +46,7 @@ const getPatch = async (currentVersion, newVersion, projectDir) => {
4546 logger . info ( `Fetching diff between v${ currentVersion } and v${ newVersion } ...` ) ;
4647
4748 try {
48- patch = await fetch (
49- `${ rnDiffPurgeUrl } /compare/version/${ currentVersion } ...version/${ newVersion } .diff` ,
50- ) ;
49+ patch = await fetch ( `${ rawDiffUrl } /${ currentVersion } ..${ newVersion } .diff` ) ;
5150 } catch ( error ) {
5251 logger . error (
5352 `Failed to fetch diff for react-native@${ newVersion } . Maybe it's not released yet?` ,
@@ -134,15 +133,17 @@ const applyPatch = async (
134133 newVersion : string ,
135134 tmpPatchFile : string ,
136135) => {
137- let filesToExclude = [ 'package.json' ] ;
136+ const defaultExcludes = [ 'package.json' ] ;
137+ let filesThatDontExist = [ ] ;
138+ let filesThatFailedToApply = [ ] ;
138139 // $FlowFixMe ThenableChildProcess is incompatible with Promise
139140 const { stdout : relativePathFromRoot } = await execa ( 'git' , [
140141 'rev-parse' ,
141142 '--show-prefix' ,
142143 ] ) ;
143144 try {
144145 try {
145- const excludes = filesToExclude . map (
146+ const excludes = defaultExcludes . map (
146147 e => `--exclude=${ path . join ( relativePathFromRoot , e ) } ` ,
147148 ) ;
148149 await execa ( 'git' , [
@@ -160,19 +161,41 @@ const applyPatch = async (
160161 ] ) ;
161162 logger . info ( 'Applying diff...' ) ;
162163 } catch ( error ) {
163- filesToExclude = [
164- ...filesToExclude ,
165- ...error . stderr
166- . split ( '\n' )
164+ const errorLines = error . stderr . split ( '\n' ) ;
165+ filesThatDontExist = [
166+ ...errorLines
167167 . filter ( x => x . includes ( 'does not exist in index' ) )
168168 . map ( x => x . replace ( / ^ e r r o r : ( .* ) : d o e s n o t e x i s t i n i n d e x $ / , '$1' ) ) ,
169169 ] . filter ( Boolean ) ;
170170
171- logger . info ( `Applying diff (excluding: ${ filesToExclude . join ( ', ' ) } )...` ) ;
172- } finally {
173- const excludes = filesToExclude . map (
174- e => `--exclude=${ path . join ( relativePathFromRoot , e ) } ` ,
171+ filesThatFailedToApply = errorLines
172+ . filter ( x => x . includes ( 'patch does not apply' ) )
173+ . map ( x => x . replace ( / ^ e r r o r : ( .* ) : p a t c h d o e s n o t a p p l y $ / , '$1' ) )
174+ . filter ( Boolean ) ;
175+
176+ logger . info ( 'Applying diff...' ) ;
177+ logger . warn (
178+ `Excluding files that exist in the template, but not in your project:\n${ filesThatDontExist
179+ . map ( file => ` - ${ chalk . bold ( file ) } ` )
180+ . join ( '\n' ) } `,
175181 ) ;
182+ if ( filesThatFailedToApply . length ) {
183+ logger . error (
184+ `Excluding files that failed to apply the diff:\n${ filesThatFailedToApply
185+ . map ( file => ` - ${ chalk . bold ( file ) } ` )
186+ . join (
187+ '\n' ,
188+ ) } \nPlease make sure to check the actual changes after the upgrade command is finished.\nYou can find them in our Upgrade Helper web app: ${ chalk . underline . dim (
189+ `${ webDiffUrl } /?from=${ currentVersion } &to=${ newVersion } ` ,
190+ ) } `,
191+ ) ;
192+ }
193+ } finally {
194+ const excludes = [
195+ ...defaultExcludes ,
196+ ...filesThatDontExist ,
197+ ...filesThatFailedToApply ,
198+ ] . map ( e => `--exclude=${ path . join ( relativePathFromRoot , e ) } ` ) ;
176199 await execa ( 'git' , [
177200 'apply' ,
178201 tmpPatchFile ,
@@ -184,9 +207,11 @@ const applyPatch = async (
184207 }
185208 } catch ( error ) {
186209 if ( error . stderr ) {
187- logger . log ( ` ${ chalk . dim ( error . stderr . trim ( ) ) } `) ;
210+ logger . debug ( `"git apply" failed. Error output:\n ${ error . stderr } `) ;
188211 }
189- logger . error ( 'Automatically applying diff failed' ) ;
212+ logger . error (
213+ 'Automatically applying diff failed. We did our best to automatically upgrade as many files as possible' ,
214+ ) ;
190215 return false ;
191216 }
192217 return true ;
@@ -247,7 +272,7 @@ async function upgrade(argv: Array<string>, ctx: ContextT, args: FlagsT) {
247272 if ( ! patchSuccess ) {
248273 if ( stdout ) {
249274 logger . warn (
250- 'Continuing after failure. Most of the files are upgraded but you will need to deal with some conflicts manually' ,
275+ 'Continuing after failure. Some of the files are upgraded but you will need to deal with conflicts manually' ,
251276 ) ;
252277 await installDeps ( newVersion , projectDir ) ;
253278 logger . info ( 'Running "git status" to check what changed...' ) ;
@@ -272,11 +297,11 @@ async function upgrade(argv: Array<string>, ctx: ContextT, args: FlagsT) {
272297• Release notes: ${ chalk . underline . dim (
273298 `https://github.com/facebook/react-native/releases/tag/v${ newVersion } ` ,
274299 ) }
275- • Comparison between versions : ${ chalk . underline . dim (
276- `${ rnDiffPurgeUrl } /compare/version/ ${ currentVersion } ..version/ ${ newVersion } ` ,
300+ • Manual Upgrade Helper : ${ chalk . underline . dim (
301+ `${ webDiffUrl } /?from= ${ currentVersion } &to= ${ newVersion } ` ,
277302 ) }
278303• Git diff: ${ chalk . underline . dim (
279- `${ rnDiffPurgeUrl } /compare/version/ ${ currentVersion } ..version/ ${ newVersion } .diff` ,
304+ `${ rawDiffUrl } / ${ currentVersion } ..${ newVersion } .diff` ,
280305 ) } `) ;
281306
282307 throw new Error (
0 commit comments