#!/usr/bin/env node /** * @license Apache-2.0 * * Copyright (c) 2018 The Stdlib Authors. * * Licensed 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'; // MODULES // var resolve = require( 'path' ).resolve; var spawn = require( 'child_process' ).spawn; var readFileSync = require( './../lib/node_modules/@stdlib/fs/read-file' ).sync; var cwd = require( './../lib/node_modules/@stdlib/process/cwd' ); var ENV = require( './../lib/node_modules/@stdlib/process/env' ); var CLI = require( './../lib/node_modules/@stdlib/tools/cli' ); var getKeys = require( './../lib/node_modules/@stdlib/utils/keys' ); var COMMANDS = require( './cli_commands.json' ); // FUNCTIONS // /** * Callback invoked upon encountering an error while running a command. * * @private * @param {Error} error - error object */ function onError( error ) { process.exitCode = 1; console.error( 'Error: %s', error.message ); // eslint-disable-line no-console } /** * Returns command information. * * @private * @param {string} cmd - command * @returns {(Object|null)} command info */ function findCommand( cmd ) { var i; for ( i = 0; i < COMMANDS.length; i++ ) { if ( cmd === COMMANDS[ i ].command ) { return COMMANDS[ i ]; } } return null; } /** * Resolves a CLI file path. * * @private * @param {string} path - package name/path * @returns {string} file path */ function getPath( path ) { if ( /^@stdlib/.test( path ) ) { // WARNING: we assume that CLIs follow the `./bin/cli` convention return resolve( __dirname, '..', 'lib', 'node_modules', path, 'bin', 'cli' ); } // Assume we are given a path relative to the root directory: return resolve( __dirname, '..', path ); } // MAIN // /** * Main execution sequence. * * @private * @returns {void} */ function main() { var subargs; var flags; var keys; var args; var opts; var proc; var cli; var cmd; var key; var i; // Create a command-line interface: cli = new CLI({ 'pkg': require( './../package.json' ), 'options': require( './cli_opts.json' ), 'help': readFileSync( resolve( __dirname, 'usage.txt' ), { 'encoding': 'utf8' }) }); // Get any provided command-line arguments: args = cli.args(); // Get any provided command-line options: flags = cli.flags(); // Extract the command: if ( args[ 0 ] === 'help' ) { if ( args.length === 1 ) { return cli.help(); } cmd = findCommand( args[ 1 ] ); if ( cmd === null ) { return onError( new Error( 'invalid argument. Unrecognized/unsupported command. Value: `' + args[ 1 ] + '`.' ) ); } subargs = [ getPath( cmd.path ), '--help' ]; } else { cmd = findCommand( args[ 0 ] ); if ( cmd === null ) { return onError( new Error( 'invalid argument. Unrecognized/unsupported command. Value: `' + args[ 0 ] + '`.' ) ); } subargs = [ getPath( cmd.path ) ]; for ( i = 1; i < args.length; i++ ) { subargs.push( args[ i ] ); } keys = getKeys( flags ); for ( i = 0; i < keys.length; i++ ) { key = keys[ i ]; if ( key === 'h' || key === 'help' || key === 'V' || key === 'version' ) { // eslint-disable-line max-len continue; } subargs.push( '--'+keys[ i ]+'='+flags[ keys[ i ] ] ); } } // Define sub-process options: opts = { 'cwd': cwd(), 'env': ENV, 'stdio': 'inherit' }; // Invoke the command in a sub-process: proc = spawn( 'node', subargs, opts ); proc.on( 'error', onError ); } main();