UNPKG

react-native-binary

Version:

CLI commands to cache and reuse React Native binaries

89 lines (74 loc) 2.46 kB
const execa = require('execa'); const fs = require('fs-extra'); const path = require('path'); const crypto = require('crypto'); const exec = (...args) => execa(...args).then(({ stdout }) => stdout); const getPackageVersion = async (pkgDir) => (await fs.readJson(path.join(pkgDir, 'package.json'))).version; const getUncommitedChangesInDir = async (dir) => { const changes = await exec('git', ['status', '--porcelain', '-u', dir]); return changes .split('\n') .map((line) => line.trim().replace(/^(A|M|D|[?]{2}) /, '')) .filter(Boolean); }; const ensureFolderIsHashable = async (dir) => { const changes = await getUncommitedChangesInDir(dir); if (changes.length !== 0) { throw new Error( `Unable to hash folder "${dir}" due to uncommited changes "${changes.join( '", "' )}"` ); } }; const getFolderHash = async (dir) => { await ensureFolderIsHashable(dir); const lsOutput = await exec('git', ['ls-tree', 'HEAD', dir]); const hash = lsOutput.split(/\s/)[2]; if (!hash) { throw new Error(`Unable to hash folder "${dir}"`); } return hash; }; const getNativeDependencyVersions = async (config, platform) => { const dependencies = Object.values(config.dependencies) .filter((dependency) => Boolean(dependency.platforms[platform])) .concat([ { name: 'react-native-binary', root: path.dirname(path.dirname(path.dirname(__dirname))), }, { name: 'react-native', root: config.reactNativePath }, ]); return Promise.all( dependencies.map( async ({ name, root }) => `${name}@${await getPackageVersion(root)}` ) ); }; const getFolderHashes = (config, platform, additionalFolders) => { const project = config.project[platform]; const folders = (additionalFolders || []).concat(project.sourceDir); return Promise.all(folders.map(getFolderHash)); }; const binaryHash = async (_, config, args) => { const { platform, folders } = args; if (!(platform in config.platforms)) { throw new Error( `Invalid platform "${platform}", expected one of ${Object.keys( config.platforms ).join(', ')}` ); } const snippets = await Promise.all([ getNativeDependencyVersions(config, platform), getFolderHashes(config, platform, folders), ]); const hash = crypto .createHash('sha256') .update(snippets.flat().join(';')) .digest('hex'); console.log(hash); }; module.exports = binaryHash;