gitpick 4.19.0-canary.0 → 4.19.0-canary.1

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/README.md CHANGED
@@ -133,6 +133,16 @@ npx gitpick https://<token>@gitlab.com/owner/repo
133
133
  npx gitpick https://<token>@bitbucket.org/owner/repo
134
134
  ```
135
135
 
136
+ Or use environment variables (recommended for CI):
137
+
138
+ ```sh
139
+ export GITHUB_TOKEN=ghp_xxxx # or GH_TOKEN
140
+ export GITLAB_TOKEN=glpat-xxxx
141
+ export BITBUCKET_TOKEN=xxxx
142
+
143
+ npx gitpick owner/private-repo # token is picked up automatically
144
+ ```
145
+
136
146
  Create a GitHub token šŸ‘‰ [here](https://github.com/settings/personal-access-tokens/new) with `repo -> contents: read-only` permission.
137
147
 
138
148
  ---
package/dist/index.mjs CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import e from"node:fs";import t from"node:os";import n from"node:path";import{parseArgs as r,stripVTControlCharacters as i}from"node:util";import a from"node:tty";import{spawn as o}from"node:child_process";import{once as s}from"node:events";import c from"node:fs/promises";import l from"node:process";import{fileURLToPath as u}from"node:url";import d from"node:https";const f=a?.WriteStream?.prototype?.hasColors?.()??!1,p=(e,t)=>{if(!f)return e=>e;let n=`\u001B[${e}m`,r=`\u001B[${t}m`;return e=>{let i=e+``,a=i.indexOf(r);if(a===-1)return n+i+r;let o=n,s=0,c=(t===22?r:``)+n;for(;a!==-1;)o+=i.slice(s,a)+c,s=a+r.length,a=i.indexOf(r,s);return o+=i.slice(s)+r,o}},m=p(1,22),h=p(2,22),g=p(31,39),_=p(32,39),v=p(33,39),y=p(36,39);var b=class extends Error{constructor(...e){super(...e),this.name=`SubprocessError`,this.stdout=``,this.stderr=``}};const x=[`.exe`,`.com`],S={},C=e=>(...t)=>S[t.join(`\0`)]??=e(...t),w=C(async(...e)=>{try{return await c.access(e[0]),!0}catch{return!1}}),T=C(async(e,t,r)=>{let i=r.split(n.delimiter).filter(Boolean).map(e=>e.replace(/^"(.*)"$/,`$1`));try{await Promise.any([t,...i].flatMap(t=>x.map(r=>w(`${n.resolve(t,e)}${r}`))))}catch{return!1}return!0}),ee=async(e,t)=>l.platform===`win32`&&!t.shell&&!x.some(t=>e.toLowerCase().endsWith(t))&&!await T(e,t.cwd??`.`,(l.env.PATH||l.env.Path)??``),E=e=>e.replaceAll(/([()\][%!^"`<>&|;, *?])/g,`^$1`),D=e=>E(E(`"${e.replaceAll(/(\\*)"/g,`$1$1\\"`).replace(/(\\*)$/,`$1$1`)}"`)),O=e=>/[^\w./-]/.test(e)?`'${e.replaceAll(`'`,`'\\''`)}'`:e;async function k(e,t=[],r={}){let{stdin:a,stdout:c,stderr:d,stdio:f,cwd:p=`.`,env:m,...h}=r,g=p instanceof URL?u(p):n.resolve(p),_=m?{...l.env,...m}:void 0,v=f??[a,c,d],y=[e,...t].map(e=>O(i(e))).join(` `);[`node`,`node.exe`].includes(e.toLowerCase())&&(e=l.execPath,t=[...l.execArgv.filter(e=>!e.startsWith(`--inspect`)),...t]);let x={...h,stdio:v,env:_,cwd:g};await ee(e,x)&&(t=t.map(e=>D(e)),e=E(e),x={...x,shell:!0}),x.shell&&t.length>0&&(e=[e,...t].join(` `),t=[]);let S=o(e,t,x),C=``,w=``;S.stdout&&(S.stdout.setEncoding(`utf8`),S.stdout.on(`data`,e=>C+=e)),S.stderr&&(S.stderr.setEncoding(`utf8`),S.stderr.on(`data`,e=>w+=e)),S.once(`error`,()=>{});try{await s(S,`spawn`)}catch(e){throw Object.assign(new b(`Command failed: ${y}`,{cause:e}),{stdout:C,stderr:w})}await s(S,`close`);let T=e=>e.at(-1)===`
3
- `?e.slice(0,e.at(-2)===`\r`?-2:-1):e;if(S.exitCode&&S.exitCode>0)throw Object.assign(new b(`Command failed with exit code ${S.exitCode}: ${y}`),{stdout:T(C),stderr:T(w),exitCode:S.exitCode});if(S.signalCode)throw Object.assign(new b(`Command was terminated with ${S.signalCode}: ${y}`),{stdout:T(C),stderr:T(w)});return{stdout:T(C),stderr:T(w)}}const A=l.platform!==`win32`||!!l.env.WT_SESSION||l.env.TERM_PROGRAM===`vscode`,te=e=>!!(e.isTTY&&l.env.TERM!==`dumb`&&!(`CI`in l.env)),ne=_(A?`āœ”`:`√`),j=A?[`ā ‹`,`ā ™`,`ā ¹`,`ā ø`,`ā ¼`,`ā “`,`ā ¦`,`ā §`,`ā ‡`,`ā `]:[`-`,`\\`,`|`,`/`],M=(e={})=>{let t=-1,n,r=e.text??``,a=e.stream??l.stderr,o=te(a),s=0,c=0,u=!1,d=e=>a.write(e),f=()=>{if(!(!o||s===0)){a.cursorTo(0);for(let e=0;e<s;e++)e>0&&a.moveCursor(0,-1),a.clearLine(1);s=0}},p=e=>{let t=a.columns??80,n=i(e).split(`
4
- `),r=0;for(let e of n)r+=Math.max(1,Math.ceil(e.length/t));return r},m=()=>{let e=Date.now();(t===-1||e-c>=80)&&(t=++t%j.length,c=e);let n=j[t],i=`${y(n)} ${r}`;o?(f(),d(i),s=p(i)):d(i+`
5
- `)};return{start(e){return r=e,u=!0,o&&d(`\x1B[?25l`),m(),o&&(n=setInterval(m,80)),this},success(e){return u?(u=!1,n&&=(clearInterval(n),void 0),f(),o&&d(`\x1B[?25h`),d(`${ne} ${e??r}\n`),this):this}}},N=async(t,r,i)=>{let a=i??r,o=await e.promises.readdir(t,{withFileTypes:!0});await e.promises.mkdir(r,{recursive:!0});let s=[];for(let i of o){if(i.name===`.git`)continue;let o=n.join(t,i.name),c=n.join(r,i.name);if(i.isDirectory())s.push(...await N(o,c,a));else if(i.isSymbolicLink()){let t=await e.promises.readlink(o);await e.promises.symlink(t,c),s.push(n.relative(a,c))}else await e.promises.copyFile(o,c),s.push(n.relative(a,c))}return s},P=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`,F=async(r,i,a)=>{let o=i.tree||i.quiet,s=i.verbose&&!o;process.platform===`win32`&&await k(`git`,[`config`,`--global`,`core.longpaths`,`true`]);let c=`https://${r.token?r.token+`@`:r.token}${r.host}/${r.owner}/${r.repository}.git`,l=`https://${r.host}/${r.owner}/${r.repository}.git`,u=n.resolve(t.tmpdir(),`${r.repository}-${Date.now()}${Math.random().toString(16).slice(2,6)}`),d=M(),f=performance.now();!i.watch&&!o&&d.start(`Picking ${r.type}${r.type===`repository`?` without .git`:` from repository`}...`);let p=`shallow`,m=performance.now();try{await k(`git`,[`clone`,c,u,`--branch`,r.branch,`--depth`,`1`,`--single-branch`,...i.recursive?[`--recursive`]:[]])}catch{p=`full`,await k(`git`,[`clone`,c,u,...i.recursive?[`--recursive`]:[]]),await k(`git`,[`checkout`,r.branch],{cwd:u})}let g=Number(((performance.now()-m)/1e3).toFixed(2)),_=n.resolve(u,r.path),v=await e.promises.stat(_),b=[],x=performance.now();v.isDirectory()?(await e.promises.mkdir(a,{recursive:!0}),b=await N(_,a)):(await e.promises.mkdir(n.dirname(a),{recursive:!0}),await e.promises.copyFile(_,a),b=[n.basename(a)]);let S=Number(((performance.now()-x)/1e3).toFixed(2)),C=Number(((performance.now()-f)/1e3).toFixed(2)),w=0;for(let t of b)try{let r=await e.promises.stat(n.join(a,t));w+=r.size}catch{let t=await e.promises.stat(a);w+=t.size;break}return o||(i.watch?console.log(`- Synced at `+new Date().toLocaleTimeString()):d.success(`Picked ${r.type}${r.type===`repository`?` without .git`:` from repository`} in ${C} seconds.`)),s&&(console.log(h(` clone: ${p} (depth=${p===`shallow`?`1`:`full`})`)),console.log(h(` from: ${l} @ ${y(r.branch)}`)),console.log(h(` to: ${a}`)),console.log(h(` files: ${b.length} (${P(w)})`)),console.log(h(` network: ${g}s`)),console.log(h(` copy: ${S}s`)),console.log(h(` total: ${C}s`))),await e.promises.rm(u,{recursive:!0,force:!0}),{files:b,duration:C,networkTime:g,copyTime:S,totalSize:w,cloneStrategy:p}};function I(e){if(typeof e==`number`||/^\d+$/.test(e))return typeof e==`number`?e:parseInt(e,10);let t=/(\d+)([hms])/g,n=0,r;for(;(r=t.exec(e))!==null;){let e=parseInt(r[1],10);switch(r[2]){case`h`:n+=e*36e5;break;case`m`:n+=e*6e4;break;case`s`:n+=e*1e3;break}}return n}const L=async e=>{let t=(await k(`git`,[`ls-remote`,e])).stdout,n=t.match(/(.+)\s+HEAD/)?.[1],r=t.match(RegExp(`${n}\\s+refs/heads/(.+)`))?.[1];if(!r)throw Error(`Could not determine default branch!`);return r},R=[{prefix:`git@github.com:`,host:`github.com`},{prefix:`https://github.com/`,host:`github.com`},{prefix:`https://raw.githubusercontent.com/`,host:`github.com`},{prefix:`git@gitlab.com:`,host:`gitlab.com`},{prefix:`https://gitlab.com/`,host:`gitlab.com`},{prefix:`git@bitbucket.org:`,host:`bitbucket.org`},{prefix:`https://bitbucket.org/`,host:`bitbucket.org`}];async function z(e,{branch:t,target:n}){let r=e.match(/^https:\/\/([^@]+)@(github\.com|gitlab\.com|bitbucket\.org)/),i=``;r&&(i=r[1],e=e.replace(`${r[1]}@`,``));let a=`github.com`;for(let{prefix:t,host:n}of R)if(e.startsWith(t)){a=n,e=e.replace(t,``);break}let o=e.split(`/`),s=o[0],c=o[1]?.endsWith(`.git`)?o[1].slice(0,-4):o[1],l=`https://${i&&i+`@`}${a}/${s}/${c}`,u,d,f;a===`github.com`?o[2]===`refs`&&[`heads`,`tags`].includes(o[3])?(u=`raw`,d=t||o[4],f=o.slice(5).join(`/`)):o[2]===`refs`&&o[3]===`remotes`?(u=`raw`,d=t||`${o[4]}/${o[5]}`,f=o.slice(6).join(`/`)):o[2]===`blob`?(u=`blob`,d=t||o[3],f=o.slice(4).join(`/`)):o[2]===`tree`?(u=`tree`,d=t||o[3],f=o.slice(4).join(`/`)):o[2]===`commit`?(u=`repository`,d=t||o[3],f=``):(u=`repository`,d=t||await L(l),f=``):a===`gitlab.com`?o[2]===`-`&&o[3]===`blob`?(u=`blob`,d=t||o[4],f=o.slice(5).join(`/`)):o[2]===`-`&&o[3]===`tree`?(u=`tree`,d=t||o[4],f=o.slice(5).join(`/`)):(u=`repository`,d=t||await L(l),f=``):o[2]===`src`?(u=`tree`,d=t||o[3],f=o.slice(4).join(`/`)):(u=`repository`,d=t||await L(l),f=``);let p=n||(u===`blob`?`.`:f.split(`/`).pop()||c);return{token:i,host:a,owner:s,repository:c,type:u,branch:d,path:f,target:p}}const B=n.join(t.homedir(),`.cache`,`gitpick`),V=n.join(B,`update-check.json`);function H(){try{return JSON.parse(e.readFileSync(V,`utf-8`))}catch{return null}}function U(t){try{e.mkdirSync(B,{recursive:!0}),e.writeFileSync(V,JSON.stringify(t))}catch{}}function W(){return new Promise(e=>{let t=d.get(`https://registry.npmjs.org/gitpick/latest`,{headers:{Accept:`application/json`},timeout:3e3},t=>{if(t.statusCode!==200)return t.resume(),e(null);let n=``;t.on(`data`,e=>n+=e),t.on(`end`,()=>{try{e(JSON.parse(n).version||null)}catch{e(null)}})});t.on(`error`,()=>e(null)),t.on(`timeout`,()=>{t.destroy(),e(null)})})}function G(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){if((n[e]||0)>(r[e]||0))return!0;if((n[e]||0)<(r[e]||0))return!1}return!1}function K(e,t){if(t)return;let n=H();n&&G(n.latestVersion,e)&&console.log(h(`\n Update available: ${v(e)} → ${y(m(n.latestVersion))}\n Run ${y(`npm i -g gitpick`)} to update\n`))}function re(){let e=H();e&&Date.now()-e.lastCheck<864e5||setTimeout(async()=>{let e=await W();e&&U({lastCheck:Date.now(),latestVersion:e})},0)}const q=Symbol(`singleComment`),J=Symbol(`multiComment`),Y=(e,t,n)=>e.slice(t,n).replace(/[^ \t\r\n]/g,` `),ie=(e,t)=>{let n=t-1,r=0;for(;e[n]===`\\`;)--n,r+=1;return!!(r%2)};function ae(e){if(typeof e!=`string`)throw TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof e}\``);let t=!1,n=!1,r=0,i=``,a=``,o=-1;for(let s=0;s<e.length;s++){let c=e[s],l=e[s+1];if(!n&&c===`"`&&(ie(e,s)||(t=!t)),!t)if(!n&&c+l===`//`)i+=e.slice(r,s),r=s,n=q,s++;else if(n===q&&c+l===`\r
6
- `){s++,n=!1,i+=Y(e,r,s),r=s;continue}else if(n===q&&c===`
7
- `)n=!1,i+=Y(e,r,s),r=s;else if(!n&&c+l===`/*`){i+=e.slice(r,s),r=s,n=J,s++;continue}else if(n===J&&c+l===`*/`){s++,n=!1,i+=Y(e,r,s+1),r=s+1;continue}else n||(o===-1?c===`,`&&(a+=i+e.slice(r,s),i=``,r=s,o=s):c===`}`||c===`]`?(i+=e.slice(r,s),a+=Y(i,0,1)+i.slice(1),i=``,r=s,o=-1):c!==` `&&c!==` `&&c!==`\r`&&c!==`
8
- `&&(i+=e.slice(r,s),r=s,o=-1))}let s=n===q?Y(e,r):e.slice(r);return a+i+s}const oe=[`.gitpick.json`,`.gitpick.jsonc`],se=async()=>{let t;for(let r of oe){let i=n.resolve(r);if(e.existsSync(i)){t=i;break}}if(!t)return!1;let r=await e.promises.readFile(t,`utf-8`),i=JSON.parse(ae(r));if(!Array.isArray(i)||!i.every(e=>typeof e==`string`))throw Error(`${n.basename(t)} must be an array of strings`);for(let e of i)await k(process.argv[0],[...process.argv.slice(1),...e.split(/\s+/),`-o`],{stdio:`inherit`});return!0};var ce=`gitpick`,X=`4.19.0-canary.0`;const Z=(e,t)=>`\x1b]8;;${t}\x07${e}\x1b]8;;\x07`,le=`
2
+ import e from"node:fs";import t from"node:os";import n from"node:path";import{parseArgs as r,stripVTControlCharacters as i}from"node:util";import a from"node:tty";import{spawn as o}from"node:child_process";import{once as s}from"node:events";import c from"node:fs/promises";import l from"node:process";import{fileURLToPath as u}from"node:url";import d from"node:https";const f=a?.WriteStream?.prototype?.hasColors?.()??!1,p=(e,t)=>{if(!f)return e=>e;let n=`\u001B[${e}m`,r=`\u001B[${t}m`;return e=>{let i=e+``,a=i.indexOf(r);if(a===-1)return n+i+r;let o=n,s=0,c=(t===22?r:``)+n;for(;a!==-1;)o+=i.slice(s,a)+c,s=a+r.length,a=i.indexOf(r,s);return o+=i.slice(s)+r,o}},m=p(1,22),h=p(2,22),g=p(31,39),_=p(32,39),v=p(33,39),y=p(36,39);var b=class extends Error{constructor(...e){super(...e),this.name=`SubprocessError`,this.stdout=``,this.stderr=``}};const x=[`.exe`,`.com`],S={},C=e=>(...t)=>S[t.join(`\0`)]??=e(...t),w=C(async(...e)=>{try{return await c.access(e[0]),!0}catch{return!1}}),T=C(async(e,t,r)=>{let i=r.split(n.delimiter).filter(Boolean).map(e=>e.replace(/^"(.*)"$/,`$1`));try{await Promise.any([t,...i].flatMap(t=>x.map(r=>w(`${n.resolve(t,e)}${r}`))))}catch{return!1}return!0}),ee=async(e,t)=>l.platform===`win32`&&!t.shell&&!x.some(t=>e.toLowerCase().endsWith(t))&&!await T(e,t.cwd??`.`,(l.env.PATH||l.env.Path)??``),E=e=>e.replaceAll(/([()\][%!^"`<>&|;, *?])/g,`^$1`),te=e=>E(E(`"${e.replaceAll(/(\\*)"/g,`$1$1\\"`).replace(/(\\*)$/,`$1$1`)}"`)),D=e=>/[^\w./-]/.test(e)?`'${e.replaceAll(`'`,`'\\''`)}'`:e;async function O(e,t=[],r={}){let{stdin:a,stdout:c,stderr:d,stdio:f,cwd:p=`.`,env:m,...h}=r,g=p instanceof URL?u(p):n.resolve(p),_=m?{...l.env,...m}:void 0,v=f??[a,c,d],y=[e,...t].map(e=>D(i(e))).join(` `);[`node`,`node.exe`].includes(e.toLowerCase())&&(e=l.execPath,t=[...l.execArgv.filter(e=>!e.startsWith(`--inspect`)),...t]);let x={...h,stdio:v,env:_,cwd:g};await ee(e,x)&&(t=t.map(e=>te(e)),e=E(e),x={...x,shell:!0}),x.shell&&t.length>0&&(e=[e,...t].join(` `),t=[]);let S=o(e,t,x),C=``,w=``;S.stdout&&(S.stdout.setEncoding(`utf8`),S.stdout.on(`data`,e=>C+=e)),S.stderr&&(S.stderr.setEncoding(`utf8`),S.stderr.on(`data`,e=>w+=e)),S.once(`error`,()=>{});try{await s(S,`spawn`)}catch(e){throw Object.assign(new b(`Command failed: ${y}`,{cause:e}),{stdout:C,stderr:w})}await s(S,`close`);let T=e=>e.at(-1)===`
3
+ `?e.slice(0,e.at(-2)===`\r`?-2:-1):e;if(S.exitCode&&S.exitCode>0)throw Object.assign(new b(`Command failed with exit code ${S.exitCode}: ${y}`),{stdout:T(C),stderr:T(w),exitCode:S.exitCode});if(S.signalCode)throw Object.assign(new b(`Command was terminated with ${S.signalCode}: ${y}`),{stdout:T(C),stderr:T(w)});return{stdout:T(C),stderr:T(w)}}const k=l.platform!==`win32`||!!l.env.WT_SESSION||l.env.TERM_PROGRAM===`vscode`,ne=e=>!!(e.isTTY&&l.env.TERM!==`dumb`&&!(`CI`in l.env)),A=_(k?`āœ”`:`√`),j=k?[`ā ‹`,`ā ™`,`ā ¹`,`ā ø`,`ā ¼`,`ā “`,`ā ¦`,`ā §`,`ā ‡`,`ā `]:[`-`,`\\`,`|`,`/`],re=(e={})=>{let t=-1,n,r=e.text??``,a=e.stream??l.stderr,o=ne(a),s=0,c=0,u=!1,d=e=>a.write(e),f=()=>{if(!(!o||s===0)){a.cursorTo(0);for(let e=0;e<s;e++)e>0&&a.moveCursor(0,-1),a.clearLine(1);s=0}},p=e=>{let t=a.columns??80,n=i(e).split(`
4
+ `),r=0;for(let e of n)r+=Math.max(1,Math.ceil(e.length/t));return r},m=()=>{if(!o)return;let e=Date.now();(t===-1||e-c>=80)&&(t=++t%j.length,c=e);let n=j[t],i=`${y(n)} ${r}`;f(),d(i),s=p(i)};return{start(e){return r=e,u=!0,o&&d(`\x1B[?25l`),m(),o&&(n=setInterval(m,80)),this},success(e){return u?(u=!1,n&&=(clearInterval(n),void 0),f(),o&&d(`\x1B[?25h`),d(`${A} ${e??r}\n`),this):this}}},M=async(t,r,i)=>{let a=i??r,o=await e.promises.readdir(t,{withFileTypes:!0});await e.promises.mkdir(r,{recursive:!0});let s=[];for(let i of o){if(i.name===`.git`)continue;let o=n.join(t,i.name),c=n.join(r,i.name);if(i.isDirectory())s.push(...await M(o,c,a));else if(i.isSymbolicLink()){let t=await e.promises.readlink(o);await e.promises.symlink(t,c),s.push(n.relative(a,c))}else await e.promises.copyFile(o,c),s.push(n.relative(a,c))}return s},N=new Set;function P(){for(let t of N)try{e.rmSync(t,{recursive:!0,force:!0})}catch{}process.exit(1)}process.on(`SIGINT`,P),process.on(`SIGTERM`,P);const ie=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`,F=async(r,i,a)=>{let o=i.tree||i.quiet,s=i.verbose&&!o;process.platform===`win32`&&await O(`git`,[`config`,`--global`,`core.longpaths`,`true`]);let c=`https://${r.token?r.token+`@`:r.token}${r.host}/${r.owner}/${r.repository}.git`,l=`https://${r.host}/${r.owner}/${r.repository}.git`,u=n.resolve(t.tmpdir(),`${r.repository}-${Date.now()}${Math.random().toString(16).slice(2,6)}`);N.add(u);let d=re(),f=performance.now();!i.watch&&!o&&d.start(`Picking ${r.type}${r.type===`repository`?` without .git`:` from repository`}...`);let p=`shallow`,m=performance.now();try{await O(`git`,[`clone`,c,u,`--branch`,r.branch,`--depth`,`1`,`--single-branch`,...i.recursive?[`--recursive`]:[]])}catch{p=`full`,await O(`git`,[`clone`,c,u,...i.recursive?[`--recursive`]:[]]),await O(`git`,[`checkout`,r.branch],{cwd:u})}let g=Number(((performance.now()-m)/1e3).toFixed(2)),_=n.resolve(u,r.path),v=await e.promises.stat(_),b=[],x=performance.now();v.isDirectory()?(await e.promises.mkdir(a,{recursive:!0}),b=await M(_,a)):(await e.promises.mkdir(n.dirname(a),{recursive:!0}),await e.promises.copyFile(_,a),b=[n.basename(a)]);let S=Number(((performance.now()-x)/1e3).toFixed(2)),C=Number(((performance.now()-f)/1e3).toFixed(2)),w=0;for(let t of b)try{let r=await e.promises.stat(n.join(a,t));w+=r.size}catch{let t=await e.promises.stat(a);w+=t.size;break}return o||(i.watch?console.log(`- Synced at `+new Date().toLocaleTimeString()):d.success(`Picked ${r.type}${r.type===`repository`?` without .git`:` from repository`} in ${C} seconds.`)),s&&(console.log(h(` clone: ${p} (depth=${p===`shallow`?`1`:`full`})`)),console.log(h(` from: ${l} @ ${y(r.branch)}`)),console.log(h(` to: ${a}`)),console.log(h(` files: ${b.length} (${ie(w)})`)),console.log(h(` network: ${g}s`)),console.log(h(` copy: ${S}s`)),console.log(h(` total: ${C}s`))),await e.promises.rm(u,{recursive:!0,force:!0}),N.delete(u),{files:b,duration:C,networkTime:g,copyTime:S,totalSize:w,cloneStrategy:p}};function I(e){if(typeof e==`number`||/^\d+$/.test(e))return typeof e==`number`?e:parseInt(e,10);let t=/(\d+)([hms])/g,n=0,r;for(;(r=t.exec(e))!==null;){let e=parseInt(r[1],10);switch(r[2]){case`h`:n+=e*36e5;break;case`m`:n+=e*6e4;break;case`s`:n+=e*1e3;break}}return n}const L=async e=>{let t=(await O(`git`,[`ls-remote`,e])).stdout,n=t.match(/(.+)\s+HEAD/)?.[1],r=t.match(RegExp(`${n}\\s+refs/heads/(.+)`))?.[1];if(!r)throw Error(`Could not determine default branch!`);return r},R=[{prefix:`git@github.com:`,host:`github.com`},{prefix:`https://github.com/`,host:`github.com`},{prefix:`https://raw.githubusercontent.com/`,host:`github.com`},{prefix:`git@gitlab.com:`,host:`gitlab.com`},{prefix:`https://gitlab.com/`,host:`gitlab.com`},{prefix:`git@bitbucket.org:`,host:`bitbucket.org`},{prefix:`https://bitbucket.org/`,host:`bitbucket.org`}];async function ae(e,{branch:t,target:n}){let r=e.match(/^https:\/\/([^@]+)@(github\.com|gitlab\.com|bitbucket\.org)/),i=``;if(r)i=r[1],e=e.replace(`${r[1]}@`,``);else{let t={"github.com":process.env.GITHUB_TOKEN||process.env.GH_TOKEN||``,"gitlab.com":process.env.GITLAB_TOKEN||``,"bitbucket.org":process.env.BITBUCKET_TOKEN||``};for(let{prefix:n,host:r}of R)if(e.startsWith(n)){i=t[r];break}!i&&!e.startsWith(`https://`)&&!e.startsWith(`git@`)&&(i=t[`github.com`])}let a=`github.com`;for(let{prefix:t,host:n}of R)if(e.startsWith(t)){a=n,e=e.replace(t,``);break}let o=e.split(`/`),s=o[0],c=o[1]?.endsWith(`.git`)?o[1].slice(0,-4):o[1],l=`https://${i&&i+`@`}${a}/${s}/${c}`,u,d,f;a===`github.com`?o[2]===`refs`&&[`heads`,`tags`].includes(o[3])?(u=`raw`,d=t||o[4],f=o.slice(5).join(`/`)):o[2]===`refs`&&o[3]===`remotes`?(u=`raw`,d=t||`${o[4]}/${o[5]}`,f=o.slice(6).join(`/`)):o[2]===`blob`?(u=`blob`,d=t||o[3],f=o.slice(4).join(`/`)):o[2]===`tree`?(u=`tree`,d=t||o[3],f=o.slice(4).join(`/`)):o[2]===`commit`?(u=`repository`,d=t||o[3],f=``):(u=`repository`,d=t||await L(l),f=``):a===`gitlab.com`?o[2]===`-`&&o[3]===`blob`?(u=`blob`,d=t||o[4],f=o.slice(5).join(`/`)):o[2]===`-`&&o[3]===`tree`?(u=`tree`,d=t||o[4],f=o.slice(5).join(`/`)):(u=`repository`,d=t||await L(l),f=``):o[2]===`src`?(u=`tree`,d=t||o[3],f=o.slice(4).join(`/`)):(u=`repository`,d=t||await L(l),f=``);let p=n||(u===`blob`?`.`:f.split(`/`).pop()||c);return{token:i,host:a,owner:s,repository:c,type:u,branch:d,path:f,target:p}}const z=n.join(t.homedir(),`.cache`,`gitpick`),B=n.join(z,`update-check.json`);function V(){try{return JSON.parse(e.readFileSync(B,`utf-8`))}catch{return null}}function oe(t){try{e.mkdirSync(z,{recursive:!0}),e.writeFileSync(B,JSON.stringify(t))}catch{}}function H(){return new Promise(e=>{let t=d.get(`https://registry.npmjs.org/gitpick/latest`,{headers:{Accept:`application/json`},timeout:3e3},t=>{if(t.statusCode!==200)return t.resume(),e(null);let n=``;t.on(`data`,e=>n+=e),t.on(`end`,()=>{try{e(JSON.parse(n).version||null)}catch{e(null)}})});t.on(`error`,()=>e(null)),t.on(`timeout`,()=>{t.destroy(),e(null)})})}function U(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){if((n[e]||0)>(r[e]||0))return!0;if((n[e]||0)<(r[e]||0))return!1}return!1}function W(e,t){if(t)return;let n=V();n&&U(n.latestVersion,e)&&console.log(h(`\n Update available: ${v(e)} → ${y(m(n.latestVersion))}\n Run ${y(`npm i -g gitpick`)} to update\n`))}function G(){let e=V();e&&Date.now()-e.lastCheck<864e5||setTimeout(async()=>{let e=await H();e&&oe({lastCheck:Date.now(),latestVersion:e})},0)}const K=Symbol(`singleComment`),q=Symbol(`multiComment`),J=(e,t,n)=>e.slice(t,n).replace(/[^ \t\r\n]/g,` `),se=(e,t)=>{let n=t-1,r=0;for(;e[n]===`\\`;)--n,r+=1;return!!(r%2)};function ce(e){if(typeof e!=`string`)throw TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof e}\``);let t=!1,n=!1,r=0,i=``,a=``,o=-1;for(let s=0;s<e.length;s++){let c=e[s],l=e[s+1];if(!n&&c===`"`&&(se(e,s)||(t=!t)),!t)if(!n&&c+l===`//`)i+=e.slice(r,s),r=s,n=K,s++;else if(n===K&&c+l===`\r
5
+ `){s++,n=!1,i+=J(e,r,s),r=s;continue}else if(n===K&&c===`
6
+ `)n=!1,i+=J(e,r,s),r=s;else if(!n&&c+l===`/*`){i+=e.slice(r,s),r=s,n=q,s++;continue}else if(n===q&&c+l===`*/`){s++,n=!1,i+=J(e,r,s+1),r=s+1;continue}else n||(o===-1?c===`,`&&(a+=i+e.slice(r,s),i=``,r=s,o=s):c===`}`||c===`]`?(i+=e.slice(r,s),a+=J(i,0,1)+i.slice(1),i=``,r=s,o=-1):c!==` `&&c!==` `&&c!==`\r`&&c!==`
7
+ `&&(i+=e.slice(r,s),r=s,o=-1))}let s=n===K?J(e,r):e.slice(r);return a+i+s}const le=[`.gitpick.json`,`.gitpick.jsonc`],ue=async()=>{let t;for(let r of le){let i=n.resolve(r);if(e.existsSync(i)){t=i;break}}if(!t)return!1;let r=await e.promises.readFile(t,`utf-8`),i=JSON.parse(ce(r));if(!Array.isArray(i)||!i.every(e=>typeof e==`string`))throw Error(`${n.basename(t)} must be an array of strings`);for(let e of i)await O(process.argv[0],[...process.argv.slice(1),...e.split(/\s+/),`-o`],{stdio:`inherit`});return!0};var Y=`gitpick`,X=`4.19.0-canary.1`;const Z=(e,t)=>`\x1b]8;;${t}\x07${e}\x1b]8;;\x07`,de=`
9
8
  With ${m(`${Z(`GitPick`,`https://github.com/nrjdalal/gitpick`)}`)} clone specific directories or files from GitHub, GitLab and Bitbucket!
10
9
 
11
10
  $ gitpick ${v(`<url>`)} ${_(`[target]`)} ${y(`[options]`)}
@@ -41,6 +40,6 @@ ${m(`Examples:`)}
41
40
  $ gitpick https://gitlab.com/owner/repo
42
41
  $ gitpick https://bitbucket.org/owner/repo
43
42
 
44
- šŸš€ More awesome tools at ${y(`https://github.com/nrjdalal`)}`,Q=e=>{let r=process.cwd(),i=t.homedir(),a=n.sep;return e===r?`.`:e.startsWith(r+a)?`./`+n.relative(r,e).replaceAll(a,`/`):e.startsWith(i+a)?`~/`+n.relative(i,e).replaceAll(a,`/`):e},$=async(t,r=``)=>{let i=(await e.promises.readdir(t,{withFileTypes:!0})).filter(e=>e.name!==`.git`).sort((e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`}));for(let a=0;a<i.length;a++){let o=i[a],s=a===i.length-1,c=s?`└── `:`ā”œā”€ā”€ `,l=n.join(t,o.name);if(o.isSymbolicLink()){let t=await e.promises.readlink(l),n=!1;try{n=e.statSync(l).isDirectory()}catch{}process.stdout.write(`${r}${c}${v(o.name)} -> ${n?y(t):t}\n`)}else o.isDirectory()?(process.stdout.write(`${r}${c}${y(o.name)}\n`),await $(l,`${r}${s?` `:`│ `}`)):process.stdout.write(`${r}${c}${o.name}\n`)}},ue=e=>{try{return r(e)}catch(e){throw Error(`Error parsing arguments: ${e.message}`)}};(async()=>{re();try{let{positionals:r,values:i}=ue({allowPositionals:!0,options:{branch:{type:`string`,short:`b`},"dry-run":{type:`boolean`,short:`n`},force:{type:`boolean`,short:`f`},help:{type:`boolean`,short:`h`},quiet:{type:`boolean`,short:`q`},tree:{type:`boolean`},verbose:{type:`boolean`},overwrite:{type:`boolean`,short:`o`},recursive:{type:`boolean`,short:`r`},version:{type:`boolean`,short:`v`},watch:{type:`string`,short:`w`}}});r.length||(i.version&&(console.log(`\n${ce}@${X}`),process.exit(0)),await se()&&process.exit(0),console.log(le),process.exit(0)),r[0]===`clone`&&r.shift();let[a,o]=r,s={branch:i.branch,dryRun:i[`dry-run`],force:i.force,quiet:i.quiet,tree:i.tree,verbose:i.verbose,overwrite:i.overwrite,recursive:i.recursive,watch:i.watch},c=s.tree||s.quiet;c||console.log(`\nWith ${m(`${Z(`GitPick`,`https://github.com/nrjdalal/gitpick`)}`)} clone specific files, folders, branches,\ncommits and much more from GitHub, GitLab and Bitbucket!`);let l=await z(a,{branch:s.branch,target:o});if(l.type===`blob`){let e=l.target.split(/[/\\]/).filter(e=>e!==``),t=e[e.length-1];t!==`.`&&t!==`..`&&t.includes(`.`)?e.pop():t=l.path.split(`/`).pop()||t,l.target=[...e,t].join(`/`)}c||console.info(`\n${_(`āœ”`)} ${l.owner}/${l.repository} ${y(l.type+`:`+l.branch)} ${l.type===`repository`?`> ${_(l.target)}`:`${l.path.length?v(l.path)+` >`:`>`} ${_(l.target)}`}`);let u=n.resolve(l.target),d=async t=>{e.statSync(t).isDirectory()?(process.stdout.write(`${m(y(Q(u)))}\n`),await $(t)):(process.stdout.write(`${m(y(Q(n.dirname(u))))}\n`),process.stdout.write(`└── ${n.basename(u)}\n`)),process.stdout.write(`
45
- `)};if(s.dryRun){if(s.tree){let r=n.resolve(t.tmpdir(),`gitpick-dry-${Date.now()}${Math.random().toString(16).slice(2,6)}`);try{await F(l,s,r),await d(r)}finally{await e.promises.rm(r,{recursive:!0,force:!0})}}c||console.log(),K(X,c),process.exit(0)}if(s.overwrite=s.overwrite||s.force,s.watch&&(s.overwrite=!0),e.existsSync(u)&&!s.overwrite&&(l.type===`blob`&&(console.log(`${v(`\nWarning: The target file exists at ${_(l.target)}. Use ${y(`-f`)} or ${y(`-o`)} to overwrite.`)}`),process.exit(1)),(await e.promises.readdir(u)).length&&(console.log(`${v(`\nWarning: The target directory exists at ${_(l.target)} and is not empty. Use ${y(`-f`)} or ${y(`-o`)} to overwrite.`)}`),process.exit(1))),s.watch){c||console.log(`\nšŸ‘€ Watching every ${I(s.watch)/1e3+`s`}\n`),await F(l,s,u),s.tree&&await d(u);let e=I(s.watch);setInterval(async()=>{await F(l,s,u),s.tree&&await d(u)},e)}else await F(l,s,u),s.tree&&await d(u),K(X,c),process.exit(0)}catch(e){e instanceof Error?console.log(m(`\n${g(`Error: `)}`)+e.message):console.log(m(`${g(`
43
+ šŸš€ More awesome tools at ${y(`https://github.com/nrjdalal`)}`,Q=e=>{let r=process.cwd(),i=t.homedir(),a=n.sep;return e===r?`.`:e.startsWith(r+a)?`./`+n.relative(r,e).replaceAll(a,`/`):e.startsWith(i+a)?`~/`+n.relative(i,e).replaceAll(a,`/`):e},$=async(t,r=``)=>{let i=(await e.promises.readdir(t,{withFileTypes:!0})).filter(e=>e.name!==`.git`).sort((e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`}));for(let a=0;a<i.length;a++){let o=i[a],s=a===i.length-1,c=s?`└── `:`ā”œā”€ā”€ `,l=n.join(t,o.name);if(o.isSymbolicLink()){let t=await e.promises.readlink(l),n=!1;try{n=e.statSync(l).isDirectory()}catch{}process.stdout.write(`${r}${c}${v(o.name)} -> ${n?y(t):t}\n`)}else o.isDirectory()?(process.stdout.write(`${r}${c}${y(o.name)}\n`),await $(l,`${r}${s?` `:`│ `}`)):process.stdout.write(`${r}${c}${o.name}\n`)}},fe=e=>{try{return r(e)}catch(e){throw Error(`Error parsing arguments: ${e.message}`)}};(async()=>{G();try{let{positionals:r,values:i}=fe({allowPositionals:!0,options:{branch:{type:`string`,short:`b`},"dry-run":{type:`boolean`,short:`n`},force:{type:`boolean`,short:`f`},help:{type:`boolean`,short:`h`},quiet:{type:`boolean`,short:`q`},tree:{type:`boolean`},verbose:{type:`boolean`},overwrite:{type:`boolean`,short:`o`},recursive:{type:`boolean`,short:`r`},version:{type:`boolean`,short:`v`},watch:{type:`string`,short:`w`}}});r.length||(i.version&&(console.log(`\n${Y}@${X}`),process.exit(0)),await ue()&&process.exit(0),console.log(de),process.exit(0)),r[0]===`clone`&&r.shift();let[a,o]=r,s={branch:i.branch,dryRun:i[`dry-run`],force:i.force,quiet:i.quiet,tree:i.tree,verbose:i.verbose,overwrite:i.overwrite,recursive:i.recursive,watch:i.watch},c=s.tree||s.quiet;c||console.log(`\nWith ${m(`${Z(`GitPick`,`https://github.com/nrjdalal/gitpick`)}`)} clone specific files, folders, branches,\ncommits and much more from GitHub, GitLab and Bitbucket!`);let l=await ae(a,{branch:s.branch,target:o});if(l.type===`blob`){let e=l.target.split(/[/\\]/).filter(e=>e!==``),t=e[e.length-1];t!==`.`&&t!==`..`&&t.includes(`.`)?e.pop():t=l.path.split(`/`).pop()||t,l.target=[...e,t].join(`/`)}c||console.info(`\n${_(`āœ”`)} ${l.owner}/${l.repository} ${y(l.type+`:`+l.branch)} ${l.type===`repository`?`> ${_(l.target)}`:`${l.path.length?v(l.path)+` >`:`>`} ${_(l.target)}`}`);let u=n.resolve(l.target),d=async t=>{e.statSync(t).isDirectory()?(process.stdout.write(`${m(y(Q(u)))}\n`),await $(t)):(process.stdout.write(`${m(y(Q(n.dirname(u))))}\n`),process.stdout.write(`└── ${n.basename(u)}\n`)),process.stdout.write(`
44
+ `)};if(s.dryRun){if(s.tree){let r=n.resolve(t.tmpdir(),`gitpick-dry-${Date.now()}${Math.random().toString(16).slice(2,6)}`);try{await F(l,s,r),await d(r)}finally{await e.promises.rm(r,{recursive:!0,force:!0})}}c||console.log(),W(X,c),process.exit(0)}if(s.overwrite=s.overwrite||s.force,s.watch&&(s.overwrite=!0),e.existsSync(u)&&!s.overwrite&&(l.type===`blob`&&(console.log(`${v(`\nWarning: The target file exists at ${_(l.target)}. Use ${y(`-f`)} or ${y(`-o`)} to overwrite.`)}`),process.exit(1)),(await e.promises.readdir(u)).length&&(console.log(`${v(`\nWarning: The target directory exists at ${_(l.target)} and is not empty. Use ${y(`-f`)} or ${y(`-o`)} to overwrite.`)}`),process.exit(1))),s.watch){c||console.log(`\nšŸ‘€ Watching every ${I(s.watch)/1e3+`s`}\n`),await F(l,s,u),s.tree&&await d(u);let e=I(s.watch);setInterval(async()=>{await F(l,s,u),s.tree&&await d(u)},e)}else await F(l,s,u),s.tree&&await d(u),W(X,c),process.exit(0)}catch(e){e instanceof Error?console.log(m(`\n${g(`Error: `)}`)+e.message):console.log(m(`${g(`
46
45
  Unexpected Error: `)}`)+JSON.stringify(e,null,2)),process.exit(1)}})();export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitpick",
3
- "version": "4.19.0-canary.0",
3
+ "version": "4.19.0-canary.1",
4
4
  "description": "Clone exactly what you need aka straightforward project scaffolding!",
5
5
  "keywords": [
6
6
  "clone",