'use strict'; const fs = require('fs'); const path = require('path'); const util = require('util'); const child = require('child_process'); const tmp = require('tmp-promise'); const fsx = require('fs-extra'); const config = require('./config'); const readFile = util.promisify(fs.readFile); function spawn(path, params, ...args) { console.log(`> ${path} ${params.join(' ')}`); const proc = child.spawn(path, params, ...args); proc.promise = new Promise((res, rejraw) => { function rej(e) { rejraw(`${path} ${params.join(' ')}: ${e}`); } proc.on('error', rej); proc.on('exit', (code, sig) => { if(sig) rej('signal: ' + sig); if(code !== 0) rej('code: ' + code); res(); }); }); return proc; } function luaser(obj) { if(Array.isArray(obj)) return `{${obj.map(luaser).join(',')}}`; if(!!obj && typeof obj === 'object' && obj.toString() === '[object Object]') return `{${Object.keys(obj) .map(k => ({ k: /^[A-Za-z_][A-Za-z0-9_]*$/.test(k) ? k : JSON.stringify(k), v: luaser(obj[k]) })) .filter(x => x.v !== 'nil') .map(x => x.k + '=' + x.v)}}`; if(typeof obj === 'number' || typeof obj === 'boolean') return `${obj}`; if(typeof obj === 'string' || obj instanceof String) return JSON.stringify(obj); if(!obj || typeof obj === 'function') return 'nil'; return JSON.stringify(obj.toString()); } module.exports = async () => { const luahook = `config = ${luaser(config)}\n\n` + (await readFile('luahook.lua')) .toString(); const tmpdir = await tmp.dir({ mode: parseInt('700', 8), prefix: 'cdbrelease-' }); try { const git = config.execgit || 'git'; const tar = config.exectar || 'tar'; const lua = config.execlua || 'lua5.1'; const repodir = path.join(tmpdir.path, 'repo'); await spawn(git, [ 'clone', '--bare', '--depth=1', '-b', config.branch, config.fromgit, repodir ], { stdio: 'inherit' }) .promise; const outdir = path.join(tmpdir.path, 'export'); await fsx.emptyDir(outdir); const garch = spawn(git, [ '--git-dir=' + repodir, 'archive', '--format=tar', config.branch ], { stdio: ['inherit', 'pipe', 'inherit'] }); const untar = spawn(tar, [ '-C', outdir, '-xf', '-' ], { stdio: ['pipe', 'inherit', 'inherit'] }); garch.stdout.pipe(untar.stdin); await garch.promise; await untar.promise; let buff = ''; const hook = spawn(lua, ['-'], { stdio: ['pipe', 'pipe', 'inherit'], cwd: outdir }); hook.stdout.on('data', x => buff += x.toString()); hook.stdin.write(luahook); hook.stdin.end(); await hook.promise; const spec = JSON.parse(buff); config.set('fromgit', spec); const scanned = require('./modscan')(outdir); config.set('modscan', scanned); } finally { await fsx.emptyDir(tmpdir.path); await tmpdir.cleanup(); } };