• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2// try to find the most reasonable prefix to use
3
4module.exports = findPrefix
5
6const fs = require('fs')
7const path = require('path')
8
9function findPrefix (dir) {
10  return new Promise((resolve, reject) => {
11    dir = path.resolve(dir)
12
13    // this is a weird special case where an infinite recurse of
14    // node_modules folders resolves to the level that contains the
15    // very first node_modules folder
16    let walkedUp = false
17    while (path.basename(dir) === 'node_modules') {
18      dir = path.dirname(dir)
19      walkedUp = true
20    }
21    if (walkedUp) {
22      resolve(dir)
23    } else {
24      resolve(findPrefix_(dir))
25    }
26  })
27}
28
29function findPrefix_ (dir, original) {
30  if (!original) original = dir
31
32  const parent = path.dirname(dir)
33  // this is a platform independent way of checking if we're in the root
34  // directory
35  if (parent === dir) return Promise.resolve(original)
36
37  return new Promise((resolve, reject) => {
38    fs.readdir(dir, (err, files) => {
39      if (err) {
40        // an error right away is a bad sign.
41        // unless the prefix was simply a non
42        // existent directory.
43        if (err && dir === original && err.code !== 'ENOENT') {
44          reject(err)
45        } else {
46          resolve(original)
47        }
48      } else if (files.indexOf('node_modules') !== -1 ||
49                 files.indexOf('package.json') !== -1) {
50        resolve(dir)
51      } else {
52        resolve(findPrefix_(parent, original))
53      }
54    })
55  })
56}
57