You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.5 KiB

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