var common = require('./common'); var fs = require('fs'); var path = require('path'); // XP's system default value for PATHEXT system variable, just in case it's not // set on Windows. var XP_DEFAULT_PATHEXT = '.com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh'; // Cross-platform method for splitting environment PATH variables function splitPath(p) { if (!p) return []; if (common.platform === 'win') return p.split(';'); else return p.split(':'); } function checkPath(path) { return fs.existsSync(path) && !fs.statSync(path).isDirectory(); } //@ //@ ### which(command) //@ //@ Examples: //@ //@ ```javascript //@ var nodeExec = which('node'); //@ ``` //@ //@ Searches for `command` in the system's PATH. On Windows, this uses the //@ `PATHEXT` variable to append the extension if it's not already executable. //@ Returns string containing the absolute path to the command. function _which(options, cmd) { if (!cmd) common.error('must specify command'); var pathEnv = process.env.path || process.env.Path || process.env.PATH, pathArray = splitPath(pathEnv), where = null; // No relative/absolute paths provided? if (cmd.search(/\//) === -1) { // Search for command in PATH pathArray.forEach(function(dir) { if (where) return; // already found it var attempt = path.resolve(dir, cmd); if (common.platform === 'win') { attempt = attempt.toUpperCase(); // In case the PATHEXT variable is somehow not set (e.g. // child_process.spawn with an empty environment), use the XP default. var pathExtEnv = process.env.PATHEXT || XP_DEFAULT_PATHEXT; var pathExtArray = splitPath(pathExtEnv.toUpperCase()); var i; // If the extension is already in PATHEXT, just return that. for (i = 0; i < pathExtArray.length; i++) { var ext = pathExtArray[i]; if (attempt.slice(-ext.length) === ext && checkPath(attempt)) { where = attempt; return; } } // Cycle through the PATHEXT variable var baseAttempt = attempt; for (i = 0; i < pathExtArray.length; i++) { attempt = baseAttempt + pathExtArray[i]; if (checkPath(attempt)) { where = attempt; return; } } } else { // Assume it's Unix-like if (checkPath(attempt)) { where = attempt; return; } } }); } // Command not found anywhere? if (!checkPath(cmd) && !where) return null; where = where || path.resolve(cmd); return common.ShellString(where); } module.exports = _which;