mirror of
https://github.com/bower/bower.git
synced 2026-02-11 22:44:58 -05:00
189 lines
5.1 KiB
JavaScript
189 lines
5.1 KiB
JavaScript
var fs = require('fs');
|
|
var path = require('path');
|
|
var Q = require('q');
|
|
var tmp = require('tmp');
|
|
var mkdirp = require('mkdirp');
|
|
var bowerJson = require('bower-json');
|
|
var pathspec = require('pathspec');
|
|
var rimraf = require('rimraf');
|
|
var glob = require('glob');
|
|
var config = require('../config');
|
|
var createError = require('../util/createError');
|
|
|
|
tmp.setGracefulCleanup();
|
|
|
|
var Resolver = function (source, options) {
|
|
options = options || {};
|
|
|
|
this._source = source;
|
|
this._target = options.target || '*';
|
|
this._name = options.name || this._source;
|
|
this._guessedName = !options.name;
|
|
this._config = options.config || config;
|
|
};
|
|
|
|
// -----------------
|
|
|
|
Resolver.prototype.getSource = function () {
|
|
return this._source;
|
|
};
|
|
|
|
Resolver.prototype.getName = function () {
|
|
return this._name;
|
|
};
|
|
|
|
Resolver.prototype.getTarget = function () {
|
|
return this._target;
|
|
};
|
|
|
|
Resolver.prototype.getTempDir = function () {
|
|
return this._tempDir;
|
|
};
|
|
|
|
Resolver.prototype.hasNew = function (canonicalPkg) {
|
|
return Q.resolve(true);
|
|
};
|
|
|
|
Resolver.prototype.resolve = function () {
|
|
var that = this;
|
|
|
|
// Create temporary dir
|
|
return this._createTempDir()
|
|
// Resolve self
|
|
.then(this._resolveSelf.bind(this))
|
|
// Read json, generating the package meta
|
|
.then(function () {
|
|
return that._readJson(that._tempDir);
|
|
})
|
|
.then(function (meta) {
|
|
return Q.all([
|
|
// Apply package meta
|
|
that._applyPkgMeta(meta),
|
|
// Save package meta
|
|
that._savePkgMeta(meta)
|
|
]);
|
|
})
|
|
.then(function () {
|
|
// Resolve with the folder
|
|
return that._tempDir;
|
|
}, function (err) {
|
|
// If something went wrong, unset the temporary dir
|
|
that._tempDir = null;
|
|
throw err;
|
|
});
|
|
};
|
|
|
|
Resolver.prototype.getPkgMeta = function () {
|
|
return this._pkgMeta;
|
|
};
|
|
|
|
// -----------------
|
|
|
|
// Abstract function that should be implemented by concrete resolvers
|
|
Resolver.prototype._resolveSelf = function () {
|
|
throw new Error('_resolveSelf not implemented');
|
|
};
|
|
|
|
// -----------------
|
|
|
|
Resolver.prototype._createTempDir = function () {
|
|
var baseDir = path.join(tmp.tmpdir, 'bower');
|
|
|
|
return Q.nfcall(mkdirp, baseDir)
|
|
.then(function () {
|
|
return Q.nfcall(tmp.dir, {
|
|
template: path.join(baseDir, this._name + '-XXXXXX'),
|
|
mode: 0777 & ~process.umask(),
|
|
unsafeCleanup: true
|
|
});
|
|
}.bind(this))
|
|
.then(function (dir) {
|
|
this._tempDir = dir;
|
|
return dir;
|
|
}.bind(this));
|
|
};
|
|
|
|
Resolver.prototype._readJson = function (dir) {
|
|
var deferred = Q.defer();
|
|
|
|
Q.nfcall(bowerJson.find, dir)
|
|
.then(function (filename) {
|
|
// If it is a component.json, warn about the deprecation
|
|
if (path.basename(filename) === 'component.json') {
|
|
deferred.notify({
|
|
type: 'warn',
|
|
data: 'Package "' + this._name + '" is using the deprecated component.json file'
|
|
});
|
|
}
|
|
|
|
// Read it
|
|
return Q.nfcall(bowerJson.read, filename)
|
|
.then(null, function (err) {
|
|
throw createError('Something went wrong while 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))
|
|
.then(deferred.resolve, deferred.reject, deferred.notify);
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
Resolver.prototype._applyPkgMeta = function (meta) {
|
|
// Check if name defined in the json is different
|
|
if (meta.name !== this._name) {
|
|
// If so and if the name was "guessed", assume the json name
|
|
if (this._guessedName) {
|
|
this._name = meta.name;
|
|
// Otherwise force the configured one
|
|
} else {
|
|
meta.name = this._name;
|
|
}
|
|
}
|
|
|
|
// Handle ignore property, deleting all files from the temporary directory
|
|
if (meta.ignore && meta.ignore.length) {
|
|
return Q.nfcall(glob, '**/*', { cwd: this._tempDir, dot: true, mark: true })
|
|
.then(function (files) {
|
|
var filter = this._createIgnoreFilter(meta.ignore),
|
|
promises = [];
|
|
|
|
// For each file that passes the ignore filter,
|
|
// rimraf it
|
|
files.forEach(function (file) {
|
|
if (filter(file)) {
|
|
promises.push(Q.nfcall(rimraf, file));
|
|
}
|
|
});
|
|
|
|
// Wait for all the rimraf's to finish
|
|
return Q.all(promises);
|
|
}.bind(this))
|
|
.then(function () {
|
|
return meta;
|
|
});
|
|
}
|
|
|
|
return Q.resolve(meta);
|
|
};
|
|
|
|
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 () {
|
|
return this._pkgMeta = meta;
|
|
}.bind(this));
|
|
};
|
|
|
|
Resolver.prototype._createIgnoreFilter = function (ignore) {
|
|
var list = pathspec.RelPathList.parse(ignore);
|
|
|
|
return function (filename) {
|
|
return list.matches(filename);
|
|
};
|
|
};
|
|
module.exports = Resolver; |