/
package-manager.ts
99 lines (92 loc) · 2.79 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
import { execSync } from 'child_process';
import { existsSync } from 'fs';
import { join } from 'path';
export type PackageManager = 'yarn' | 'pnpm' | 'npm';
export interface PackageManagerCommands {
install: string;
add: string;
addDev: string;
addGlobal: string;
rm: string;
exec: string;
list: string;
run: (script: string, args: string) => string;
}
/**
* Detects which package manager is used in the workspace based on the lock file.
*/
export function detectPackageManager(dir: string = ''): PackageManager {
return existsSync(join(dir, 'yarn.lock'))
? 'yarn'
: existsSync(join(dir, 'pnpm-lock.yaml'))
? 'pnpm'
: 'npm';
}
/**
* Returns commands for the package manager used in the workspace.
* By default, the package manager is derived based on the lock file,
* but it can also be passed in explicitly.
*
* Example:
*
* ```javascript
* execSync(`${getPackageManagerCommand().addDev} my-dev-package`);
* ```
*/
export function getPackageManagerCommand(
packageManager: PackageManager = detectPackageManager()
): PackageManagerCommands {
const commands: { [pm in PackageManager]: () => PackageManagerCommands } = {
yarn: () => ({
install: 'yarn',
add: 'yarn add -W',
addDev: 'yarn add -D -W',
addGlobal: 'yarn global add',
rm: 'yarn remove',
exec: 'yarn',
run: (script: string, args: string) => `yarn ${script} ${args}`,
list: 'yarn list',
}),
pnpm: () => {
const [major, minor] = getPackageManagerVersion('pnpm').split('.');
let useExec = false;
if (+major >= 6 && +minor >= 13) {
useExec = true;
}
return {
install: 'pnpm install --no-frozen-lockfile', // explicitly disable in case of CI
add: 'pnpm add',
addDev: 'pnpm add -D',
addGlobal: 'pnpm add -g',
rm: 'pnpm rm',
exec: useExec ? 'pnpm exec' : 'pnpx',
run: (script: string, args: string) => `pnpm run ${script} -- ${args}`,
list: 'pnpm ls --depth 100',
};
},
npm: () => {
process.env.npm_config_legacy_peer_deps ??= 'true';
return {
install: 'npm install',
add: 'npm install',
addDev: 'npm install -D',
addGlobal: 'npm install -g',
rm: 'npm rm',
exec: 'npx',
run: (script: string, args: string) => `npm run ${script} -- ${args}`,
list: 'npm ls',
};
},
};
return commands[packageManager]();
}
/**
* Returns the version of the package manager used in the workspace.
* By default, the package manager is derived based on the lock file,
* but it can also be passed in explicitly.
*/
export function getPackageManagerVersion(
packageManager: PackageManager = detectPackageManager()
): string {
return execSync(`${packageManager} --version`).toString('utf-8').trim();
}