ppl-os/build-tool.js

91 lines
2.8 KiB
JavaScript

#!/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 bool if snap need 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()