Allow custom commands to be called from the main binary
These commands can be made available in the PATH and will be picked up when running `bolt`. For instance, an executable `bolt-doc` will be ran when running `bolt doc`.
This commit is contained in:
parent
e50f45992c
commit
beac8eb0ac
1 changed files with 49 additions and 2 deletions
|
@ -12,11 +12,59 @@ import { TypeclassDictPassing } from "../passes/TypeclassDictPass"
|
|||
import BoltToC from "../passes/BoltToC"
|
||||
import BoltToJS from "../passes/BoltToJS"
|
||||
import { stripExtension } from "../util"
|
||||
import { sync as which } from "which"
|
||||
import { spawnSync } from "child_process"
|
||||
|
||||
function debug(value: any) {
|
||||
console.error(util.inspect(value, { colors: true, depth: Infinity }));
|
||||
}
|
||||
|
||||
// The positions of all program arguments which are not flags will be parsed
|
||||
// into this structure.
|
||||
const commandIndices = [];
|
||||
|
||||
for (let i = 2; i < process.argv.length; i++) {
|
||||
const arg = process.argv[i];
|
||||
if (!arg.startsWith('-')) {
|
||||
commandIndices.push(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate in reverse over the command indices, such that bolt-self-test-run
|
||||
// gets precedence over bolt-self-test
|
||||
for (let i = commandIndices.length-1; i >= 0; i--) {
|
||||
|
||||
const argvIndex = commandIndices[i];
|
||||
|
||||
// Construct the binary name from the parts of which we stored the locations in `commandIndices`.
|
||||
// Build from the first command up until the command at index `i`
|
||||
const binaryName = 'bolt-' + commandIndices.slice(0, i+1).map(index => process.argv[index]).join('-');
|
||||
|
||||
const binaryPath = which(binaryName, { nothrow: true });
|
||||
|
||||
// Reconstruct the args list without the commands in `binaryName`
|
||||
const argv = [];
|
||||
for (let i = 2; i < argvIndex; i++) {
|
||||
const arg = process.argv[i];
|
||||
if (arg.startsWith('-')) {
|
||||
argv.push(arg);
|
||||
}
|
||||
}
|
||||
for (let i = argvIndex+1; i < process.argv.length; i++) {
|
||||
argv.push(process.argv[i]);
|
||||
}
|
||||
|
||||
// Only execute and return if the command was actually found. Otherwise, try
|
||||
// the other possible commands or execute the default program if this was the
|
||||
// last iteration.
|
||||
if (binaryPath) {
|
||||
const exitCode = spawnSync(binaryPath, argv, { stdio: 'inherit' }).status;
|
||||
process.exit(exitCode || 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const program = new Command();
|
||||
|
||||
program
|
||||
|
@ -25,8 +73,7 @@ program
|
|||
.version('0.0.1')
|
||||
.option('-C, --work-dir', 'Act as if run from this directory', '.');
|
||||
|
||||
program
|
||||
.command('build', 'Build a set of Bolt sources')
|
||||
program.command('build', 'Build a set of Bolt sources')
|
||||
.argument('<file>', 'Path to the Bolt program to compile')
|
||||
.option('--no-typecheck', 'Skip type-checking')
|
||||
.option('--no-emit', 'Do not output compiled files')
|
||||
|
|
Loading…
Reference in a new issue