2018-11-18 16:29:14 +08:00

148 lines
3.1 KiB
JavaScript

var downloadUrl = require('download')
var gitclone = require('git-clone')
var rm = require('rimraf').sync
/**
* Expose `download`.
*/
module.exports = download
/**
* Download `repo` to `dest` and callback `fn(err)`.
*
* @param {String} repo
* @param {String} dest
* @param {Object} opts
* @param {Function} fn
*/
function download (repo, dest, opts, fn) {
if (typeof opts === 'function') {
fn = opts
opts = null
}
opts = opts || {}
var clone = opts.clone || false
repo = normalize(repo)
var url = repo.url || getUrl(repo, clone)
if (clone) {
gitclone(url, dest, { checkout: repo.checkout, shallow: repo.checkout === 'master' }, function (err) {
if (err === undefined) {
rm(dest + '/.git')
fn()
} else {
fn(err)
}
})
} else {
downloadUrl(url, dest, { extract: true, strip: 1, mode: '666', headers: { accept: 'application/zip' } })
.then(function (data) {
fn()
})
.catch(function (err) {
fn(err)
})
}
}
/**
* Normalize a repo string.
*
* @param {String} repo
* @return {Object}
*/
function normalize (repo) {
var regex = /^(?:(direct):([^#]+)(?:#(.+))?)$/
var match = regex.exec(repo)
if (match) {
var url = match[2]
var checkout = match[3] || 'master'
return {
type: 'direct',
url: url,
checkout: checkout
}
} else {
regex = /^(?:(github|gitlab|bitbucket):)?(?:(.+):)?([^\/]+)\/([^#]+)(?:#(.+))?$/
match = regex.exec(repo)
var type = match[1] || 'github'
var origin = match[2] || null
var owner = match[3]
var name = match[4]
var checkout = match[5] || 'master'
if (origin == null) {
if (type === 'github')
origin = 'github.com'
else if (type === 'gitlab')
origin = 'gitlab.com'
else if (type === 'bitbucket')
origin = 'bitbucket.com'
}
return {
type: type,
origin: origin,
owner: owner,
name: name,
checkout: checkout
}
}
}
/**
* Adds protocol to url in none specified
*
* @param {String} url
* @return {String}
*/
function addProtocol (origin, clone) {
if (!/^(f|ht)tps?:\/\//i.test(origin)) {
if (clone)
origin = 'git@' + origin
else
origin = 'https://' + origin
}
return origin
}
/**
* Return a zip or git url for a given `repo`.
*
* @param {Object} repo
* @return {String}
*/
function getUrl (repo, clone) {
var url
// Get origin with protocol and add trailing slash or colon (for ssh)
var origin = addProtocol(repo.origin, clone)
if (/^git\@/i.test(origin))
origin = origin + ':'
else
origin = origin + '/'
// Build url
if (clone) {
url = origin + repo.owner + '/' + repo.name + '.git'
} else {
if (repo.type === 'github')
url = origin + repo.owner + '/' + repo.name + '/archive/' + repo.checkout + '.zip'
else if (repo.type === 'gitlab')
url = origin + repo.owner + '/' + repo.name + '/repository/archive.zip?ref=' + repo.checkout
else if (repo.type === 'bitbucket')
url = origin + repo.owner + '/' + repo.name + '/get/' + repo.checkout + '.zip'
}
return url
}