react-native/local-cli/util/copyAndReplace.js
function copyAndReplace(srcPath, destPath, replacements, contentChangedCallback) {
  if (fs.lstatSync(srcPath).isDirectory()) {
    if (!fs.existsSync(destPath)) {
      fs.mkdirSync(destPath);
    }
    // Not recursive
    return;
  }

  const extension = path.extname(srcPath);
  if (binaryExtensions.indexOf(extension) !== -1) {
    // Binary file
    let shouldOverwrite = 'overwrite';
    if (contentChangedCallback) {
      const newContentBuffer = fs.readFileSync(srcPath);
      let contentChanged = 'identical';
      try {
        const origContentBuffer = fs.readFileSync(destPath);
        if (Buffer.compare(origContentBuffer, newContentBuffer) !== 0) {
          contentChanged = 'changed';
        }
      } catch (err) {
        if (err.code === 'ENOENT') {
          contentChanged = 'new';
        } else {
          throw err;
        }
      }
      shouldOverwrite = contentChangedCallback(destPath, contentChanged);
    }
    if (shouldOverwrite === 'overwrite') {
      copyBinaryFile(srcPath, destPath, (err) => {
        if (err) { throw err; }
      });
    }
  } else {
    // Text file
    const srcPermissions = fs.statSync(srcPath).mode;
    let content = fs.readFileSync(srcPath, 'utf8');
    Object.keys(replacements).forEach(regex =>
      content = content.replace(new RegExp(regex, 'g'), replacements[regex])
    );

    let shouldOverwrite = 'overwrite';
    if (contentChangedCallback) {
      // Check if contents changed and ask to overwrite
      let contentChanged = 'identical';
      try {
        const origContent = fs.readFileSync(destPath, 'utf8');
        if (content !== origContent) {
          //console.log('Content changed: ' + destPath);
          contentChanged = 'changed';
        }
      } catch (err) {
        if (err.code === 'ENOENT') {
          contentChanged = 'new';
        } else {
          throw err;
        }
      }
      shouldOverwrite = contentChangedCallback(destPath, contentChanged);
    }
    if (shouldOverwrite === 'overwrite') {
      fs.writeFileSync(destPath, content, {
        encoding: 'utf8',
        mode: srcPermissions,
      });
    }
  }
}
function copyAndReplace(srcPath, destPath, replacements, contentChangedCallback) {
  if (fs.lstatSync(srcPath).isDirectory()) {
    if (!fs.existsSync(destPath)) {
      fs.mkdirSync(destPath);
    }
    // Not recursive
    return;
  }

  const extension = path.extname(srcPath);
  if (binaryExtensions.indexOf(extension) !== -1) {
    // Binary file
    let shouldOverwrite = 'overwrite';
    if (contentChangedCallback) {
      const newContentBuffer = fs.readFileSync(srcPath);
      let contentChanged = 'identical';
      try {
        const origContentBuffer = fs.readFileSync(destPath);
        if (Buffer.compare(origContentBuffer, newContentBuffer) !== 0) {
          contentChanged = 'changed';
        }
      } catch (err) {
        if (err.code === 'ENOENT') {
          contentChanged = 'new';
        } else {
          throw err;
        }
      }
      shouldOverwrite = contentChangedCallback(destPath, contentChanged);
    }
    if (shouldOverwrite === 'overwrite') {
      copyBinaryFile(srcPath, destPath, (err) => {
        if (err) { throw err; }
      });
    }
  } else {
    // Text file
    const srcPermissions = fs.statSync(srcPath).mode;
    let content = fs.readFileSync(srcPath, 'utf8');
    Object.keys(replacements).forEach(regex =>
      content = content.replace(new RegExp(regex, 'g'), replacements[regex])
    );

    let shouldOverwrite = 'overwrite';
    if (contentChangedCallback) {
      // Check if contents changed and ask to overwrite
      let contentChanged = 'identical';
      try {
        const origContent = fs.readFileSync(destPath, 'utf8');
        if (content !== origContent) {
          //console.log('Content changed: ' + destPath);
          contentChanged = 'changed';
        }
      } catch (err) {
        if (err.code === 'ENOENT') {
          contentChanged = 'new';
        } else {
          throw err;
        }
      }
      shouldOverwrite = contentChangedCallback(destPath, contentChanged);
    }
    if (shouldOverwrite === 'overwrite') {
      fs.writeFileSync(destPath, content, {
        encoding: 'utf8',
        mode: srcPermissions,
      });
    }
  }
}
function copyAndReplace ( srcPath , destPath , replacements , contentChangedCallback ) { if ( fs . lstatSync ( srcPath ) . isDirectory ( ) ) { if ( ! fs . existsSync ( destPath ) ) { fs . mkdirSync ( destPath ) ; } // Not recursive return ; } const extension = path . extname ( srcPath ) ; if ( binaryExtensions . indexOf ( extension ) !== - 1 ) { // Binary file let shouldOverwrite = 'overwrite' ; if ( contentChangedCallback ) { const newContentBuffer = fs . readFileSync ( srcPath ) ; let contentChanged = 'identical' ; try { const origContentBuffer = fs . readFileSync ( destPath ) ; if ( Buffer . compare ( origContentBuffer , newContentBuffer ) !== 0 ) { contentChanged = 'changed' ; } } catch ( err ) { if ( err . code === 'ENOENT' ) { contentChanged = 'new' ; } else { throw err ; } } shouldOverwrite = contentChangedCallback ( destPath , contentChanged ) ; } if ( shouldOverwrite === 'overwrite' ) { copyBinaryFile ( srcPath , destPath , ( err ) => { if ( err ) { throw err ; } } ) ; } } else { // Text file const srcPermissions = fs . statSync ( srcPath ) . mode ; let content = fs . readFileSync ( srcPath , 'utf8' ) ; Object . keys ( replacements ) . forEach ( regex => content = content . replace ( new RegExp ( regex , 'g' ) , replacements [ regex ] ) ) ; let shouldOverwrite = 'overwrite' ; if ( contentChangedCallback ) { // Check if contents changed and ask to overwrite let contentChanged = 'identical' ; try { const origContent = fs . readFileSync ( destPath , 'utf8' ) ; if ( content !== origContent ) { //console.log('Content changed: ' + destPath); contentChanged = 'changed' ; } } catch ( err ) { if ( err . code === 'ENOENT' ) { contentChanged = 'new' ; } else { throw err ; } } shouldOverwrite = contentChangedCallback ( destPath , contentChanged ) ; } if ( shouldOverwrite === 'overwrite' ) { fs . writeFileSync ( destPath , content , { encoding : 'utf8' , mode : srcPermissions , } ) ; } } }
Copy a file to given destination, replacing parts of its contents.
@param srcPath Path to a file to be copied.
@param destPath Destination path.
@param replacements: e.g. {'TextToBeReplaced': 'Replacement'}
@param contentChangedCallback
Used when upgrading projects. Based on if file contents would change
when being replaced, allows the caller to specify whether the file
should be replaced or not.
If null, files will be overwritten.
Function(path, 'identical' | 'changed' | 'new') => 'keep' | 'overwrite'
Copy a file to given destination replacing parts of its contents .