jazelle/rules/untar.js (59 lines of code) (raw):

// @flow const { realpathSync: realpath, statSync: stat, readFileSync, existsSync: exists, mkdirSync: mkdir, readdirSync: ls, copyFileSync: cp, } = require('fs'); const {execSync: exec} = require('child_process'); const {dirname, resolve} = require('path'); const root = process.cwd(); const [runtime] = process.argv.slice(2); const options = {cwd: root, encoding: 'utf8', maxBuffer: 1e9}; const files = exec(`find . -name __jazelle__*.tgz`, options) .split('\n') .filter(Boolean); files.map(file => { untarIntoSandbox(file); if (runtime) { copyToSourceFolder(file); } }); function untarIntoSandbox(file) { const target = resolve(root, dirname(file)); const untar = `tar xzf "${file}" -C "${target}"`; exec(untar, {cwd: root}); } function copyToSourceFolder(file) { const target = resolve(root, dirname(file)); const real = dirname(realpath(`${target}/package.json`)); const files = exec(`tar ztf ${file}`, {encoding: 'utf8'}) .trim() .split('\n') .map(line => line.replace(/\/$/, '')); for (const file of files) { copy(target, real, file); } } function copy(target, real, file) { if (stat(`${target}/${file}`).isDirectory()) { const srcPath = `${real}/${file}`; if (!exists(srcPath)) mkdir(srcPath); for (const child of ls(srcPath)) { copy(target, real, `${file}/${child}`); } } else { // only overwrite file if it's not identical if (read(`${target}/${file}`) !== read(`${real}/${file}`)) { cp(`${target}/${file}`, `${real}/${file}`); } } } function read(file) { try { return readFileSync(file, 'utf8'); } catch (e) { return Symbol('not found'); // must return something that does not equal itself } }