Skip to content

Commit de7b452

Browse files
committed
Add isGlobalDeprecated for better --global handling (#1144)
1 parent 92c4aa7 commit de7b452

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

src/package-managers/npm.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ const readNpmConfig = () => {
8686

8787
const npmConfig = readNpmConfig()
8888

89+
/** A promise that returns true if --global is deprecated on the system npm. Spawns "npm --version". */
90+
const isGlobalDeprecated = new Promise((resolve, reject) => {
91+
const cmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'
92+
return spawn(cmd, ['--version'])
93+
.then((output: string) => {
94+
const npmVersion = output.trim()
95+
// --global was deprecated in npm v8.11.0.
96+
resolve(semver.valid(npmVersion) && semver.gte(npmVersion, '8.11.0'))
97+
})
98+
.catch(reject)
99+
})
100+
89101
/**
90102
* @typedef {object} CommandAndPackageName
91103
* @property {string} command
@@ -245,19 +257,29 @@ function filterPredicate(options: Options): (o: Packument) => boolean {
245257
}
246258

247259
/**
248-
* Spawn npm requires a different command on Windows.
260+
* Spawns npm. Handles different commands for Window and Linux/OSX, and automatically converts --location=global to --global on node < 8.11.0.
249261
*
250262
* @param args
251263
* @param [npmOptions={}]
252264
* @param [spawnOptions={}]
253265
* @returns
254266
*/
255-
function spawnNpm(args: string | string[], npmOptions: NpmOptions = {}, spawnOptions: Index<any> = {}): Promise<any> {
267+
async function spawnNpm(
268+
args: string | string[],
269+
npmOptions: NpmOptions = {},
270+
spawnOptions: Index<any> = {},
271+
): Promise<any> {
256272
const cmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'
257273
args = Array.isArray(args) ? args : [args]
258274

259275
const fullArgs = args.concat(
260-
npmOptions.location ? `--location=${npmOptions.location}` : [],
276+
npmOptions.location
277+
? (await isGlobalDeprecated)
278+
? `--location=${npmOptions.location}`
279+
: npmOptions.location === 'global'
280+
? '--global'
281+
: ''
282+
: [],
261283
npmOptions.prefix ? `--prefix=${npmOptions.prefix}` : [],
262284
'--depth=0',
263285
'--json',
@@ -358,6 +380,7 @@ export const list = async (options: Options = {}) => {
358380
const result = await spawnNpm(
359381
'ls',
360382
{
383+
// spawnNpm takes the modern --location option and converts it to --global on older versions of npm
361384
...(options.global ? { location: 'global' } : null),
362385
...(options.prefix ? { prefix: options.prefix } : null),
363386
},

0 commit comments

Comments
 (0)