mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
Update resolver implementation according to the API, integrate bower-json package.
This commit is contained in:
@@ -5,6 +5,7 @@ var events = require('events');
|
||||
var Q = require('q');
|
||||
var tmp = require('tmp');
|
||||
var mkdirp = require('mkdirp');
|
||||
var bowerJson = require('bower-json');
|
||||
var config = require('../config');
|
||||
var createError = require('../util/createError');
|
||||
|
||||
@@ -34,29 +35,43 @@ Resolver.prototype.getTempDir = function () {
|
||||
return this._tempDir;
|
||||
};
|
||||
|
||||
Resolver.prototype.hasNew = function (canonicalPkg) {
|
||||
return Q.resolve(true);
|
||||
};
|
||||
|
||||
Resolver.prototype.resolve = function () {
|
||||
// Create temporary dir
|
||||
return this._createTempDir()
|
||||
// Resolve self
|
||||
.then(this._resolveSelf.bind(this))
|
||||
// Read json
|
||||
.then(this._readJson.bind(this))
|
||||
// Parse json
|
||||
.then(this._parseJson.bind(this));
|
||||
// Read json, generating the package meta
|
||||
.then(function () {
|
||||
return this._readJson(this._tempDir);
|
||||
}.bind(this))
|
||||
.then(function (meta) {
|
||||
return Q.all([
|
||||
// Apply package meta
|
||||
this._applyPkgMeta(meta),
|
||||
// Save package meta
|
||||
this._savePkgMeta(meta)
|
||||
]);
|
||||
}.bind(this))
|
||||
.then(function () {
|
||||
// Resolve with the folder
|
||||
return this._tempDir;
|
||||
});
|
||||
};
|
||||
|
||||
Resolver.prototype.hasNew = function (oldResolution) {
|
||||
return Q.resolve(true);
|
||||
};
|
||||
|
||||
Resolver.prototype.getDependencies = function () {
|
||||
return this._json.dependencies;
|
||||
Resolver.prototype.getPkgMeta = function () {
|
||||
return this._pkgMeta;
|
||||
};
|
||||
|
||||
// -----------------
|
||||
|
||||
// Abstract function that should be implemented by concrete resolvers
|
||||
Resolver.prototype._resolveSelf = function () {};
|
||||
Resolver.prototype._resolveSelf = function () {
|
||||
throw new Error('_resolveSelf not implemented');
|
||||
};
|
||||
|
||||
// -----------------
|
||||
|
||||
@@ -67,7 +82,7 @@ Resolver.prototype._createTempDir = function () {
|
||||
.then(function () {
|
||||
return Q.nfcall(tmp.dir, {
|
||||
template: path.join(baseDir, this._name + '-XXXXXX'),
|
||||
mode: parseInt('0777', 8) & (~process.umask()),
|
||||
mode: parseInt('0777', 8) & (~process.umask())
|
||||
//unsafeCleanup: true // TODO: don't forget enable this
|
||||
});
|
||||
}.bind(this))
|
||||
@@ -80,60 +95,35 @@ Resolver.prototype._createTempDir = function () {
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Resolver.prototype._readJson = function () {
|
||||
var jsonFile;
|
||||
|
||||
// Try bower.json
|
||||
jsonFile = path.join(this.getTempDir(), 'bower.json');
|
||||
return Q.nfcall(fs.readFile, jsonFile)
|
||||
// Try component.json
|
||||
.then(null, function (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
}
|
||||
|
||||
jsonFile = path.join(this.getTempDir(), 'component.json');
|
||||
return Q.nfcall(fs.readFile, jsonFile)
|
||||
// Issue a deprecation message if it exists
|
||||
.then(function (contents) {
|
||||
Resolver.prototype._readJson = function (dir) {
|
||||
return Q.nfcall(bowerJson.find, dir)
|
||||
.then(function (filename) {
|
||||
// If it is a component.json, warn about the deprecation
|
||||
if (path.basename(filename) === 'component.json') {
|
||||
this.emit('warn', 'Package "' + this.name + '" is using the deprecated component.json file');
|
||||
return contents;
|
||||
}.bind(this));
|
||||
}.bind(this))
|
||||
// If we got the file contents, validate them
|
||||
.then(function (contents) {
|
||||
// TODO: change the validation to a separate module in the bower organization
|
||||
try {
|
||||
this._json = JSON.parse(contents);
|
||||
return this._json;
|
||||
} catch (e) {
|
||||
throw createError('Unable to parse "' + jsonFile + '" file', e.code, {
|
||||
details: e.message
|
||||
});
|
||||
}
|
||||
// Otherwise there was an error
|
||||
}.bind(this), function (err) {
|
||||
// If no json file was found, return one just with the name
|
||||
if (err.code === 'ENOENT') {
|
||||
this._json = { name: this.name };
|
||||
return this._json;
|
||||
}
|
||||
|
||||
// If we got here, the error code is something else so we re-throw it
|
||||
throw err;
|
||||
// Read it
|
||||
return Q.nfcall(bowerJson.read, filename)
|
||||
.then(null, function (err) {
|
||||
throw createError('Something went wrong when reading "' + filename + '"', err.code, {
|
||||
details: err.message
|
||||
});
|
||||
});
|
||||
}.bind(this), function () {
|
||||
// No json file was found, assume one
|
||||
return Q.nfcall(bowerJson.parse, { name: this._name });
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Resolver.prototype._parseJson = function () {
|
||||
Resolver.prototype._applyPkgMeta = function (meta) {
|
||||
// Check if name defined in the json is different
|
||||
// If so and if the name was "guessed", assume the json name
|
||||
if (this._guessedName && this._json.name !== this.name) {
|
||||
this.name = this._json.name;
|
||||
if (this._guessedName && meta.name !== this.name) {
|
||||
this.name = meta.name;
|
||||
this.emit('name_change', this.name);
|
||||
}
|
||||
|
||||
this._json.dependencies = this._json.dependencies || {};
|
||||
|
||||
// Handle ignore property, deleting all files from the temporary directory
|
||||
return Q.fcall(function () {
|
||||
// Delete all the files specified in the ignore from the temporary directory
|
||||
@@ -141,4 +131,12 @@ Resolver.prototype._parseJson = function () {
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Resolver.prototype._savePkgMeta = function (meta) {
|
||||
var contents = JSON.stringify(meta, null, 2);
|
||||
|
||||
return Q.nfcall(fs.writeFile, path.join(this._tempDir, '.bower.json'), contents)
|
||||
.then(function () {
|
||||
this._pkgMeta = meta;
|
||||
}.bind(this));
|
||||
};
|
||||
module.exports = Resolver;
|
||||
@@ -24,37 +24,33 @@ mout.object.mixIn(GitFsResolver, GitResolver);
|
||||
GitFsResolver.prototype._resolveSelf = function () {
|
||||
return this._findResolution()
|
||||
.then(this._copy.bind(this))
|
||||
.then(function () {
|
||||
return this._checkout(this._resolution);
|
||||
}.bind(this));
|
||||
.then(this._checkout.bind(this));
|
||||
};
|
||||
|
||||
// -----------------
|
||||
|
||||
GitFsResolver.prototype._copy = function () {
|
||||
var tempDir = this._tempDir;
|
||||
|
||||
// Copy folder permissions
|
||||
return Q.nfcall(fs.stat, this._source)
|
||||
.then(function (stat) {
|
||||
return Q.nfcall(fs.chmod, tempDir, stat.mode);
|
||||
})
|
||||
return Q.nfcall(fs.chmod, this._tempDir, stat.mode);
|
||||
}.bind(this))
|
||||
// Copy folder contents
|
||||
.then(function () {
|
||||
return Q.nfcall(ncp, this._source, tempDir);
|
||||
return Q.nfcall(ncp, this._source, this._tempDir);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
// Override the checkout function to work with the local copy
|
||||
GitFsResolver.prototype._checkout = function (resolution) {
|
||||
var dir = this._tempDir;
|
||||
GitFsResolver.prototype._checkout = function () {
|
||||
var resolution = this._resolution;
|
||||
|
||||
console.log(resolution);
|
||||
|
||||
// Checkout resolution
|
||||
return cmd('git', ['checkout', '-f', resolution.tag || resolution.branch || resolution.commit], { cwd: dir })
|
||||
return cmd('git', ['checkout', '-f', resolution.tag || resolution.branch || resolution.commit], { cwd: this._tempDir })
|
||||
// Cleanup unstagged files
|
||||
.then(cmd.bind(cmd, 'git', ['clean', '-f', '-d'], { cwd: dir }));
|
||||
.then(cmd.bind(cmd, 'git', ['clean', '-f', '-d'], { cwd: this._tempDir }));
|
||||
};
|
||||
|
||||
// -----------------
|
||||
|
||||
@@ -13,21 +13,21 @@ mout.object.mixIn(GitRemoteResolver, GitResolver);
|
||||
|
||||
// -----------------
|
||||
|
||||
GitRemoteResolver.prototype._checkout = function (resolution) {
|
||||
var dir = this._tempDir,
|
||||
branch;
|
||||
GitRemoteResolver.prototype._checkout = function () {
|
||||
var branch,
|
||||
resolution = this._resolution;
|
||||
|
||||
console.log(resolution);
|
||||
|
||||
// If resolution is a commit, we need to clone the entire repo and checkit out
|
||||
// Because a commit is not a nammed ref, there's no better solution
|
||||
if (resolution.type === 'commit') {
|
||||
return cmd('git', ['clone', this._source, '.'], { cwd: dir })
|
||||
.then(cmd.bind(cmd, 'git', ['checkout', resolution.commit], { cwd: dir }));
|
||||
return cmd('git', ['clone', this._source, this._tempDir])
|
||||
.then(cmd.bind(cmd, 'git', ['checkout', resolution.commit], { cwd: this._tempDir }));
|
||||
// Otherwise we are checking out a named ref so we can optimize it
|
||||
} else {
|
||||
branch = resolution.tag || resolution.branch;
|
||||
return cmd('git', ['clone', this._source, '-b', branch, '--depth', 1, '.'], { cwd: dir });
|
||||
return cmd('git', ['clone', this._source, '-b', branch, '--depth', 1, '.'], { cwd: this._tempDir });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -158,7 +158,6 @@ GitResolver.fetchHeads = function (source) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return heads;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user