yogi-cli
Version:
npm 工具包
205 lines (186 loc) • 4.35 kB
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;
delete opts.clone;
repo = normalize(repo);
var url = repo.url || getUrl(repo, clone);
if (clone) {
var cloneOptions = {
checkout: repo.checkout,
shallow: ["main", "master", "vite5x"].includes(repo.checkout),
...opts,
};
gitclone(url, dest, cloneOptions, function (err) {
if (err === undefined) {
rm(dest + "/.git");
fn();
} else {
fn(err);
}
});
} else {
var downloadOptions = {
extract: true,
strip: 1,
mode: "666",
...opts,
headers: {
accept: "application/zip",
...(opts.headers || {}),
},
};
downloadUrl(url, dest, downloadOptions)
.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 directCheckout = match[3] || "main" || "master";
return {
type: "direct",
url: url,
checkout: directCheckout,
};
} else {
regex =
/^(?:(github|gitlab|bitbucket|gitee):)?(?:(.+):)?([^/]+)\/([^#]+)(?:#(.+))?$/;
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] || "main" || "master";
if (origin == null) {
if (type === "github") {
origin = "github.com";
} else if (type === "gitlab") {
origin = "gitlab.com";
} else if (type === "bitbucket") {
origin = "bitbucket.org";
} else if (type === "gitee") {
origin = "gitee.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(repo, clone) {
let origin = repo.origin;
if (!/^(f|ht)tps?:\/\//i.test(origin)) {
// if (clone) {
// origin = "git@" + origin;
// } else {
// origin = "https://" + origin;
// }
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, 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/refs/heads/" +
repo.checkout +
".zip";
} else if (repo.type === "gitlab") {
url =
origin +
repo.owner +
"/" +
repo.name +
"/-/archive/" +
repo.checkout +
"/" +
repo.name +
"-" +
repo.checkout +
".zip";
} else if (repo.type === "bitbucket") {
url =
origin +
repo.owner +
"/" +
repo.name +
"/get/" +
repo.checkout +
".zip";
} else if (repo.type === "gitee") {
url =
origin +
repo.owner +
"/" +
repo.name +
"/repository/archive/" +
repo.checkout +
".zip";
}
}
return url;
}