#!/usr/bin/env node /* eslint-disable no-console */ 'use strict' const {board, env} = require('yargs').argv require('colors') const fs = require('fs') const path = require('path') const read = (...file) => String(fs.readFileSync(path.join(__dirname, ...file))) const yaml = require('js-yaml') const cp = require('child_process') const JSON5 = require('json5') const mkdir = require('mkdirp').sync const isDev = env === 'dev' const forceBuild = isDev const deps = yaml.safeLoad(read('deps/' + board + '.yaml')) const common = yaml.safeLoad(read('deps/common.yaml')) const boardDef = yaml.safeLoad(read('boards/' + board + '.yaml')) const exec = (cmd, dir, ...args) => new Promise((resolve, reject) => { console.log('$ %s'.bold, [cmd, ...args].map(JSON5.stringify).join(' ')) const p = cp.spawn(cmd, args, {stdio: 'inherit', cwd: dir}) p.once('close', (code, sig) => { if (code || sig) { return reject(new Error('Failed with code/sig: ' + (code || sig))) } resolve() }) }) const execWithOutput = (cmd, ...args) => { const p = cp.spawnSync(cmd, args) if (p.status || p.signal) { throw new Error('Failed with code/sig: ' + (p.status || p.signal)) } return p } async function snapcraft (folder, outFile, targetArch) { await exec('snapcraft', folder, 'snap', '-o', outFile, '--target-arch=' + targetArch) } async function pullOrClone (repo, dest, checkout) { let currentCommit = '' if (fs.existsSync(dest)) { await exec('git', dest, 'remote', 'update', '-p') } else { await exec('git', process.cwd(), 'clone', '--recursive', repo, dest) currentCommit = String(execWithOutput('git', '-C', dest, 'rev-parse', '--verify', 'HEAD').stdout) } await exec('git', dest, 'checkout', checkout) await exec('git', dest, 'submodule', 'init', '.') await exec('git', dest, 'submodule', 'update') let newCommit = String(execWithOutput('git', '-C', dest, 'rev-parse', '--verify', 'HEAD').stdout) return currentCommit !== newCommit // returns true if snap needs recompilation } async function main () { const snaps = Object.assign(deps.snaps, common.snaps) for (const snapName in snaps) { // eslint-disable-line guard-for-in const snap = snaps[snapName] if (snap.mustBuild || forceBuild) { console.log('Building %s...', snapName) let buildFolder = path.join('snaps', board, snapName) mkdir(buildFolder) let sourceFolder = path.join(buildFolder, 'source') let snapFile = path.join(buildFolder, snapName + '.snap') if (await pullOrClone(snap.git, path.join(buildFolder, 'source'), snap.version)) { if (fs.existsSync(snapFile)) { fs.unlinkSync(snapFile) } } if (!fs.existsSync(snapFile)) { await snapcraft(sourceFolder, snapFile, boardDef.architecture) } } } } main().catch(e => { console.error(e.stack) process.exit(1) })