• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const path = require('path');
3const os = require('os');
4const fs = require('fs');
5const ini = require('ini');
6
7const readRc = fp => {
8	try {
9		return ini.parse(fs.readFileSync(fp, 'utf8')).prefix;
10	} catch (err) {}
11};
12
13const defaultNpmPrefix = (() => {
14	if (process.env.PREFIX) {
15		return process.env.PREFIX;
16	}
17
18	if (process.platform === 'win32') {
19		// `c:\node\node.exe` → `prefix=c:\node\`
20		return path.dirname(process.execPath);
21	}
22
23	// `/usr/local/bin/node` → `prefix=/usr/local`
24	return path.dirname(path.dirname(process.execPath));
25})();
26
27const getNpmPrefix = () => {
28	if (process.env.PREFIX) {
29		return process.env.PREFIX;
30	}
31
32	const homePrefix = readRc(path.join(os.homedir(), '.npmrc'));
33	if (homePrefix) {
34		return homePrefix;
35	}
36
37	const globalConfigPrefix = readRc(path.resolve(defaultNpmPrefix, 'etc', 'npmrc'));
38	if (globalConfigPrefix) {
39		return globalConfigPrefix;
40	}
41
42	if (process.platform === 'win32' && process.env.APPDATA) {
43		// Hardcoded contents of `c:\Program Files\nodejs\node_modules\npm\.npmrc`
44		const prefix = path.join(process.env.APPDATA, 'npm');
45		if (fs.existsSync(prefix)) {
46			return prefix;
47		}
48	}
49
50	return defaultNpmPrefix;
51};
52
53const npmPrefix = path.resolve(getNpmPrefix());
54
55const getYarnPrefix = () => {
56	if (process.env.PREFIX) {
57		return process.env.PREFIX;
58	}
59
60	if (process.platform === 'win32' && process.env.LOCALAPPDATA) {
61		const prefix = path.join(process.env.LOCALAPPDATA, 'Yarn');
62		if (fs.existsSync(prefix)) {
63			return prefix;
64		}
65	}
66
67	const configPrefix = path.join(os.homedir(), '.config/yarn');
68	if (fs.existsSync(configPrefix)) {
69		return configPrefix;
70	}
71
72	const homePrefix = path.join(os.homedir(), '.yarn-config');
73	if (fs.existsSync(homePrefix)) {
74		return homePrefix;
75	}
76
77	// Yarn supports the npm conventions but the inverse is not true
78	return npmPrefix;
79};
80
81exports.npm = {};
82exports.npm.prefix = npmPrefix;
83exports.npm.packages = path.join(npmPrefix, process.platform === 'win32' ? 'node_modules' : 'lib/node_modules');
84exports.npm.binaries = process.platform === 'win32' ? npmPrefix : path.join(npmPrefix, 'bin');
85
86const yarnPrefix = path.resolve(getYarnPrefix());
87exports.yarn = {};
88exports.yarn.prefix = yarnPrefix;
89exports.yarn.packages = path.join(yarnPrefix, process.platform === 'win32' ? 'config/global/node_modules' : 'global/node_modules');
90exports.yarn.binaries = path.join(exports.yarn.packages, '.bin');
91