git0 0.2.98 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/benchmark/README.md +104 -0
- package/benchmark/report.ts +142 -0
- package/benchmark/tarball-vs-clone.bench.ts +173 -0
- package/dist/cli.js +264 -25
- package/dist/cli.js.map +9 -7
- package/package.json +3 -2
- package/readme.md +120 -1
- package/src/args.ts +58 -0
- package/src/cli.ts +104 -20
- package/src/download.ts +214 -12
- package/src/github-api.ts +108 -2
- package/src/history.ts +225 -0
- package/src/utils.ts +29 -9
- package/test/args.test.ts +44 -0
- package/test/benchmark-report.test.ts +102 -0
- package/test/download-repo.test.ts +178 -0
- package/test/history.test.ts +157 -0
- package/test/parse-target.test.ts +73 -0
- package/test/subpath.test.ts +178 -0
- package/test/utils.test.ts +37 -0
package/dist/cli.js
CHANGED
|
@@ -23601,6 +23601,9 @@ var chalk = createChalk();
|
|
|
23601
23601
|
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
23602
23602
|
var source_default = chalk;
|
|
23603
23603
|
|
|
23604
|
+
// src/cli.ts
|
|
23605
|
+
import path6 from "path";
|
|
23606
|
+
|
|
23604
23607
|
// node_modules/grab-api.js/dist/grab-api.es.js
|
|
23605
23608
|
function log(message = "", options = {}) {
|
|
23606
23609
|
let {
|
|
@@ -27326,11 +27329,60 @@ function getAvailableDirectoryName(basePath) {
|
|
|
27326
27329
|
counter++;
|
|
27327
27330
|
}
|
|
27328
27331
|
}
|
|
27329
|
-
|
|
27332
|
+
function normalizeSubPath(raw) {
|
|
27333
|
+
if (!raw)
|
|
27334
|
+
return "";
|
|
27335
|
+
const segments = raw.replace(/\\/g, "/").split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
27336
|
+
if (segments.includes("..")) {
|
|
27337
|
+
throw new Error(`Invalid path "${raw}" — ".." segments are not allowed.`);
|
|
27338
|
+
}
|
|
27339
|
+
return segments.join("/");
|
|
27340
|
+
}
|
|
27341
|
+
function subPathFilter(subPath) {
|
|
27342
|
+
if (!subPath)
|
|
27343
|
+
return () => true;
|
|
27344
|
+
const prefix = `${subPath}/`;
|
|
27345
|
+
return (entryPath) => {
|
|
27346
|
+
const relative = entryPath.replace(/\\/g, "/").split("/").slice(1).join("/").replace(/\/+$/, "");
|
|
27347
|
+
return relative === subPath || relative.startsWith(prefix);
|
|
27348
|
+
};
|
|
27349
|
+
}
|
|
27350
|
+
function hoistSubPath(extractPath, subPath) {
|
|
27351
|
+
if (!subPath)
|
|
27352
|
+
return;
|
|
27353
|
+
const landed = path2.join(extractPath, subPath);
|
|
27354
|
+
if (!fs2.existsSync(landed)) {
|
|
27355
|
+
throw new Error(`"${subPath}" was not found in this repository — check the path and the branch.`);
|
|
27356
|
+
}
|
|
27357
|
+
const staging = fs2.mkdtempSync(path2.join(path2.dirname(extractPath), ".git0-hoist-"));
|
|
27358
|
+
const parked = path2.join(staging, "payload");
|
|
27359
|
+
try {
|
|
27360
|
+
fs2.renameSync(landed, parked);
|
|
27361
|
+
fs2.rmSync(path2.join(extractPath, subPath.split("/")[0]), { recursive: true, force: true });
|
|
27362
|
+
if (fs2.statSync(parked).isDirectory()) {
|
|
27363
|
+
for (const child of fs2.readdirSync(parked)) {
|
|
27364
|
+
fs2.renameSync(path2.join(parked, child), path2.join(extractPath, child));
|
|
27365
|
+
}
|
|
27366
|
+
} else {
|
|
27367
|
+
fs2.renameSync(parked, path2.join(extractPath, path2.basename(subPath)));
|
|
27368
|
+
}
|
|
27369
|
+
} finally {
|
|
27370
|
+
fs2.rmSync(staging, { recursive: true, force: true });
|
|
27371
|
+
}
|
|
27372
|
+
}
|
|
27373
|
+
function subPathDirName(subPath, type) {
|
|
27374
|
+
if (!subPath)
|
|
27375
|
+
return;
|
|
27376
|
+
const segments = subPath.split("/");
|
|
27377
|
+
if (type === "blob")
|
|
27378
|
+
segments.pop();
|
|
27379
|
+
return segments.pop();
|
|
27380
|
+
}
|
|
27381
|
+
async function streamTarball(res, extractPath, subPath = "") {
|
|
27330
27382
|
const { Readable } = await import("stream");
|
|
27331
27383
|
const nodeStream = Readable.fromWeb(res);
|
|
27332
27384
|
await new Promise((resolve, reject) => {
|
|
27333
|
-
nodeStream.pipe(fo({ C: extractPath, strip: 1 })).on("finish", resolve).on("error", reject);
|
|
27385
|
+
nodeStream.pipe(fo({ C: extractPath, strip: 1, filter: subPathFilter(subPath) })).on("finish", resolve).on("error", reject);
|
|
27334
27386
|
});
|
|
27335
27387
|
}
|
|
27336
27388
|
async function streamToFile(res, dest) {
|
|
@@ -27340,22 +27392,31 @@ async function streamToFile(res, dest) {
|
|
|
27340
27392
|
nodeStream.pipe(fs2.createWriteStream(dest)).on("finish", resolve).on("error", reject);
|
|
27341
27393
|
});
|
|
27342
27394
|
}
|
|
27343
|
-
async function downloadRepo(callGithub, repo, targetDir = null) {
|
|
27395
|
+
async function downloadRepo(callGithub, repo, targetDir = null, options = {}) {
|
|
27344
27396
|
const parsed = import_git_url_parse.default(repo);
|
|
27345
27397
|
if (parsed.owner.includes("/")) {
|
|
27346
27398
|
parsed.owner = parsed.owner.split("/").slice(-1)[0];
|
|
27347
27399
|
}
|
|
27348
|
-
const
|
|
27400
|
+
const subPath = normalizeSubPath(options.subPath);
|
|
27401
|
+
const defaultName = (targetDir?.length ? targetDir : undefined) ?? subPathDirName(subPath, options.subPathType) ?? parsed.name;
|
|
27402
|
+
const defaultDir = path2.resolve(process.cwd(), defaultName);
|
|
27349
27403
|
const extractPath = getAvailableDirectoryName(defaultDir);
|
|
27350
27404
|
fs2.mkdirSync(extractPath, { recursive: true });
|
|
27351
|
-
|
|
27352
|
-
|
|
27405
|
+
const what = subPath ? `${parsed.name}/${subPath}` : parsed.name;
|
|
27406
|
+
console.log(source_default.blue(`\uD83D\uDCE6 Downloading ${what} into ${path2.basename(extractPath)}...`));
|
|
27407
|
+
const requestedRef = options.ref || parsed.ref || "";
|
|
27408
|
+
const defaultBranch = requestedRef || parsed.default_branch || "master";
|
|
27353
27409
|
const tarballUrl = `/repos/${parsed.owner}/${parsed.name}/tarball/${defaultBranch}`;
|
|
27354
|
-
const params = { onStream: (res) => streamTarball(res, extractPath) };
|
|
27410
|
+
const params = { onStream: (res) => streamTarball(res, extractPath, subPath) };
|
|
27355
27411
|
let response = await callGithub(tarballUrl, params);
|
|
27412
|
+
if (response.error && !requestedRef) {
|
|
27413
|
+
response = await callGithub(tarballUrl.replace(/\/master$/, "/main"), params);
|
|
27414
|
+
}
|
|
27356
27415
|
if (response.error) {
|
|
27357
|
-
|
|
27416
|
+
fs2.rmSync(extractPath, { recursive: true, force: true });
|
|
27417
|
+
throw new Error(`Could not download ${parsed.owner}/${parsed.name}${requestedRef ? ` at ${requestedRef}` : ""}: ${response.error}`);
|
|
27358
27418
|
}
|
|
27419
|
+
hoistSubPath(extractPath, subPath);
|
|
27359
27420
|
return extractPath;
|
|
27360
27421
|
}
|
|
27361
27422
|
async function downloadPackage(callGithub, packageURL, downloadPath) {
|
|
@@ -27421,6 +27482,36 @@ function printInstallInstructions(filePath, fileName) {
|
|
|
27421
27482
|
}
|
|
27422
27483
|
|
|
27423
27484
|
// src/github-api.ts
|
|
27485
|
+
function parseTarget(query) {
|
|
27486
|
+
const looksLikeUrl = query.includes("github.com") || query.startsWith("git@github.com:") || query.startsWith("https://") || query.startsWith("git://");
|
|
27487
|
+
if (!looksLikeUrl) {
|
|
27488
|
+
const shorthand = query.match(/^([\w-]+)\/([\w.-]+)(?:\/(.+))?$/);
|
|
27489
|
+
if (!shorthand)
|
|
27490
|
+
return false;
|
|
27491
|
+
const [, owner2, name, subPath = ""] = shorthand;
|
|
27492
|
+
return {
|
|
27493
|
+
owner: owner2,
|
|
27494
|
+
name,
|
|
27495
|
+
href: `https://github.com/${owner2}/${name}`,
|
|
27496
|
+
ref: "",
|
|
27497
|
+
subPath,
|
|
27498
|
+
subPathType: ""
|
|
27499
|
+
};
|
|
27500
|
+
}
|
|
27501
|
+
const parsed = import_git_url_parse2.default(query);
|
|
27502
|
+
if (!parsed?.owner || !parsed?.name)
|
|
27503
|
+
return false;
|
|
27504
|
+
const owner = parsed.owner.includes("/") ? parsed.owner.split("/").slice(-1)[0] : parsed.owner;
|
|
27505
|
+
return {
|
|
27506
|
+
owner,
|
|
27507
|
+
name: parsed.name,
|
|
27508
|
+
href: `https://github.com/${owner}/${parsed.name}`,
|
|
27509
|
+
ref: parsed.ref || "",
|
|
27510
|
+
subPath: parsed.filepath || "",
|
|
27511
|
+
subPathType: parsed.filepathtype || ""
|
|
27512
|
+
};
|
|
27513
|
+
}
|
|
27514
|
+
|
|
27424
27515
|
class GithubAPI {
|
|
27425
27516
|
static DEFAULT_RESULTS_PER_PAGE = 10;
|
|
27426
27517
|
callGithub;
|
|
@@ -27442,8 +27533,8 @@ class GithubAPI {
|
|
|
27442
27533
|
}
|
|
27443
27534
|
});
|
|
27444
27535
|
}
|
|
27445
|
-
async downloadRepo(repo, targetDir = null) {
|
|
27446
|
-
return downloadRepo(this.callGithub, repo, targetDir);
|
|
27536
|
+
async downloadRepo(repo, targetDir = null, options = {}) {
|
|
27537
|
+
return downloadRepo(this.callGithub, repo, targetDir, options);
|
|
27447
27538
|
}
|
|
27448
27539
|
async searchRepositories(query, options = {}) {
|
|
27449
27540
|
const {
|
|
@@ -27484,6 +27575,9 @@ class GithubAPI {
|
|
|
27484
27575
|
async downloadPackage(packageURL, downloadPath) {
|
|
27485
27576
|
return downloadPackage(this.callGithub, packageURL, downloadPath);
|
|
27486
27577
|
}
|
|
27578
|
+
parseTarget(query) {
|
|
27579
|
+
return parseTarget(query);
|
|
27580
|
+
}
|
|
27487
27581
|
parseURL(query) {
|
|
27488
27582
|
if (query.includes("github.com") || query.startsWith("git@github.com:") || query.startsWith("https://") || query.startsWith("git://")) {
|
|
27489
27583
|
return import_git_url_parse2.default(query);
|
|
@@ -27574,7 +27668,11 @@ import fs4 from "fs";
|
|
|
27574
27668
|
|
|
27575
27669
|
// src/utils.ts
|
|
27576
27670
|
import { execSync as execSync2 } from "child_process";
|
|
27671
|
+
var logoPrinted = false;
|
|
27577
27672
|
function printLogo() {
|
|
27673
|
+
if (logoPrinted)
|
|
27674
|
+
return;
|
|
27675
|
+
logoPrinted = true;
|
|
27578
27676
|
console.log(source_default.cyan(` ___
|
|
27579
27677
|
__ _(_)‾|_ / _ \\
|
|
27580
27678
|
/ _ | | __| | | |
|
|
@@ -27716,22 +27814,151 @@ async function showPackageMenu(selectedRepo, downloadPackage2, currentPlatform)
|
|
|
27716
27814
|
await downloadPackage2(selectedPackage.asset.browser_download_url, downloadPath);
|
|
27717
27815
|
}
|
|
27718
27816
|
|
|
27817
|
+
// src/history.ts
|
|
27818
|
+
import { execFile } from "child_process";
|
|
27819
|
+
import fs6 from "fs";
|
|
27820
|
+
import path5 from "path";
|
|
27821
|
+
import { promisify } from "util";
|
|
27822
|
+
var run = promisify(execFile);
|
|
27823
|
+
async function git(args, cwd) {
|
|
27824
|
+
const { stdout } = await run("git", args, { cwd, maxBuffer: 1024 * 1024 * 64 });
|
|
27825
|
+
return stdout.trim();
|
|
27826
|
+
}
|
|
27827
|
+
async function gitAvailable() {
|
|
27828
|
+
try {
|
|
27829
|
+
await git(["--version"]);
|
|
27830
|
+
return true;
|
|
27831
|
+
} catch {
|
|
27832
|
+
return false;
|
|
27833
|
+
}
|
|
27834
|
+
}
|
|
27835
|
+
function assertSafeRemote(url) {
|
|
27836
|
+
if (!/^(https?|git|file):\/\/[^\s]+$/.test(url)) {
|
|
27837
|
+
throw new Error(`Refusing to clone from "${url}" — expected an https:// repository URL.`);
|
|
27838
|
+
}
|
|
27839
|
+
return url;
|
|
27840
|
+
}
|
|
27841
|
+
async function attachGitHistory(extractPath, repoUrl, options = {}) {
|
|
27842
|
+
assertSafeRemote(repoUrl);
|
|
27843
|
+
const gitDir = path5.join(extractPath, ".git");
|
|
27844
|
+
if (fs6.existsSync(gitDir)) {
|
|
27845
|
+
throw new Error(`${gitDir} already exists — not overwriting it.`);
|
|
27846
|
+
}
|
|
27847
|
+
if (!await gitAvailable()) {
|
|
27848
|
+
throw new Error("git is not installed, so the history cannot be downloaded.");
|
|
27849
|
+
}
|
|
27850
|
+
const staging = fs6.mkdtempSync(path5.join(path5.dirname(extractPath), ".git0-history-"));
|
|
27851
|
+
const cloned = path5.join(staging, "repo.git");
|
|
27852
|
+
try {
|
|
27853
|
+
await git(["clone", options.mirror ? "--mirror" : "--bare", "--quiet", repoUrl, cloned]);
|
|
27854
|
+
fs6.renameSync(cloned, gitDir);
|
|
27855
|
+
} catch (error) {
|
|
27856
|
+
fs6.rmSync(staging, { recursive: true, force: true });
|
|
27857
|
+
throw error;
|
|
27858
|
+
}
|
|
27859
|
+
fs6.rmSync(staging, { recursive: true, force: true });
|
|
27860
|
+
await git(["config", "--local", "--bool", "core.bare", "false"], extractPath);
|
|
27861
|
+
await git(["config", "--local", "--bool", "core.logallrefupdates", "true"], extractPath);
|
|
27862
|
+
await git(["config", "--local", "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"], extractPath);
|
|
27863
|
+
await git(["fetch", "--quiet", "origin"], extractPath).catch(() => {});
|
|
27864
|
+
if (options.ref) {
|
|
27865
|
+
await git(["symbolic-ref", "HEAD", `refs/heads/${options.ref}`], extractPath).catch(() => {});
|
|
27866
|
+
}
|
|
27867
|
+
await git(["reset", "--mixed", "--quiet", "HEAD"], extractPath).catch(() => {});
|
|
27868
|
+
return gitDir;
|
|
27869
|
+
}
|
|
27870
|
+
async function cloneHistoryOnly(repoUrl, targetDir, options = {}) {
|
|
27871
|
+
assertSafeRemote(repoUrl);
|
|
27872
|
+
if (fs6.existsSync(targetDir)) {
|
|
27873
|
+
throw new Error(`${targetDir} already exists — not overwriting it.`);
|
|
27874
|
+
}
|
|
27875
|
+
if (!await gitAvailable()) {
|
|
27876
|
+
throw new Error("git is not installed, so the history cannot be downloaded.");
|
|
27877
|
+
}
|
|
27878
|
+
await git(["clone", options.bare ? "--bare" : "--mirror", "--quiet", repoUrl, targetDir]);
|
|
27879
|
+
return targetDir;
|
|
27880
|
+
}
|
|
27881
|
+
function attachGitHistoryLazily(extractPath, repoUrl, options = {}) {
|
|
27882
|
+
console.log(source_default.blue("⏳ Fetching .git history in the background..."));
|
|
27883
|
+
return attachGitHistory(extractPath, repoUrl, options).then(() => {
|
|
27884
|
+
console.log(source_default.green("✅ Git history attached — `git log` is ready."));
|
|
27885
|
+
}, (error) => {
|
|
27886
|
+
console.log(source_default.yellow(`⚠️ Could not attach git history: ${error.message}`));
|
|
27887
|
+
console.log(source_default.gray(" The downloaded source is unaffected."));
|
|
27888
|
+
});
|
|
27889
|
+
}
|
|
27890
|
+
|
|
27891
|
+
// src/args.ts
|
|
27892
|
+
function parseArgs(argv) {
|
|
27893
|
+
const positional = [];
|
|
27894
|
+
const flags = { history: false, historyOnly: false, mirror: false };
|
|
27895
|
+
for (const arg of argv) {
|
|
27896
|
+
if (!arg.startsWith("--")) {
|
|
27897
|
+
positional.push(arg);
|
|
27898
|
+
continue;
|
|
27899
|
+
}
|
|
27900
|
+
const [name, ...rest] = arg.slice(2).split("=");
|
|
27901
|
+
const value = rest.join("=");
|
|
27902
|
+
if (name === "path")
|
|
27903
|
+
flags.path = value;
|
|
27904
|
+
else if (name === "branch" || name === "ref")
|
|
27905
|
+
flags.branch = value;
|
|
27906
|
+
else if (name === "history" || name === "git")
|
|
27907
|
+
flags.history = true;
|
|
27908
|
+
else if (name === "history-only" || name === "git-only")
|
|
27909
|
+
flags.historyOnly = true;
|
|
27910
|
+
else if (name === "mirror")
|
|
27911
|
+
flags.mirror = true;
|
|
27912
|
+
else
|
|
27913
|
+
console.log(source_default.yellow(`Ignoring unknown flag: ${arg}`));
|
|
27914
|
+
}
|
|
27915
|
+
return { positional, flags };
|
|
27916
|
+
}
|
|
27917
|
+
|
|
27719
27918
|
// src/cli.ts
|
|
27720
27919
|
var Github = new github_api_default({ debug: false });
|
|
27721
|
-
async function downloadRepoAndSetup(
|
|
27920
|
+
async function downloadRepoAndSetup(target, folderPath = null, flags = { history: false, historyOnly: false, mirror: false }) {
|
|
27722
27921
|
printLogo();
|
|
27723
|
-
const
|
|
27922
|
+
const ref = flags.branch || target.ref;
|
|
27923
|
+
const extractPath = await Github.downloadRepo(target.href, folderPath, {
|
|
27924
|
+
subPath: flags.path ?? target.subPath,
|
|
27925
|
+
subPathType: flags.path ? "" : target.subPathType,
|
|
27926
|
+
ref
|
|
27927
|
+
});
|
|
27928
|
+
const history = flags.history ? attachGitHistoryLazily(extractPath, target.href, { mirror: flags.mirror, ref }) : Promise.resolve();
|
|
27724
27929
|
setTimeout(() => openInIDE(extractPath), 500);
|
|
27725
27930
|
await installDependencies(extractPath);
|
|
27931
|
+
await history;
|
|
27932
|
+
}
|
|
27933
|
+
async function downloadHistoryOnly(target, flags) {
|
|
27934
|
+
printLogo();
|
|
27935
|
+
const targetDir = getAvailableDirectoryName(path6.resolve(process.cwd(), `${target.name}.git`));
|
|
27936
|
+
console.log(source_default.blue(`\uD83D\uDCE6 Cloning ${target.name} history into ${path6.basename(targetDir)}...`));
|
|
27937
|
+
try {
|
|
27938
|
+
await cloneHistoryOnly(target.href, targetDir, { bare: !flags.mirror });
|
|
27939
|
+
console.log(source_default.green(`✅ History-only clone at ${targetDir}`));
|
|
27940
|
+
console.log(source_default.white(" Read the log without checking anything out:"));
|
|
27941
|
+
console.log(source_default.gray(` git --git-dir="${targetDir}" log --all --oneline`));
|
|
27942
|
+
console.log(source_default.white(" Or restore a working copy from it:"));
|
|
27943
|
+
console.log(source_default.gray(` git clone "${targetDir}" ${target.name}`));
|
|
27944
|
+
} catch (error) {
|
|
27945
|
+
console.error(source_default.red("❌ History clone failed:"), error.message);
|
|
27946
|
+
process.exit(1);
|
|
27947
|
+
}
|
|
27726
27948
|
}
|
|
27727
27949
|
function formatRepoChoice(repo) {
|
|
27728
27950
|
const packageInfo = repo.hasCompatibleReleases ? source_default.green(" \uD83D\uDCE6 Packages available") : repo.hasReleases ? source_default.yellow(" \uD83D\uDCE6 Packages (other platforms)") : "";
|
|
27729
27951
|
return `${source_default.bold(repo.full_name)} - ${source_default.gray(repo.description || "No description")}
|
|
27730
27952
|
` + ` ${source_default.yellow(`★ ${repo.stargazers_count}`)} | ${source_default.blue(repo.language || "Unknown")}${packageInfo}`;
|
|
27731
27953
|
}
|
|
27732
|
-
async function handleRepoDownload(selectedRepo) {
|
|
27954
|
+
async function handleRepoDownload(selectedRepo, flags) {
|
|
27955
|
+
const target = Github.parseTarget(selectedRepo.url);
|
|
27956
|
+
if (!target) {
|
|
27957
|
+
console.log(source_default.yellow(`Could not parse repository URL: ${selectedRepo.url}`));
|
|
27958
|
+
return;
|
|
27959
|
+
}
|
|
27733
27960
|
if (!selectedRepo.hasReleases && !selectedRepo.hasCompatibleReleases) {
|
|
27734
|
-
await downloadRepoAndSetup(
|
|
27961
|
+
await downloadRepoAndSetup(target, null, flags);
|
|
27735
27962
|
return;
|
|
27736
27963
|
}
|
|
27737
27964
|
const { downloadChoice } = await esm_default12.prompt({
|
|
@@ -27748,20 +27975,29 @@ async function handleRepoDownload(selectedRepo) {
|
|
|
27748
27975
|
await showPackageMenu(selectedRepo, Github.downloadPackage.bind(Github), Github.getCurrentPlatform());
|
|
27749
27976
|
}
|
|
27750
27977
|
if (downloadChoice === "source" || downloadChoice === "both") {
|
|
27751
|
-
await downloadRepoAndSetup(
|
|
27978
|
+
await downloadRepoAndSetup(target, null, flags);
|
|
27752
27979
|
}
|
|
27753
27980
|
}
|
|
27754
27981
|
async function main() {
|
|
27755
27982
|
printLogo();
|
|
27756
|
-
const
|
|
27757
|
-
if (!
|
|
27758
|
-
console.log(source_default.yellow("Usage: git0 <github-url | owner/repo | search-query>"));
|
|
27983
|
+
const { positional, flags } = parseArgs(process.argv.slice(2));
|
|
27984
|
+
if (!positional.length) {
|
|
27985
|
+
console.log(source_default.yellow("Usage: git0 <github-url | owner/repo[/path] | search-query>"));
|
|
27986
|
+
console.log(source_default.gray(" --path=<path> download only that folder or file"));
|
|
27987
|
+
console.log(source_default.gray(" --branch=<ref> download a branch, tag or commit"));
|
|
27988
|
+
console.log(source_default.gray(" --history also fetch .git history, in the background"));
|
|
27989
|
+
console.log(source_default.gray(" --history-only clone only the history, no working files"));
|
|
27990
|
+
console.log(source_default.gray(" --mirror keep every ref when cloning history"));
|
|
27759
27991
|
process.exit(1);
|
|
27760
27992
|
}
|
|
27761
|
-
const query =
|
|
27762
|
-
const
|
|
27763
|
-
if (
|
|
27764
|
-
|
|
27993
|
+
const query = positional.join(" ");
|
|
27994
|
+
const target = Github.parseTarget(query);
|
|
27995
|
+
if (target) {
|
|
27996
|
+
if (flags.historyOnly) {
|
|
27997
|
+
await downloadHistoryOnly(target, flags);
|
|
27998
|
+
return;
|
|
27999
|
+
}
|
|
28000
|
+
await downloadRepoAndSetup(target, positional[1] ?? null, flags);
|
|
27765
28001
|
return;
|
|
27766
28002
|
}
|
|
27767
28003
|
const results = await Github.searchRepositories(query);
|
|
@@ -27775,9 +28011,12 @@ async function main() {
|
|
|
27775
28011
|
message: "Select a repository to download:",
|
|
27776
28012
|
choices: results.map((repo) => ({ name: formatRepoChoice(repo), value: repo }))
|
|
27777
28013
|
});
|
|
27778
|
-
await handleRepoDownload(selectedRepo);
|
|
28014
|
+
await handleRepoDownload(selectedRepo, flags);
|
|
27779
28015
|
}
|
|
27780
|
-
main()
|
|
28016
|
+
main().catch((error) => {
|
|
28017
|
+
console.error(source_default.red(`❌ ${error.message}`));
|
|
28018
|
+
process.exit(1);
|
|
28019
|
+
});
|
|
27781
28020
|
|
|
27782
|
-
//# debugId=
|
|
28021
|
+
//# debugId=0AD82F200D77527064756E2164756E21
|
|
27783
28022
|
//# sourceMappingURL=cli.js.map
|