• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2var path = require('path')
3var log = require('npmlog')
4var validate = require('aproba')
5var uniq = require('lodash.uniq')
6var asyncMap = require('slide').asyncMap
7var npm = require('../npm.js')
8var exists = require('./exists.js')
9var writable = require('./writable.js')
10
11module.exports = function (actions, next) {
12  validate('AF', arguments)
13  var errors = []
14  asyncMap(actions, function (action, done) {
15    var cmd = action[0]
16    var pkg = action[1]
17    switch (cmd) {
18      case 'add':
19        hasAnyWriteAccess(path.resolve(pkg.path, '..'), errors, done)
20        break
21      case 'update':
22      case 'remove':
23        hasWriteAccess(pkg.path, errors, andHasWriteAccess(path.resolve(pkg.path, '..'), errors, done))
24        break
25      case 'move':
26        hasAnyWriteAccess(pkg.path, errors, andHasWriteAccess(path.resolve(pkg.fromPath, '..'), errors, done))
27        break
28      default:
29        done()
30    }
31  }, function () {
32    if (!errors.length) return next()
33    uniq(errors.map(function (er) { return 'Missing write access to ' + er.path })).forEach(function (er) {
34      log.warn('checkPermissions', er)
35    })
36    npm.config.get('force') ? next() : next(errors[0])
37  })
38}
39
40function andHasWriteAccess (dir, errors, done) {
41  validate('SAF', arguments)
42  return function () {
43    hasWriteAccess(dir, errors, done)
44  }
45}
46
47function hasAnyWriteAccess (dir, errors, done) {
48  validate('SAF', arguments)
49  findNearestDir()
50  function findNearestDir () {
51    var nextDir = path.resolve(dir, '..')
52    exists(dir, function (dirDoesntExist) {
53      if (!dirDoesntExist || nextDir === dir) {
54        return hasWriteAccess(dir, errors, done)
55      } else {
56        dir = nextDir
57        findNearestDir()
58      }
59    })
60  }
61}
62
63function hasWriteAccess (dir, errors, done) {
64  validate('SAF', arguments)
65  writable(dir, function (er) {
66    if (er) errors.push(er)
67    done()
68  })
69}
70