mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
Merge pull request #1216 from benschwarz/master
Revert 1077, merge 1211
This commit is contained in:
@@ -5,6 +5,7 @@ var Q = require('q');
|
||||
var mkdirp = require('mkdirp');
|
||||
var rimraf = require('rimraf');
|
||||
var LRU = require('lru-cache');
|
||||
var lockFile = require('lockfile');
|
||||
var semver = require('../util/semver');
|
||||
var readJson = require('../util/readJson');
|
||||
var copy = require('../util/copy');
|
||||
@@ -18,6 +19,9 @@ function ResolveCache(config) {
|
||||
// - etc..
|
||||
this._config = config;
|
||||
this._dir = this._config.storage.packages;
|
||||
this._lockDir = this._config.storage.packages;
|
||||
|
||||
mkdirp.sync(this._lockDir);
|
||||
|
||||
// Cache is stored/retrieved statically to ensure singularity
|
||||
// among instances
|
||||
@@ -97,6 +101,7 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) {
|
||||
var sourceId;
|
||||
var release;
|
||||
var dir;
|
||||
var pkgLock;
|
||||
var promise;
|
||||
var that = this;
|
||||
|
||||
@@ -107,57 +112,41 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) {
|
||||
sourceId = md5(pkgMeta._source);
|
||||
release = that._getPkgRelease(pkgMeta);
|
||||
dir = path.join(that._dir, sourceId, release);
|
||||
pkgLock = path.join(that._lockDir, sourceId + '-' + release + '.lock');
|
||||
|
||||
var checkExistingDirectory;
|
||||
var key = 'moving:' + dir;
|
||||
// Check if destination directory exists to prevent issuing lock at all times
|
||||
return Q.nfcall(fs.stat, dir)
|
||||
.fail(function (err) {
|
||||
var lockParams = { wait: 250, retries: 25, stale: 60000 };
|
||||
return Q.nfcall(lockFile.lock, pkgLock, lockParams).then(function () {
|
||||
// Ensure other process didn't start copying files before lock was created
|
||||
return Q.nfcall(fs.stat, dir)
|
||||
.fail(function (err) {
|
||||
// If stat fails, it is expected to return ENOENT
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (! that._cache.has(key)) {
|
||||
// Check if directory exists
|
||||
checkExistingDirectory = Q.nfcall(fs.stat, dir)
|
||||
.then(function () {
|
||||
// If it does exists, remove it
|
||||
return Q.nfcall(rimraf, dir);
|
||||
}, function (err) {
|
||||
// If directory does not exists, ensure its basename
|
||||
// is created
|
||||
if (err.code === 'ENOENT') {
|
||||
return Q.nfcall(mkdirp, path.dirname(dir));
|
||||
}
|
||||
// Create missing directory and copy files there
|
||||
return Q.nfcall(mkdirp, path.dirname(dir)).then(function () {
|
||||
return Q.nfcall(fs.rename, canonicalDir, dir)
|
||||
.fail(function (err) {
|
||||
// If error is EXDEV it means that we are trying to rename
|
||||
// across different drives, so we copy and remove it instead
|
||||
if (err.code !== 'EXDEV') {
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
checkExistingDirectory = new Q();
|
||||
}
|
||||
|
||||
return checkExistingDirectory
|
||||
// Move the canonical to sourceId/target
|
||||
.then(function () {
|
||||
// We store the renaming in cache.
|
||||
var promise;
|
||||
if (that._cache.has(key)) {
|
||||
promise = that._cache.get(key);
|
||||
}
|
||||
else {
|
||||
promise = Q.nfcall(fs.rename, canonicalDir, dir);
|
||||
that._cache.set(key, promise);
|
||||
}
|
||||
|
||||
return promise
|
||||
.fail(function (err) {
|
||||
// If error is EXDEV it means that we are trying to rename
|
||||
// across different drives, so we copy and remove it instead
|
||||
if (err.code !== 'EXDEV') {
|
||||
throw err;
|
||||
}
|
||||
|
||||
return copy.copyDir(canonicalDir, dir);
|
||||
})
|
||||
// To match all case, we remove the directory.
|
||||
.then(function () {
|
||||
return Q.nfcall(rimraf, canonicalDir);
|
||||
return copy.copyDir(canonicalDir, dir);
|
||||
});
|
||||
});
|
||||
});
|
||||
}).finally(function () {
|
||||
lockFile.unlockSync(pkgLock);
|
||||
});
|
||||
}).finally(function () {
|
||||
// Ensure no tmp dir is left on disk.
|
||||
return Q.nfcall(rimraf, canonicalDir);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
@@ -58,7 +58,8 @@
|
||||
"p-throttler": "~0.0.1",
|
||||
"insight": "~0.3.0",
|
||||
"is-root": "~0.1.0",
|
||||
"shell-quote": "~1.4.1"
|
||||
"shell-quote": "~1.4.1",
|
||||
"lockfile": "~0.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expect.js": "~0.2.0",
|
||||
|
||||
@@ -138,30 +138,6 @@ describe('ResolveCache', function () {
|
||||
.done();
|
||||
});
|
||||
|
||||
it('should overwrite if the exact same package source/version exists', function (next) {
|
||||
var cachePkgDir = path.join(cacheDir, md5('foo'), '1.0.0-rc.blehhh');
|
||||
|
||||
mkdirp.sync(cachePkgDir);
|
||||
fs.writeFileSync(path.join(cachePkgDir, '_bleh'), 'w00t');
|
||||
|
||||
resolveCache.store(tempPackage, {
|
||||
name: 'foo',
|
||||
version: '1.0.0-rc.blehhh',
|
||||
_source: 'foo',
|
||||
_target: '*'
|
||||
})
|
||||
.then(function (dir) {
|
||||
expect(dir).to.equal(cachePkgDir);
|
||||
expect(fs.existsSync(dir)).to.be(true);
|
||||
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
||||
expect(fs.existsSync(tempPackage)).to.be(false);
|
||||
expect(fs.existsSync(path.join(cachePkgDir, '_bleh'))).to.be(false);
|
||||
|
||||
next();
|
||||
})
|
||||
.done();
|
||||
});
|
||||
|
||||
it('should read the package meta if not present', function (next) {
|
||||
var pkgMeta = path.join(tempPackage, '.bower.json');
|
||||
|
||||
@@ -241,14 +217,14 @@ describe('ResolveCache', function () {
|
||||
|
||||
resolveCache.store(tempPackage, {
|
||||
name: 'foo',
|
||||
_source: 'foo',
|
||||
_source: 'foobar',
|
||||
_target: 'some-branch'
|
||||
})
|
||||
.then(function (dir) {
|
||||
// Ensure mock was called
|
||||
expect(hittedMock).to.be(true);
|
||||
|
||||
expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'some-branch'));
|
||||
expect(dir).to.equal(path.join(cacheDir, md5('foobar'), 'some-branch'));
|
||||
expect(fs.existsSync(dir)).to.be(true);
|
||||
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
||||
expect(fs.existsSync(tempPackage)).to.be(false);
|
||||
|
||||
Reference in New Issue
Block a user