// 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 fs = require('node:fs')const path = require('node:path')const { spawn } = require('node:child_process')const PROJECT_ROOT = path.normalize(path.join(__dirname, '../../../..'))const WORKSPACE_FILE = path.join(PROJECT_ROOT, 'WORKSPACE')function isDevMode() { return fs.existsSync(WORKSPACE_FILE)}function checkIsDevMode() { if (!isDevMode()) { throw Error('Cannot execute build; not running in dev mode') }}/** * Targets that have been previously built. * @type {!Object} */let builtTargets = {}/** * @param {!Array.<string>} targets The targets to build. * @throws {Error} If not running in dev mode. * @constructor */const 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 () { let targets = this.targets_ if (!targets.length) { throw Error('No targets specified') } // Filter out cached results. if (this.cacheResults_) { targets = targets.filter(function (target) { return !Object.prototype.hasOwnProperty.call(builtTargets, target) }) if (!targets.length) { return Promise.resolve() } } console.log('\nBuilding', targets.join(' '), '...') let cmd, args = targets if (process.platform === 'win32') { cmd = 'cmd.exe' args.unshift('/c', path.join(PROJECT_ROOT, 'go.bat')) } else { cmd = path.join(PROJECT_ROOT, 'go') } return new Promise((resolve, reject) => { spawn(cmd, args, { cwd: PROJECT_ROOT, 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() } let msg = 'Unable to build artifacts' if (code) { // May be null. msg += '; code=' + code } if (signal) { msg += '; signal=' + signal } reject(Error(msg)) }) })}// PUBLIC APIexports.isDevMode = isDevMode/** * 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 (_) { let 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 () { return PROJECT_ROOT}