1const { resolve, dirname, delimiter } = require('path') 2// the path here is relative, even though it does not need to be 3// in order to make the posix tests pass in windows 4const nodeGypPath = resolve(__dirname, '../lib/node-gyp-bin') 5 6// Windows typically calls its PATH environ 'Path', but this is not 7// guaranteed, nor is it guaranteed to be the only one. Merge them 8// all together in the order they appear in the object. 9const setPATH = (projectPath, binPaths, env) => { 10 const PATH = Object.keys(env).filter(p => /^path$/i.test(p) && env[p]) 11 .map(p => env[p].split(delimiter)) 12 .reduce((set, p) => set.concat(p.filter(concatted => !set.includes(concatted))), []) 13 .join(delimiter) 14 15 const pathArr = [] 16 if (binPaths) { 17 pathArr.push(...binPaths) 18 } 19 // unshift the ./node_modules/.bin from every folder 20 // walk up until dirname() does nothing, at the root 21 // XXX we should specify a cwd that we don't go above 22 let p = projectPath 23 let pp 24 do { 25 pathArr.push(resolve(p, 'node_modules', '.bin')) 26 pp = p 27 p = dirname(p) 28 } while (p !== pp) 29 pathArr.push(nodeGypPath, PATH) 30 31 const pathVal = pathArr.join(delimiter) 32 33 // XXX include the node-gyp-bin path somehow? Probably better for 34 // npm or arborist or whoever to just provide that by putting it in 35 // the PATH environ, since that's preserved anyway. 36 for (const key of Object.keys(env)) { 37 if (/^path$/i.test(key)) { 38 env[key] = pathVal 39 } 40 } 41 42 return env 43} 44 45module.exports = setPATH 46