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