@@ -64,19 +64,7 @@ if (process.env.CIRCLE_NODE_TOTAL) {
6464 // will have already removed conflicting files.
6565 //
6666 // In CI, merging is handled automatically by CircleCI's workspace feature.
67- const { error} = spawnSync ( 'rsync' , [
68- '-ar' ,
69- experimentalDir + '/' ,
70- stableDir + '/' ,
71- ] ) ;
72- if ( error !== undefined ) {
73- if ( error . code === 'ENOENT' ) {
74- throw new Error (
75- `${ process . argv [ 1 ] } needs the \`rsync\` CLI installed to work.`
76- ) ;
77- }
78- throw error ;
79- }
67+ mergeDirsSync ( experimentalDir + '/' , stableDir + '/' ) ;
8068
8169 // Now restore the combined directory back to its original name
8270 // TODO: Currently storing artifacts as `./build2` so that it doesn't conflict
@@ -198,3 +186,23 @@ function updateTheReactVersionThatDevToolsReads(version) {
198186 `export default '${ version } ';\n`
199187 ) ;
200188}
189+
190+ /**
191+ * cross-platform alternative to `rsync -ar`
192+ * @param {string } source
193+ * @param {string } destination
194+ */
195+ function mergeDirsSync ( source , destination ) {
196+ for ( const sourceFileBaseName of fs . readdirSync ( source ) ) {
197+ const sourceFileName = path . join ( source , sourceFileBaseName ) ;
198+ const targetFileName = path . join ( destination , sourceFileBaseName ) ;
199+
200+ const sourceFile = fs . statSync ( sourceFileName ) ;
201+ if ( sourceFile . isDirectory ( ) ) {
202+ fse . ensureDirSync ( targetFileName ) ;
203+ mergeDirsSync ( sourceFileName , targetFileName ) ;
204+ } else {
205+ fs . copyFileSync ( sourceFileName , targetFileName ) ;
206+ }
207+ }
208+ }
0 commit comments