// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. 'use strict'; const spawn = require('child_process').spawn, fs = require('fs'), path = require('path'); const isDevMode = require('../devmode'); var projectRoot = path.normalize(path.join(__dirname, '../../../../..')); function checkIsDevMode() { if (!isDevMode) { throw Error('Cannot execute build; not running in dev mode'); } } /** * Targets that have been previously built. * @type {!Object} */ var builtTargets = {}; /** * @param {!Array.} targets The targets to build. * @throws {Error} If not running in dev mode. * @constructor */ var Build = function(targets) { checkIsDevMode(); this.targets_ = targets; }; /** @private {boolean} */ Build.prototype.cacheResults_ = false; /** * Configures this build to only execute if it has not previously been * run during the life of the current process. * @return {!Build} A self reference. */ Build.prototype.onlyOnce = function() { this.cacheResults_ = true; return this; }; /** * Executes the build. * @return {!Promise} A promise that will be resolved when * the build has completed. * @throws {Error} If no targets were specified. */ Build.prototype.go = function() { var targets = this.targets_; if (!targets.length) { throw Error('No targets specified'); } // Filter out cached results. if (this.cacheResults_) { targets = targets.filter(function(target) { return !builtTargets.hasOwnProperty(target); }); if (!targets.length) { return Promise.resolve(); } } console.log('\nBuilding', targets.join(' '), '...'); var cmd, args = targets; if (process.platform === 'win32') { cmd = 'cmd.exe'; args.unshift('/c', path.join(projectRoot, 'go.bat')); } else { cmd = path.join(projectRoot, 'go'); } return new Promise((resolve, reject) => { spawn(cmd, args, { cwd: projectRoot, env: process.env, stdio: ['ignore', process.stdout, process.stderr] }).on('exit', function(code, signal) { if (code === 0) { targets.forEach(function(target) { builtTargets[target] = 1; }); return resolve(); } var msg = 'Unable to build artifacts'; if (code) { // May be null. msg += '; code=' + code; } if (signal) { msg += '; signal=' + signal; } reject(Error(msg)); }); }); }; // PUBLIC API /** * Creates a build of the listed targets. * @param {...string} var_args The targets to build. * @return {!Build} The new build. * @throws {Error} If not running in dev mode. */ exports.of = function(var_args) { var targets = Array.prototype.slice.call(arguments, 0); return new Build(targets); }; /** * @return {string} Absolute path of the project's root directory. * @throws {Error} If not running in dev mode. */ exports.projectRoot = function() { checkIsDevMode(); return projectRoot; };