mirror of
https://github.com/bower/bower.git
synced 2026-02-12 15:05:05 -05:00
123 lines
4.0 KiB
JavaScript
123 lines
4.0 KiB
JavaScript
var util = require('util');
|
|
var Q = require('q');
|
|
var mout = require('mout');
|
|
var GitResolver = require('./GitResolver');
|
|
var cmd = require('../../util/cmd');
|
|
|
|
function GitRemoteResolver(decEndpoint, config, logger) {
|
|
if (!mout.string.startsWith(decEndpoint.source, 'file://')) {
|
|
// Trim trailing slashes
|
|
decEndpoint.source = decEndpoint.source.replace(/\/+$/, '');
|
|
|
|
// Ensure trailing .git
|
|
if (!mout.string.endsWith(decEndpoint.source, '.git')) {
|
|
decEndpoint.source += '.git';
|
|
}
|
|
}
|
|
|
|
GitResolver.call(this, decEndpoint, config, logger);
|
|
|
|
// If the name was guessed, remove the trailing .git
|
|
if (this._guessedName && mout.string.endsWith(this._name, '.git')) {
|
|
this._name = this._name.slice(0, -4);
|
|
}
|
|
}
|
|
|
|
util.inherits(GitRemoteResolver, GitResolver);
|
|
mout.object.mixIn(GitRemoteResolver, GitResolver);
|
|
|
|
// -----------------
|
|
|
|
GitRemoteResolver.prototype._checkout = function () {
|
|
var branch;
|
|
var promise;
|
|
var timer;
|
|
var that = this;
|
|
var resolution = this._resolution;
|
|
|
|
this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, {
|
|
resolution: resolution,
|
|
to: this._tempDir
|
|
});
|
|
|
|
// If resolution is a commit, we need to clone the entire repo and check it out
|
|
// Because a commit is not a named ref, there's no better solution
|
|
if (resolution.type === 'commit') {
|
|
promise = cmd('git', ['clone', this._source, this._tempDir, '--progress'])
|
|
.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;
|
|
promise = cmd('git', ['clone', this._source, '-b', branch, '--depth', 1, '--progress', '.'], { cwd: this._tempDir })
|
|
.spread(function (stdout, stderr) {
|
|
// Only after 1.7.10 --branch accepts tags
|
|
// Detect those cases and inform the user to update git otherwise it's
|
|
// a lot slower than newer versions
|
|
if (!/branch .+? not found/i.test(stderr)) {
|
|
return;
|
|
}
|
|
|
|
that._logger.warn('old-git', 'It seems you are using an old version of git, it will be slower and propitious to errors!');
|
|
return cmd('git', ['checkout', resolution.commit], { cwd: that._tempDir });
|
|
});
|
|
}
|
|
|
|
// Start reporting progress after a few seconds
|
|
timer = setTimeout(function () {
|
|
promise.progress(function (data) {
|
|
var lines = data.split(/[\r\n]+/);
|
|
|
|
lines.forEach(function (line) {
|
|
if (/\d{1,3}\%/.test(line)) {
|
|
// TODO: There are some strange chars that appear once in a while (\u001b[K)
|
|
// Trim also those?
|
|
that._logger.info('progress', line.trim());
|
|
}
|
|
});
|
|
});
|
|
}, 10000);
|
|
|
|
return promise
|
|
// Clear timer at the end
|
|
.fin(function () {
|
|
clearTimeout(timer);
|
|
});
|
|
};
|
|
|
|
// ------------------------------
|
|
|
|
// Grab refs remotely
|
|
GitRemoteResolver.refs = function (source) {
|
|
var value;
|
|
|
|
// TODO: Normalize source because of the various available protocols?
|
|
value = this._cache.refs.get(source);
|
|
if (value) {
|
|
return Q.resolve(value);
|
|
}
|
|
|
|
// Store the promise in the refs object
|
|
value = cmd('git', ['ls-remote', '--tags', '--heads', source])
|
|
.spread(function (stdout) {
|
|
var refs;
|
|
|
|
refs = stdout.toString()
|
|
.trim() // Trim trailing and leading spaces
|
|
.replace(/[\t ]+/g, ' ') // Standardize spaces (some git versions make tabs, other spaces)
|
|
.split(/[\r\n]+/); // Split lines into an array
|
|
|
|
// Update the refs with the actual refs
|
|
this._cache.refs.set(source, refs);
|
|
|
|
return refs;
|
|
}.bind(this));
|
|
|
|
// Store the promise to be reused until it resolves
|
|
// to a specific value
|
|
this._cache.refs.set(source);
|
|
|
|
return value;
|
|
};
|
|
|
|
module.exports = GitRemoteResolver;
|