1'use strict';
2
3const path = require('path');
4const which = require('which');
5const getPathKey = require('path-key');
6
7function resolveCommandAttempt(parsed, withoutPathExt) {
8    const env = parsed.options.env || process.env;
9    const cwd = process.cwd();
10    const hasCustomCwd = parsed.options.cwd != null;
11    // Worker threads do not have process.chdir()
12    const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
13
14    // If a custom `cwd` was specified, we need to change the process cwd
15    // because `which` will do stat calls but does not support a custom cwd
16    if (shouldSwitchCwd) {
17        try {
18            process.chdir(parsed.options.cwd);
19        } catch (err) {
20            /* Empty */
21        }
22    }
23
24    let resolved;
25
26    try {
27        resolved = which.sync(parsed.command, {
28            path: env[getPathKey({ env })],
29            pathExt: withoutPathExt ? path.delimiter : undefined,
30        });
31    } catch (e) {
32        /* Empty */
33    } finally {
34        if (shouldSwitchCwd) {
35            process.chdir(cwd);
36        }
37    }
38
39    // If we successfully resolved, ensure that an absolute path is returned
40    // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it
41    if (resolved) {
42        resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved);
43    }
44
45    return resolved;
46}
47
48function resolveCommand(parsed) {
49    return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
50}
51
52module.exports = resolveCommand;
53