Comparing version 2.1.4 to 2.2.0
#!/usr/bin/env node | ||
"use strict"; | ||
// Configuration | ||
var Config = require("../lib/config"); | ||
var config = new Config(); | ||
var path = require("path"); | ||
var log = require("../lib/log"); | ||
// Set up environment | ||
var Environment = require("../lib/environment"); | ||
var env = new Environment({ | ||
config: config | ||
}); | ||
// Infer if we are global and there is a local version available. | ||
var builderPath = require.resolve("./builder-core"); | ||
var localPath = path.resolve(process.cwd(), "node_modules/builder/bin/builder-core.js"); | ||
// Infer task to run | ||
var Task = require("../lib/task"); | ||
var task = new Task({ | ||
config: config, | ||
env: env | ||
}); | ||
// Swap to local path if different. | ||
if (builderPath !== localPath) { | ||
try { | ||
builderPath = require.resolve(localPath); | ||
log.info("local-detect", "Switched to local builder at: " + localPath); | ||
} catch (err) { | ||
log.warn("local-detect", "Error importing local builder: " + err.message); | ||
log.info("local-detect", "Using global builder at: " + builderPath); | ||
} | ||
} | ||
// Run the task | ||
task.execute(function (err) { | ||
// Import and run. | ||
var builder = require(builderPath); | ||
builder(function (err) { | ||
/*eslint-disable no-process-exit*/ | ||
process.exit(err ? err.code || 1 : 0); | ||
}); |
History | ||
======= | ||
## 2.2.0 | ||
* Global `builder` script detects if local install available and switches to it. | ||
[#10](https://github.com/FormidableLabs/builder/issues/10) | ||
* Add `builder envs` action for concurrent runs based on environment variables. | ||
[#29](https://github.com/FormidableLabs/builder/issues/29) | ||
* Add `builder envs|concurrent --buffer` flag to buffer and display stderr and | ||
stdout at the _end_ of a task run for easier reading of concurrent output. | ||
## 2.1.4 | ||
@@ -5,0 +14,0 @@ |
@@ -22,2 +22,7 @@ "use strict"; | ||
}; | ||
var FLAG_BUFFER = { | ||
desc: "Buffer output until process end (default: `false`)", | ||
types: [Boolean], | ||
default: false | ||
}; | ||
@@ -42,6 +47,13 @@ // Option flags. | ||
queue: FLAG_QUEUE, | ||
buffer: { | ||
desc: "Buffer output until process end (default: `false`)", | ||
types: [Boolean], | ||
default: false | ||
buffer: FLAG_BUFFER | ||
}, | ||
envs: { | ||
tries: FLAG_TRIES, | ||
queue: FLAG_QUEUE, | ||
buffer: FLAG_BUFFER, | ||
"envs-path": { | ||
desc: "Path to JSON env variable array file (default: `null`)", | ||
types: [path], | ||
default: null | ||
} | ||
@@ -48,0 +60,0 @@ } |
@@ -59,2 +59,3 @@ "use strict"; | ||
var tracker = opts.tracker; | ||
var taskEnv = opts.taskEnv; | ||
@@ -80,3 +81,4 @@ // State. | ||
if (error && tries > 0) { | ||
log.warn("proc:retry", chalk.red(tries) + " tries left, Command: " + cmd); | ||
log.warn("proc:retry", chalk.red(tries) + " tries left, Command: " + chalk.gray(cmd) + | ||
(taskEnv ? ", Environment: " + chalk.magenta(JSON.stringify(taskEnv)) : "")); | ||
} | ||
@@ -188,3 +190,37 @@ | ||
}); | ||
}, | ||
/** | ||
* Run a single task with multiple environment variables in parallel. | ||
* | ||
* @param {String} cmd Shell command | ||
* @param {Object} shOpts Shell options | ||
* @param {Object} opts Runner options | ||
* @param {Function} callback Callback `(err)` | ||
* @returns {void} | ||
*/ | ||
envs: function (cmd, shOpts, opts, callback) { | ||
var tracker = new Tracker(); | ||
var queue = opts.queue; | ||
var taskEnvs = opts._envs; | ||
// Get mapper (queue vs. non-queue) | ||
var map = queue ? | ||
async.mapLimit.bind(async, taskEnvs, queue) : | ||
async.map.bind(async, taskEnvs); | ||
log.info("envs", "Starting with queue size: " + chalk.magenta(queue || "unlimited")); | ||
map(function (taskEnv, cb) { | ||
// Add each specific set of environment variables. | ||
var taskShOpts = _.merge({}, shOpts, { env: taskEnv }); | ||
var taskOpts = _.extend({ tracker: tracker, taskEnv: taskEnv }, opts); | ||
log.info("envs", "Starting environment " + chalk.magenta(JSON.stringify(taskEnv)) + | ||
" run for command: " + chalk.gray(cmd)); | ||
retry(cmd, taskShOpts, taskOpts, cb); | ||
}, function (err) { | ||
tracker.kill(); | ||
callback(err); | ||
}); | ||
} | ||
}; |
"use strict"; | ||
var fs = require("fs"); | ||
var path = require("path"); | ||
@@ -46,3 +47,3 @@ var _ = require("lodash"); | ||
Task.prototype.ACTIONS = ["help", "run", "concurrent", "install"]; | ||
Task.prototype.ACTIONS = ["help", "run", "concurrent", "envs"]; | ||
@@ -174,3 +175,63 @@ Task.prototype.toString = function () { | ||
Task.prototype._parseJson = function (objStr) { | ||
try { | ||
return JSON.parse(objStr); | ||
} catch (err) { | ||
log.error(this._action + ":json-obj", "Failed to load JSON object: " + objStr); | ||
throw err; | ||
} | ||
}; | ||
Task.prototype._parseJsonFile = function (filePath) { | ||
try { | ||
return JSON.parse(fs.readFileSync(filePath)); | ||
} catch (err) { | ||
log.error(this._action + ":json-file", "Failed to load JSON file: " + filePath); | ||
throw err; | ||
} | ||
}; | ||
/** | ||
* Run multiple environments. | ||
* | ||
* @param {Function} callback Callback function `(err)` | ||
* @returns {void} | ||
*/ | ||
Task.prototype.envs = function (callback) { | ||
/*eslint max-statements: [2, 20]*/ | ||
// Core setup. | ||
var env = this._env.env; | ||
var task = this.getCommand(this._command); | ||
var flags = args.envs(this.argv); | ||
var opts = _.extend({}, flags); | ||
// Get task environment array. | ||
var envsStr = this._commands[1]; | ||
if (envsStr) { | ||
// Try string on command line first: | ||
// $ builder envs <task> '[{ "FOO": "VAL1" }, { "FOO": "VAL2" }]' | ||
opts._envs = this._parseJson(envsStr); | ||
} else if (opts.envsPath) { | ||
// Try JSON file path next: | ||
// $ builder envs <task> --envs-path=my-environment-vars.json | ||
opts._envs = this._parseJsonFile(opts.envsPath); | ||
} | ||
// Validation | ||
var err; | ||
if (_.isEmpty(opts._envs)) { | ||
err = new Error("Empty/null JSON environments array."); | ||
} else if (!_.isArray(opts._envs)) { | ||
err = new Error("Non-array JSON environments object: " + JSON.stringify(opts._envs)); | ||
} | ||
if (err) { | ||
log.error("envs:json-error", err); | ||
return callback(err); | ||
} | ||
runner.envs(task, { env: env }, opts, callback); | ||
}; | ||
/** | ||
* Execute task or tasks. | ||
@@ -177,0 +238,0 @@ * |
{ | ||
"name": "builder", | ||
"version": "2.1.4", | ||
"version": "2.2.0", | ||
"description": "An NPM-based task runner", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -89,3 +89,13 @@ [![Travis Status][trav_img]][trav_site] | ||
To help you keep up with project-specific builder requirements, a globally- | ||
installed `builder` will detect if a locally-installed version of `builder` is | ||
available and switch to that instead: | ||
``` | ||
$ /GLOBAL/PATH/TO/builder | ||
[builder:local-detect] Switched to local builder at: ./node_modules/builder/bin/builder-core.js | ||
... now using local builder! ... | ||
``` | ||
#### Local Install | ||
@@ -157,3 +167,2 @@ | ||
```sh | ||
@@ -175,2 +184,34 @@ $ builder concurrent <task1> <task2> <task3> | ||
##### builder envs | ||
Run a single task from `script` concurrently for item in an array of different | ||
environment variables. Roughly analogous to: | ||
```sh | ||
$ FOO=VAL1 npm run <task> | FOO=VAL2 npm run <task> | FOO=VAL3 npm run <task> | ||
``` | ||
... but kills all processes on first non-zero exit (which makes it suitable for | ||
test tasks). Usage: | ||
```sh | ||
$ builder envs <task> <json-array> | ||
$ builder envs <task> --envs-path=<path-to-json-file> | ||
``` | ||
Examples: | ||
```sh | ||
$ builder envs <task> '[{ "FOO": "VAL1" }, { "FOO": "VAL2" }, { "ENV1": "VAL3" }]' | ||
$ builder envs <task> '[{ "FOO": "VAL1", "BAR": "VAL2" }, { "FOO": "VAL3" }]' | ||
``` | ||
Flags: | ||
* `--builderrc`: Path to builder config file (default: `.builderrc`) | ||
* `--tries`: Number of times to attempt a task (default: `1`) | ||
* `--queue`: Number of concurrent processes to run (default: unlimited - `0|null`) | ||
* `--[no-]buffer`: Buffer output until process end (default: `false`) | ||
* `--envs-path`: Path to JSON env variable array file (default: `null`) | ||
## Tasks | ||
@@ -391,3 +432,3 @@ | ||
* revise configuration file paths for the moved files | ||
* replace instances of `builder run <TASK>` with `npm run <TASK>` | ||
* replace instances of `builder run <task>` with `npm run <task>` | ||
* for `builder concurrent <task1> <task2>` tasks, first install the | ||
@@ -394,0 +435,0 @@ `concurrently` package and then rewrite to: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
45284
14
851
456
9