UNPKG

@cmtlyt/git-down

Version:
4 lines (3 loc) 5.34 kB
#!/usr/bin/env node import{defineCommand as A,runMain as k}from"citty";import{existsSync as s,rmSync as v}from"node:fs";import{extname as q,resolve as F}from"node:path";import{exit as f,stdin as G,stdout as R}from"node:process";import{createInterface as x}from"node:readline";import{exec as L}from"node:child_process";import{mkdir as S,rm as U,cp as j,rename as H,readFile as I,writeFile as M}from"node:fs/promises";import{promisify as O}from"node:util";const P="0.3.0",c=O(L);async function d(u){if(!s(u))return S(u,{recursive:!0})}async function m(u){if(s(u))return U(u,{recursive:!0,force:!0}).catch(()=>{})}function T(u){return{output:"./git-down",branch:"main",...u}}function W(u){return t=>{if(t){if(!u)throw t;u(t)}u&&u(null)}}function D(u){const t=u.replace(/(^https?:\/\/github\.com\/)|(^git@github\.com:)/,"/"),[,n,o,,e="",...i]=t.split("/"),r=i.join("/"),l=t.includes("blob")||!!q(r);return{href:u,owner:n,project:o.replace(/\.git$/,""),isRepo:t.endsWith(".git")||!t.includes("tree")&&!t.includes("blob"),sourceType:l?"file":"dir",branch:e,pathname:r}}async function _(u,t){return s(t)?j(u,t,{recursive:!0}):H(u,t)}function z(u){const{gitInfo:t,option:n,callback:o}=u,{branch:e,output:i}=n,{owner:r,project:l}=t,p={cwd:F(i)};return c("git init --quiet",p).then(()=>c(`git remote add origin https://github.com/${r}/${l}`,p),o).then(()=>c(`git pull origin --quiet ${e} --depth 1`,p),o).then(()=>m(F(i,".git")),o)}async function J(u){const{gitInfo:t,callback:n,option:o}=u,{output:e}=o,{pathname:i,sourceType:r,branch:l,owner:p,project:w}=t,a=F(e,`./.git-down-temp-folder-${Date.now()}-${Math.random().toString(36).slice(2)}`);s(a)&&m(a),await d(a).catch(n);const g=F(a,".git/info/sparse-checkout"),C=r==="file"?i:`${i}/*`,y=`${s(g)?await I(g,{encoding:"utf-8"}):""} ${C}`,$=F(e,i.split("/").pop()),E={cwd:a},h=`remote-${Date.now()}-${Math.random().toString(36).slice(2)}`;return c("git init --quiet",E).then(()=>c(`git remote add ${h} https://github.com/${p}/${w}`,E),n).then(async()=>{try{if((await c("git config --get core.sparseCheckout",E)).stdout.trim()==="true")return}catch{}return c("git config core.sparseCheckout true",E)},n).then(()=>M(g,y),n).then(()=>c(`git pull ${h} --quiet ${l} --depth 1`,E),n).then(()=>_(F(a,i),$),n).then(()=>m(a),n)}function K(u,t,n){const o=T(t),e=W(n),i=D(u),r={option:o,callback:e,gitInfo:i};d(o.output).then(()=>(i.isRepo?z:J)(r),e).then(()=>e(null),e)}function N(u,t){return new Promise((n,o)=>{K(u,t,e=>{e?o(e):n()})})}function Q(u){return!u||typeof u!="string"?!1:/^https?:\/\/github\.com\/[\w.-]+\/[\w.-]+/.test(u)}function B(u,t){return typeof u=="string"?u:t}function V(u){const t=u.url||u._[0];return t||(console.error("\u274C \u9519\u8BEF: \u5FC5\u987B\u63D0\u4F9BURL\u53C2\u6570"),console.log("\u4F7F\u7528 --help \u67E5\u770B\u4F7F\u7528\u8BF4\u660E"),f(1)),Q(t)||(console.error("\u274C \u9519\u8BEF: GitHub URL\u683C\u5F0F\u65E0\u6548"),console.log("\u8BF7\u63D0\u4F9B\u6709\u6548\u7684GitHub\u4ED3\u5E93\u3001\u6587\u4EF6\u6216\u76EE\u5F55URL"),f(1)),t}async function X(u){const t=x({input:G,output:R});return new Promise(n=>{t.question(`\u76EE\u5F55 "${u}" \u5DF2\u5B58\u5728\u3002\u662F\u5426\u5220\u9664? (y/n): `,o=>{t.close(),n(o.toLowerCase()==="y")})})}async function Y(u,t){const n=B(u.output,`./${u.name??t.project}`);return s(n)&&(console.log(`\u26A0\uFE0F \u8B66\u544A: \u8F93\u51FA\u76EE\u5F55\u5DF2\u5B58\u5728: ${n}`),await X(n)||(console.log("\u274C \u64CD\u4F5C\u53D6\u6D88"),f(1)),b(n)),n}function Z(u,t){return B(u.branch,t)}function b(u){if(!u)return;const t=F(u);if(s(t))try{v(t,{recursive:!0}),console.log(`\u{1F5D1}\uFE0F \u5DF2\u6E05\u7406\u4E0D\u5B8C\u6574\u7684\u4E0B\u8F7D\u76EE\u5F55: ${u}`)}catch(n){console.error(`\u26A0\uFE0F \u6E05\u7406\u76EE\u5F55\u5931\u8D25: ${String(n)}`)}}async function uu(u,t){console.log(`\u{1F680} \u5F00\u59CB\u4ECE\u4EE5\u4E0B\u5730\u5740\u4E0B\u8F7D: ${u}`),console.log(`\u{1F4C1} \u8F93\u51FA\u76EE\u5F55: ${t.output}`),await N(u,t),console.log("\u2705 \u4E0B\u8F7D\u6210\u529F\u5B8C\u6210!")}async function tu(u){let t="";try{const n=V(u),o=D(n);t=await Y(u,o);const e={output:t,branch:Z(u,o.branch||"master")};await uu(n,e)}catch(n){console.error("\u274C \u4E0B\u8F7D\u5931\u8D25:",n instanceof Error?n.message:String(n)),b(t),f(1)}}const nu=A({meta:{name:"gd",description:"\u4E0B\u8F7D GitHub \u4ED3\u5E93\u6587\u4EF6\u6216\u76EE\u5F55",version:P},args:{url:{type:"positional",description:"GitHub \u4ED3\u5E93URL\u6216\u6587\u4EF6/\u76EE\u5F55URL",required:!0},output:{type:"string",description:"\u6307\u5B9A\u5B8C\u6574\u7684\u8F93\u51FA\u8DEF\u5F84\uFF0C\u652F\u6301\u76F8\u5BF9\u6216\u7EDD\u5BF9\u8DEF\u5F84 (\u4F8B\u5982: ./path \u6216 /path)",alias:["o","out"]},branch:{type:"string",description:"\u6307\u5B9A\u8981\u4E0B\u8F7D\u7684\u5206\u652F\u540D\u79F0",alias:["b"],default:"main"},help:{type:"boolean",description:"\u663E\u793A\u5E2E\u52A9\u4FE1\u606F",alias:["h"],default:!1},name:{type:"positional",description:"\u7B80\u4FBF\u65B9\u5F0F\uFF1A\u6307\u5B9A\u8F93\u51FA\u6587\u4EF6\u5939\u540D\u79F0 (\u7C7B\u4F3C git clone \u7684\u7528\u6CD5)",required:!1}},async run({args:u}){console.warn("\u4E3B\u5206\u652F\u9ED8\u8BA4\u662F main\uFF0C\u5982\u679C\u9700\u8981\u4E0B\u8F7D\u5176\u4ED6\u5206\u652F\uFF0C\u8BF7\u4F7F\u7528 -b \u53C2\u6570\u6307\u5B9A\u5206\u652F\u540D\u79F0"),await tu(u)}});k(nu);