package-manager.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. "use strict";
  2. const path = require("path");
  3. const fs = require("fs");
  4. const spawn = require("cross-spawn");
  5. const SPAWN_FUNCTIONS = {
  6. npm: spawnNPM,
  7. yarn: spawnYarn
  8. };
  9. /**
  10. *
  11. * Spawns a new process using npm
  12. *
  13. * @param {String} pkg - The dependency to be installed
  14. * @param {Boolean} isNew - indicates if it needs to be updated or installed
  15. * @returns {Function} spawn - Installs the package
  16. */
  17. function spawnNPM(pkg, isNew) {
  18. return spawn.sync("npm", [isNew ? "install" : "update", "-g", pkg], {
  19. stdio: "inherit"
  20. });
  21. }
  22. /**
  23. *
  24. * Spawns a new process using yarn
  25. *
  26. * @param {String} pkg - The dependency to be installed
  27. * @param {Boolean} isNew - indicates if it needs to be updated or installed
  28. * @returns {Function} spawn - Installs the package
  29. */
  30. function spawnYarn(pkg, isNew) {
  31. return spawn.sync("yarn", ["global", isNew ? "add" : "upgrade", pkg], {
  32. stdio: "inherit"
  33. });
  34. }
  35. /**
  36. *
  37. * Spawns a new process that installs the addon/dependency
  38. *
  39. * @param {String} pkg - The dependency to be installed
  40. * @returns {Function} spawn - Installs the package
  41. */
  42. function spawnChild(pkg) {
  43. const rootPath = getPathToGlobalPackages();
  44. const pkgPath = path.resolve(rootPath, pkg);
  45. const packageManager = getPackageManager();
  46. const isNew = !fs.existsSync(pkgPath);
  47. return SPAWN_FUNCTIONS[packageManager](pkg, isNew);
  48. }
  49. /**
  50. *
  51. * Returns the name of package manager to use,
  52. * preferring yarn over npm if available
  53. *
  54. * @returns {String} - The package manager name
  55. */
  56. function getPackageManager() {
  57. const hasLocalNPM = fs.existsSync(
  58. path.resolve(process.cwd(), "package-lock.json")
  59. );
  60. const hasLocalYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
  61. if (hasLocalNPM) {
  62. return "npm";
  63. } else if (hasLocalYarn) {
  64. return "yarn";
  65. } else if (spawn.sync("yarn", [" --version"], { stdio: "ignore" }).error) {
  66. return "npm";
  67. } else {
  68. return "yarn";
  69. }
  70. }
  71. /**
  72. *
  73. * Returns the path to globally installed
  74. * npm packages, depending on the available
  75. * package manager determined by `getPackageManager`
  76. *
  77. * @returns {String} path - Path to global node_modules folder
  78. */
  79. function getPathToGlobalPackages() {
  80. const manager = getPackageManager();
  81. if (manager === "yarn") {
  82. try {
  83. const yarnDir = spawn
  84. .sync("yarn", ["global", "dir"])
  85. .stdout.toString()
  86. .trim();
  87. return path.join(yarnDir, "node_modules");
  88. } catch (e) {
  89. // Default to the global npm path below
  90. }
  91. }
  92. return require("global-modules");
  93. }
  94. module.exports = {
  95. getPackageManager,
  96. getPathToGlobalPackages,
  97. spawnChild
  98. };