mirror of
https://github.com/bower/bower.git
synced 2026-01-15 01:08:07 -05:00
146 lines
4.5 KiB
JavaScript
146 lines
4.5 KiB
JavaScript
var util = require('util');
|
|
var path = require('path');
|
|
var mout = require('mout');
|
|
var Q = require('q');
|
|
var GitRemoteResolver = require('./GitRemoteResolver');
|
|
var download = require('../../util/download');
|
|
var extract = require('../../util/extract');
|
|
var createError = require('../../util/createError');
|
|
|
|
function GitHubResolver(decEndpoint, config, logger) {
|
|
var pair;
|
|
|
|
GitRemoteResolver.call(this, decEndpoint, config, logger);
|
|
|
|
// Grab the org/repo
|
|
// /xxxxx/yyyyy.git or :xxxxx/yyyyy.git (.git is optional)
|
|
pair = GitHubResolver.getOrgRepoPair(this._source);
|
|
if (!pair) {
|
|
throw createError('Invalid GitHub URL', 'EINVEND', {
|
|
details: this._source + ' does not seem to be a valid GitHub URL'
|
|
});
|
|
}
|
|
|
|
this._org = pair.org;
|
|
this._repo = pair.repo;
|
|
|
|
// Ensure trailing for all protocols
|
|
if (!mout.string.endsWith(this._source, '.git')) {
|
|
this._source += '.git';
|
|
}
|
|
|
|
// Use https:// rather than git:// if on a proxy
|
|
if (this._config.proxy || this._config.httpsProxy) {
|
|
this._source = this._source.replace('git://', 'https://');
|
|
}
|
|
|
|
// Enable shallow clones for GitHub repos
|
|
this._shallowClone = function () {
|
|
return Q.resolve(true);
|
|
};
|
|
}
|
|
|
|
util.inherits(GitHubResolver, GitRemoteResolver);
|
|
mout.object.mixIn(GitHubResolver, GitRemoteResolver);
|
|
|
|
// -----------------
|
|
|
|
GitHubResolver.prototype._checkout = function () {
|
|
var msg;
|
|
var name = this._resolution.tag || this._resolution.branch || this._resolution.commit;
|
|
var tarballUrl = 'https://github.com/' + this._org + '/' + this._repo + '/archive/' + name + '.tar.gz';
|
|
|
|
var file = path.join(this._tempDir, 'archive.tar.gz');
|
|
var reqHeaders = {};
|
|
var that = this;
|
|
|
|
if (this._config.userAgent) {
|
|
reqHeaders['User-Agent'] = this._config.userAgent;
|
|
}
|
|
|
|
this._logger.action('download', tarballUrl, {
|
|
url: that._source,
|
|
to: file
|
|
});
|
|
|
|
// Download tarball
|
|
return download(tarballUrl, file, {
|
|
ca: this._config.ca.default,
|
|
strictSSL: this._config.strictSsl,
|
|
timeout: this._config.timeout,
|
|
headers: reqHeaders
|
|
})
|
|
.progress(function (state) {
|
|
// Retry?
|
|
if (state.retry) {
|
|
msg = 'Download of ' + tarballUrl + ' failed with ' + state.error.code + ', ';
|
|
msg += 'retrying in ' + (state.delay / 1000).toFixed(1) + 's';
|
|
that._logger.debug('error', state.error.message, { error: state.error });
|
|
return that._logger.warn('retry', msg);
|
|
}
|
|
|
|
// Progress
|
|
msg = 'received ' + (state.received / 1024 / 1024).toFixed(1) + 'MB';
|
|
if (state.total) {
|
|
msg += ' of ' + (state.total / 1024 / 1024).toFixed(1) + 'MB downloaded, ';
|
|
msg += state.percent + '%';
|
|
}
|
|
that._logger.info('progress', msg);
|
|
})
|
|
.then(function () {
|
|
// Extract archive
|
|
that._logger.action('extract', path.basename(file), {
|
|
archive: file,
|
|
to: that._tempDir
|
|
});
|
|
|
|
return extract(file, that._tempDir)
|
|
// Fallback to standard git clone if extraction failed
|
|
.fail(function (err) {
|
|
msg = 'Decompression of ' + path.basename(file) + ' failed' + (err.code ? ' with ' + err.code : '') + ', ';
|
|
msg += 'trying with git..';
|
|
that._logger.debug('error', err.message, { error: err });
|
|
that._logger.warn('retry', msg);
|
|
|
|
return that._cleanTempDir()
|
|
.then(GitRemoteResolver.prototype._checkout.bind(that));
|
|
});
|
|
// Fallback to standard git clone if download failed
|
|
}, function (err) {
|
|
msg = 'Download of ' + tarballUrl + ' failed' + (err.code ? ' with ' + err.code : '') + ', ';
|
|
msg += 'trying with git..';
|
|
that._logger.debug('error', err.message, { error: err });
|
|
that._logger.warn('retry', msg);
|
|
|
|
return that._cleanTempDir()
|
|
.then(GitRemoteResolver.prototype._checkout.bind(that));
|
|
});
|
|
};
|
|
|
|
GitHubResolver.prototype._savePkgMeta = function (meta) {
|
|
// Set homepage if not defined
|
|
if (!meta.homepage) {
|
|
meta.homepage = 'https://github.com/' + this._org + '/' + this._repo;
|
|
}
|
|
|
|
return GitRemoteResolver.prototype._savePkgMeta.call(this, meta);
|
|
};
|
|
|
|
// ----------------
|
|
|
|
GitHubResolver.getOrgRepoPair = function (url) {
|
|
var match;
|
|
|
|
match = url.match(/(?:@|:\/\/)github.com[:\/]([^\/\s]+?)\/([^\/\s]+?)(?:\.git)?\/?$/i);
|
|
if (!match) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
org: match[1],
|
|
repo: match[2]
|
|
};
|
|
};
|
|
|
|
module.exports = GitHubResolver;
|