74 lines
1.8 KiB
JavaScript
74 lines
1.8 KiB
JavaScript
var crypto = require('crypto')
|
|
var resolve = require('path').resolve
|
|
|
|
var lockfile = require('lockfile')
|
|
var log = require('npmlog')
|
|
|
|
var npm = require('../npm.js')
|
|
var correctMkdir = require('../utils/correct-mkdir.js')
|
|
|
|
var installLocks = {}
|
|
|
|
function lockFileName (base, name) {
|
|
var c = name.replace(/[^a-zA-Z0-9]+/g, '-').replace(/^-+|-+$/g, '')
|
|
var p = resolve(base, name)
|
|
var h = crypto.createHash('sha1').update(p).digest('hex')
|
|
var l = resolve(npm.cache, '_locks')
|
|
|
|
return resolve(l, c.substr(0, 24) + '-' + h.substr(0, 16) + '.lock')
|
|
}
|
|
|
|
function lock (base, name, cb) {
|
|
var lockDir = resolve(npm.cache, '_locks')
|
|
correctMkdir(lockDir, function (er) {
|
|
if (er) return cb(er)
|
|
|
|
var opts = {
|
|
stale: npm.config.get('cache-lock-stale'),
|
|
retries: npm.config.get('cache-lock-retries'),
|
|
wait: npm.config.get('cache-lock-wait')
|
|
}
|
|
var lf = lockFileName(base, name)
|
|
lockfile.lock(lf, opts, function (er) {
|
|
if (er) log.warn('locking', lf, 'failed', er)
|
|
|
|
if (!er) {
|
|
log.verbose('lock', 'using', lf, 'for', resolve(base, name))
|
|
installLocks[lf] = true
|
|
}
|
|
|
|
cb(er)
|
|
})
|
|
})
|
|
}
|
|
|
|
function unlock (base, name, cb) {
|
|
var lf = lockFileName(base, name)
|
|
var locked = installLocks[lf]
|
|
if (locked === false) {
|
|
return process.nextTick(cb)
|
|
} else if (locked === true) {
|
|
lockfile.unlock(lf, function (er) {
|
|
if (er) {
|
|
log.warn('unlocking', lf, 'failed', er)
|
|
} else {
|
|
installLocks[lf] = false
|
|
log.verbose('unlock', 'done using', lf, 'for', resolve(base, name))
|
|
}
|
|
|
|
cb(er)
|
|
})
|
|
} else {
|
|
var notLocked = new Error(
|
|
'Attempt to unlock ' + resolve(base, name) + ", which hasn't been locked"
|
|
)
|
|
notLocked.code = 'ENOTLOCKED'
|
|
throw notLocked
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
lock: lock,
|
|
unlock: unlock
|
|
}
|