gitpick 3.27.0-canary.9 → 4.0.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.
Files changed (3) hide show
  1. package/README.md +45 -118
  2. package/dist/index.js +29 -20
  3. package/package.json +4 -7
package/README.md CHANGED
@@ -1,158 +1,85 @@
1
1
  # GitPick
2
2
 
3
- With [gitpick](https://www.npmjs.com/package/gitpick), you can clone precisely what you need.
3
+ **Clone exactly what you need aka straightforward project scaffolding**
4
4
 
5
- [![npm](https://img.shields.io/npm/v/gitpick?color=red&logo=npm)](https://www.npmjs.com/package/gitpick)
6
- [![npm](https://img.shields.io/npm/dt/gitpick?color=red&logo=npm)](https://www.npmjs.com/package/gitpick)
7
- [![GitHub](https://img.shields.io/github/stars/nrjdalal/gitpick?color=blue)](https://github.com/nrjdalal/gitpick)
8
-
9
- Tired of cloning an entire repository when you only need a specific file or folder? Need to watch remote changes and sync them locally? GitPick is here to help!
10
-
11
- Simply copy the Github URL and run with `npx gitpick <url>`, be that a public or a private repository.
12
-
13
- - Target is optional, and `gitpick` follows default git clone behavior. Read [usage](#usage) for more details.
14
-
15
- <img width="400" alt="GitPick Meme" src="https://github.com/user-attachments/assets/dde09ae9-1ee4-4cd8-a181-91f8e6ed6ba6" />
16
-
17
- ## Features
5
+ 📦 `Zero dependencies` / `125x smaller (<10kb)` / `More features` yet drop-in replacement for `degit`
18
6
 
19
- Shorthand (or use full URL):
7
+ [![Twitter](https://img.shields.io/twitter/follow/nrjdalal_com?label=%40nrjdalal_com)](https://twitter.com/nrjdalal_com)
8
+ [![npm](https://img.shields.io/npm/v/gitpick?color=red&logo=npm)](https://www.npmjs.com/package/gitpick)
9
+ [![downloads](https://img.shields.io/npm/dt/gitpick?color=red&logo=npm)](https://www.npmjs.com/package/gitpick)
10
+ [![stars](https://img.shields.io/github/stars/nrjdalal/gitpick?color=blue)](https://github.com/nrjdalal/gitpick)
20
11
 
21
- ```sh
22
- npx gitpick TanStack/router
23
- ```
12
+ <img width="400" alt="GitPick Meme" src="https://github.com/user-attachments/assets/180c3e5b-320c-48d7-aaf9-a7402e74c882" />
24
13
 
25
- Or clone a repository:
14
+ ---
26
15
 
27
- ```sh
28
- npx gitpick https://github.com/TanStack/router
29
- # npx gitpick TanStack/router
30
- ```
16
+ ## ✨ Features
31
17
 
32
- Or clone a specific directory:
18
+ - 🔍 Clone individual files or folders from any GitHub repository
19
+ - ⚙️ Auto-detects branches and target directory (if not specified) like `git clone`
20
+ - 🔁 Sync changes remotely with `--watch` using intervals (e.g., `15s`, `1m`, `1h`)
21
+ - 🗑️ Overwrite or replace existing files without a prompt using `--overwrite`
22
+ - 🔐 Seamlessly works with both public and private repositories using a PAT
23
+ - 🧠 Use shorthands `TanStack/router` or full URL's `https://github.com/TanStack/router`
33
24
 
34
- ```sh
35
- npx gitpick https://github.com/TanStack/router/tree/main/examples
36
- # npx gitpick TanStack/router/tree/main/examples
37
- ```
25
+ ---
38
26
 
39
- Or clone a specific file:
27
+ ## 🚀 Quick Usage
40
28
 
41
29
  ```sh
42
- npx gitpick https://github.com/TanStack/router/tree/main/package.json
43
- # npx gitpick TanStack/router/tree/main/package.json
30
+ npx gitpick <url/shorthand> [target] [options]
44
31
  ```
45
32
 
46
- - Clone a file or directory from a GitHub repository.
47
- - Autodetect branch and target directory if not provided explicitly.
48
- - Clone from public or private repositories using personal access tokens.
49
- - Overwrite existing files without prompt using `-o` or `--overwrite` flag.
50
- - Sync changes with remote repository at a specified interval using `-w` or `--watch` flag.
51
- - Use shorthands like `npx gitpick TanStack/router` or `npx gitpick TanStack/router/tree/main/examples`, no need to provide full URL.
52
-
53
- <img width="600" alt="Demo Image" src="https://github.com/user-attachments/assets/954f670a-f30d-43cf-b674-f65a170c989d" />
54
-
55
- ## Usage
56
-
57
- ```text
58
- With gitpick, you can clone precisely what you need.
59
-
60
- 🚀 More awesome tools at https://github.com/nrjdalal
61
-
62
- -------------------------------------
63
- gitpick <url> [target] [options]
64
- -------------------------------------
65
-
66
- Hint: Target is optional, and follows default git clone behavior.
67
-
68
- Arguments:
69
- url GitHub URL with path to file/folder
70
- target Directory to clone into (optional)
71
-
72
- Options:
73
- -b, --branch Branch to clone
74
- -o, --overwrite Skip overwrite prompt
75
- -w, --watch [time] Watch the repository and sync every [time]
76
- (e.g. 1h, 30m, 15s) default: 1m
77
- -h, --help display help for command
78
- -v, --version display the version number
33
+ - [target] and [options] are optional
79
34
 
80
35
  Examples:
81
- $ gitpick <url>
82
- $ gitpick <url> [target]
83
- $ gitpick <url> [target] -b [branch]
84
- $ gitpick <url> [target] -w [time]
85
- $ gitpick <url> [target] -b [branch] -w [time]
86
- ```
87
-
88
- If you wish to clone a private repository, generate a [personal access token](https://github.com/settings/personal-access-tokens/new).
89
-
90
- - For fine-grained access, select Repository permissions to be `Contents: Read-Only`.
91
-
92
- - Use `https://<token>@github.com` as URL prefix when cloning.
93
-
94
- Checkout https://github.com/nrjdalal for more awesome repositories.
95
-
96
- ## Installation
97
-
98
- You can install GitPick globally using npm:
99
36
 
100
37
  ```sh
101
- npm install -g gitpick
38
+ npx gitpick https://github.com/TanStack/router # repository without .git
39
+ npx gitpick TanStack/router/tree/main/examples # a folder
40
+ npx gitpick TanStack/router/tree/main/package.json # a file
41
+ npx gitpick <url/shorthand> -w 30s # sync every 30 seconds
42
+ npx gitpick <url/shorthand> -o # overwrite if exists
43
+ npx gitpick https://<token>@github.com/owner/repo # private repo
102
44
  ```
103
45
 
104
- After installing, you can run the command:
105
-
106
- ```sh
107
- gitpick <url> [target] [options]
108
- ```
46
+ ---
109
47
 
110
- Or use `npx` to run the command without installing:
48
+ ## 🔧 Options
111
49
 
112
- ```sh
113
- npx gitpick <url> [target] [options]
50
+ ```txt
51
+ -b, --branch Branch to clone from
52
+ -o, --overwrite Skip overwrite prompt
53
+ -w, --watch [time] Auto-sync at intervals (default: 1m)
54
+ -h, --help Show help
55
+ -v, --version Show version
114
56
  ```
115
57
 
116
- ## Usage
117
-
118
- Run `npx gitpick <url> [target] [options]` to clone a file or directory from a GitHub repository.
119
-
120
58
  ---
121
59
 
122
- Say your files are located at following GitHub URL with a directory:
123
-
124
- > https://github.com/nrjdalal/nrjdalal/tree/main/.config
60
+ ## 🔐 Private Repos
125
61
 
126
- You can sync them to a target directory in your project using:
62
+ Use a [GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#about-personal-access-tokens) (create one 👉 [here](https://github.com/settings/personal-access-tokens/new)) with `repo -> contents: read-only` permission:
127
63
 
128
- ```bash
129
- npx gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config config
130
64
  ```
131
-
132
- > This will clone the `.config` directory from the `nrjdalal/nrjdalal` repository to the `config` directory in your project. If no target directory is given, it will use the last segment of the URL, e.g., in this case, `.config`.
133
-
134
- ---
135
-
136
- If you need to watch for changes, just add `-w` or `-w [time]` (e.g., `1s`, `1m`, `1h` which is time in a human-readable format, default is `1m`):
137
-
138
- ```bash
139
- gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config -w
65
+ npx gitpick https://<token>@github.com/owner/repo
140
66
  ```
141
67
 
142
68
  ---
143
69
 
144
- Additionally, you can use this tool to clone any file or directory from any repository. For example:
70
+ ## 📦 Install Globally (Optional)
145
71
 
146
- ```bash
147
- gitpick https://github.com/nrjdalal/awesome-templates/tree/main/next.js-apps/next.js-pro
72
+ ```sh
73
+ npm install -g gitpick
74
+ gitpick <url/shorthand> [target] [options]
148
75
  ```
149
76
 
150
- The above command will clone the `next.js-pro` template from that particular repository.
151
-
152
77
  ---
153
78
 
154
- I would love feedback from you all. Let's go!
79
+ ## 🛠 More Tools
80
+
81
+ Check out more projects at [github.com/nrjdalal](https://github.com/nrjdalal)
155
82
 
156
- ## License
83
+ ## 📄 License
157
84
 
158
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
85
+ MIT [LICENSE](LICENSE)
package/dist/index.js CHANGED
@@ -1,32 +1,41 @@
1
1
  #!/usr/bin/env node
2
- var O=Object.defineProperty;var U=(t,i)=>{for(var n in i)O(t,n,{get:i[n],enumerable:!0})};import P from"fs";import{parseArgs as X}from"node:util";import Z from"path";var r={};U(r,{blue:()=>Y,bold:()=>R,cyan:()=>q,green:()=>N,white:()=>z,yellow:()=>J});import G from"node:tty";var v,k,g,j,D,L=(D=(j=(g=(k=(v=G)==null?void 0:v.WriteStream)==null?void 0:k.prototype)==null?void 0:g.hasColors)==null?void 0:j.call(g))!=null?D:!1,m=(t,i)=>{if(!L)return o=>o;let n=`\x1B[${t}m`,s=`\x1B[${i}m`;return o=>{let e=o+"",c=e.indexOf(s);if(c===-1)return n+e+s;let a=n,p=0;for(;c!==-1;)a+=e.slice(p,c)+n,p=c+s.length,c=e.indexOf(s,p);return a+=e.slice(p)+s,a}},R=m(1,22),N=m(32,39),J=m(33,39),Y=m(34,39),q=m(36,39),z=m(37,39);import h from"node:fs";import K from"node:os";import C from"node:path";import f from"node:fs";import E from"node:path";var d=async(t,i)=>{let n=await f.promises.readdir(t,{withFileTypes:!0});await f.promises.mkdir(i,{recursive:!0});for(let s of n){if(s.name===".git")continue;let o=E.join(t,s.name),e=E.join(i,s.name);s.isDirectory()?await d(o,e):await f.promises.copyFile(o,e)}};import{log as w,spinner as Q}from"@clack/prompts";import T from"nano-spawn";var y=async(t,i,n)=>{let s=Q();try{process.platform==="win32"&&await T("git",["config","--global","core.longpaths","true"]);let o=`https://${t.token?t.token+"@":t.token}github.com/${t.owner}/${t.repository}.git`,e=C.join(K.tmpdir(),`${t.repository}-${Date.now()}${Math.random().toString(16).slice(2,6)}`);i.watch||s.start(`Picking ${t.type}${t.type==="repository"?" without .git":" from repository"}`);let c=performance.now();await T("git",["clone",o,e,"--depth","1","--single-branch","--branch",t.branch]);let a=C.join(e,t.path);(await h.promises.stat(a)).isDirectory()?(await h.promises.mkdir(n,{recursive:!0}),await d(a,n)):(await h.promises.mkdir(n,{recursive:!0}),await h.promises.copyFile(a,n+"/"+t.path.split("/").pop())),i.watch?w.success("Synced at "+new Date().toLocaleTimeString()):s.stop(`Picked ${t.type}${t.type==="repository"?" without .git":" from repository"} in ${((performance.now()-c)/1e3).toFixed(2)} seconds!`),await h.promises.rm(e,{recursive:!0,force:!0})}catch(o){s.stop("Level 2: An error occurred while cloning!"),o instanceof Error?w.error("Error: "+o.message):w.error("Unexpected Error: "+JSON.stringify(o,null,2)),process.exit(1)}};function b(t){if(typeof t=="number"||/^\d+$/.test(t))return typeof t=="number"?t:parseInt(t,10);let i=/(\d+)([hms])/g,n=0,s;for(;(s=i.exec(t))!==null;){let o=parseInt(s[1],10);switch(s[2]){case"h":n+=o*36e5;break;case"m":n+=o*6e4;break;case"s":n+=o*1e3;break}}return n}import V from"nano-spawn";var A=async t=>{var o,e;let i=(await V("git",["ls-remote",t])).stdout,n=(o=i.match(/(.+)\s+HEAD/))==null?void 0:o[1],s=(e=i.match(new RegExp(`${n}\\s+refs/heads/(.+)`)))==null?void 0:e[1];if(!s)throw new Error("Could not determine default branch!");return s};async function W(t,{branch:i,target:n}){let s=/^https:\/\/([^@]+)@github\.com/,o=t.match(s),e="";o&&(e=o[1],t=t.replace(s,"https://github.com"));let c=["git@github.com:","https://github.com/","https://raw.githubusercontent.com/"];for(let x of c)if(t.startsWith(x)){t=t.replace(x,"");break}let a=t.split("/"),p=a[0],u=a[1].endsWith(".git")?a[1].slice(0,-4):a[1],l=a[2]==="blob"?"blob":a[2]==="tree"?"tree":a[2]+a[3]==="refsheads"?"raw":"repository",H=i||(l==="repository"?await A(`https://${e&&e+"@"}github.com/${p}/${u}`):l==="raw"?a[4]:a[3]),$=l?l==="raw"?a.slice(5).join("/"):a.slice(4).join("/"):a.slice(2).join("/")||"/",M=n||(l==="blob"?".":$.split("/").pop()||u);return{token:e,owner:p,repository:u,type:l,branch:H,path:$,target:M}}import{cancel as _,confirm as tt,intro as et,isCancel as ot,log as S}from"@clack/prompts";var F="gitpick",I="3.27.0-canary.9";var rt=`
3
- ${r.bold("With GitPick, you can clone precisely what you need.")}
2
+ var vt=Object.defineProperty,kt=Object.defineProperties;var Et=Object.getOwnPropertyDescriptors;var C=Object.getOwnPropertySymbols;var _=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var v=(t,e)=>(e=Symbol[t])?e:Symbol.for("Symbol."+t),jt=t=>{throw TypeError(t)};var T=(t,e,r)=>e in t?vt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,g=(t,e)=>{for(var r in e||(e={}))_.call(e,r)&&T(t,r,e[r]);if(C)for(var r of C(e))J.call(e,r)&&T(t,r,e[r]);return t},b=(t,e)=>kt(t,Et(e));var D=(t,e)=>{var r={};for(var o in t)_.call(t,o)&&e.indexOf(o)<0&&(r[o]=t[o]);if(t!=null&&C)for(var o of C(t))e.indexOf(o)<0&&J.call(t,o)&&(r[o]=t[o]);return r};var V=(t,e,r)=>T(t,typeof e!="symbol"?e+"":e,r);var y=function(t,e){this[0]=t,this[1]=e},F=(t,e,r)=>{var o=(i,a,c,p)=>{try{var l=r[i](a),u=(a=l.value)instanceof y,w=l.done;Promise.resolve(u?a[0]:a).then(m=>u?o(i==="return"?i:"next",a[1]?{done:m.done,value:m.value}:m,c,p):c({value:m,done:w})).catch(m=>o("throw",m,c,p))}catch(m){p(m)}},n=i=>s[i]=a=>new Promise((c,p)=>o(i,a,c,p)),s={};return r=r.apply(t,e),s[v("asyncIterator")]=()=>s,n("next"),n("throw"),n("return"),s},q=t=>{var e=t[v("asyncIterator")],r=!1,o,n={};return e==null?(e=t[v("iterator")](),o=s=>n[s]=i=>e[s](i)):(e=e.call(t),o=s=>n[s]=i=>{if(r){if(r=!1,s==="throw")throw i;return i}return r=!0,{done:!1,value:new y(new Promise(a=>{var c=e[s](i);c instanceof Object||jt("Object expected"),a(c)}),1)}}),n[v("iterator")]=()=>n,o("next"),"throw"in e?o("throw"):n.throw=s=>{throw s},"return"in e&&o("return"),n},S=(t,e,r)=>(e=t[v("asyncIterator")])?e.call(t):(t=t[v("iterator")](),e={},r=(o,n)=>(n=t[o])&&(e[o]=s=>new Promise((i,a,c)=>(s=n.call(t,s),c=s.done,Promise.resolve(s.value).then(p=>i({value:p,done:c}),a)))),r("next"),r("return"),e);import xt from"fs";import{parseArgs as Yt}from"node:util";import Zt from"path";import E from"node:fs";import zt from"node:os";import mt from"node:path";import O from"node:fs";import z from"node:path";var B=async(t,e)=>{let r=await O.promises.readdir(t,{withFileTypes:!0});await O.promises.mkdir(e,{recursive:!0});for(let o of r){if(o.name===".git")continue;let n=z.join(t,o.name),s=z.join(e,o.name);o.isDirectory()?await B(n,s):await O.promises.copyFile(n,s)}};import Pt from"node:process";import{stripVTControlCharacters as Ct}from"node:util";var K=t=>({start:Pt.hrtime.bigint(),command:t.map(e=>St(Ct(e))).join(" "),state:{stdout:"",stderr:"",output:""}}),St=t=>/[^\w./-]/.test(t)?`'${t.replaceAll("'","'\\''")}'`:t;var L=function(o,n,s){return F(this,arguments,function*(t,{state:e},r){if(e.isIterating===!1)throw new Error(`The subprocess must be iterated right away, for example:
3
+ for await (const line of spawn(...)) { ... }`);e.isIterating=!0;try{let{[r]:l}=yield new y(t.nodeChildProcess);if(!l)return;let u="";try{for(var i=S(l.iterator({destroyOnReturn:!1})),a,c,p;a=!(c=yield new y(i.next())).done;a=!1){let w=c.value;let m=`${u}${w}`.split(/\r?\n/);u=m.pop(),yield*q(m)}}catch(c){p=[c]}finally{try{a&&(c=i.return)&&(yield new y(c.call(i)))}finally{if(p)throw p[0]}}u&&(yield u)}finally{yield new y(t)}})},Q=function(...t){return F(this,null,function*(){try{let e=[];for(;t.length>0;){e=t.map((i,a)=>{var c;return(c=e[a])!=null?c:It(i)});let[{value:r,done:o},n]=yield new y(Promise.race(e.map((i,a)=>Promise.all([i,a])))),[s]=t.splice(n,1);e.splice(n,1),o||(t.push(s),yield r)}}finally{yield new y(Promise.all(t.map(e=>e.return())))}})},It=async t=>{try{return await t.next()}catch(e){await t.throw(e)}};import k from"node:path";import Y from"node:process";import{fileURLToPath as Rt}from"node:url";var Z=c=>{var p=c,{stdin:t,stdout:e,stderr:r,stdio:o=[t,e,r],env:n,preferLocal:s,cwd:i="."}=p,a=D(p,["stdin","stdout","stderr","stdio","env","preferLocal","cwd"]);var m;let l=i instanceof URL?Rt(i):k.resolve(i),u=n?g(g({},Y.env),n):void 0,w=(m=o[0])==null?void 0:m.string;return b(g({},a),{input:w,stdio:w===void 0?o:["pipe",...o.slice(1)],env:s?At(u!=null?u:Y.env,l):u,cwd:l})},At=(n,o)=>{var s=n,{Path:t="",PATH:e=t}=s,r=D(s,["Path","PATH"]);let i=e.split(k.delimiter),a=X([],k.resolve(o)).map(c=>k.join(c,"node_modules/.bin")).filter(c=>!i.includes(c));return b(g({},r),{PATH:[...a,e].filter(Boolean).join(k.delimiter)})},X=(t,e)=>t.at(-1)===e?t:X([...t,e],k.resolve(e,".."));import{pipeline as Tt}from"node:stream/promises";var tt=async t=>{var o;let[[e,r]]=await Promise.all([Promise.allSettled(t),Dt(t)]);if(r.reason)throw r.reason.pipedFrom=(o=e.reason)!=null?o:e.value,r.reason;if(e.reason)throw e.reason;return b(g({},r.value),{pipedFrom:e.value})},Dt=async t=>{try{let[{stdout:e},{stdin:r}]=await Promise.all(t.map(({nodeChildProcess:o})=>o));if(r===null)throw new Error('The "stdin" option must be set on the first "spawn()" call in the pipeline.');if(e===null)throw new Error('The "stdout" option must be set on the last "spawn()" call in the pipeline.');Tt(e,r).catch(()=>{})}catch(e){throw await Promise.allSettled(t.map(({nodeChildProcess:r})=>Ft(r))),e}},Ft=async t=>{let{stdin:e}=await t;e.end()};import{on as Ot,once as Bt}from"node:events";import Lt from"node:process";var et=async(t,{input:e},r)=>{let o=await t;e!==void 0&&o.stdin.end(e);let n=Bt(o,"close");try{return await Promise.race([n,...o.stdio.filter(Boolean).map(s=>Ut(s))]),Wt(r,rt(o)),ot(r)}catch(s){throw await Promise.allSettled([n]),W(s,o,r)}},Ut=async t=>{try{for(var e=S(Ot(t,"error")),r,o,n;r=!(o=await e.next()).done;r=!1){let[s]=o.value;if(!["ERR_STREAM_PREMATURE_CLOSE","EPIPE"].includes(s==null?void 0:s.code))throw s}}catch(o){n=[o]}finally{try{r&&(o=e.return)&&await o.call(e)}finally{if(n)throw n[0]}}},Wt=({command:t},{exitCode:e,signalName:r})=>{if(r!==void 0)throw new $(`Command was terminated with ${r}: ${t}`);if(e!==void 0)throw new $(`Command failed with exit code ${e}: ${t}`)},W=(t,e,r)=>Object.assign(Mt(t,r),rt(e),ot(r)),Mt=(t,{command:e})=>t instanceof $?t:new $(`Command failed: ${e}`,{cause:t}),$=class extends Error{constructor(){super(...arguments);V(this,"name","SubprocessError")}},rt=({exitCode:t,signalCode:e})=>g(g({},t<1?{}:{exitCode:t}),e===null?{}:{signalName:e}),ot=({state:{stdout:t,stderr:e,output:r},command:o,start:n})=>({stdout:U(t),stderr:U(e),output:U(r),command:o,durationMs:Number(Lt.hrtime.bigint()-n)/1e6}),U=t=>t.at(-1)===`
4
+ `?t.slice(0,t.at(-2)==="\r"?-2:-1):t;import{spawn as Vt}from"node:child_process";import{once as qt}from"node:events";import ct from"node:process";import{stat as Gt}from"node:fs/promises";import st from"node:path";import nt from"node:process";var it=async(t,e,r)=>await Ht(t,r)?[G(t),e.map(o=>Jt(o)),b(g({},r),{shell:!0})]:[t,e,r],Ht=async(t,{shell:e,cwd:r,env:o=nt.env})=>nt.platform==="win32"&&!e&&!await Nt(t,r,o),Nt=async(t,e,{Path:r="",PATH:o=r})=>{var n,s;return at.some(i=>t.toLowerCase().endsWith(i))||((s=M[n=`${t}\0${e}\0${o}`])!=null?s:M[n]=await _t(t,e,o))},M={},_t=async(t,e,r)=>{let o=r.split(st.delimiter).filter(Boolean).map(n=>n.replace(/^"(.*)"$/,"$1"));try{await Promise.all(at.flatMap(n=>[e,...o].map(s=>`${st.resolve(s,t)}${n}`)).map(async n=>{try{await Gt(n)}catch(s){return}throw 0}))}catch(n){return!0}return!1},at=[".exe",".com"],Jt=t=>G(G(`"${t.replaceAll(/(\\*)"/g,'$1$1\\"').replace(/(\\*)$/,"$1$1")}"`)),G=t=>t.replaceAll(/([()\][%!^"`<>&|;, *?])/g,"^$1");var lt=async(t,e,r,o)=>{try{[t,e]=["node","node.exe"].includes(t.toLowerCase())?[ct.execPath,[...ct.execArgv.filter(s=>!s.startsWith("--inspect")),...e]]:[t,e];let n=Vt(...await it(t,e,r));return pt(n.stdout,o,"stdout"),pt(n.stderr,o,"stderr"),n.once("error",()=>{}),await qt(n,"spawn"),n}catch(n){throw W(n,{},o)}},pt=(t,{state:e},r)=>{t&&(t.setEncoding("utf8"),e.isIterating||(e.isIterating=!1,t.on("data",o=>{e[r]+=o,e.output+=o})))};function x(t,e,r,o){let[n=[],s={}]=Array.isArray(e)?[e,r]:[[],e],i=K([t,...n]),a=Z(s),c=lt(t,n,a,i),p=et(c,a,i);Object.assign(p,{nodeChildProcess:c}),p=o?tt([o,p]):p;let l=L(p,i,"stdout"),u=L(p,i,"stderr");return Object.assign(p,{nodeChildProcess:c,stdout:l,stderr:u,[Symbol.asyncIterator]:()=>Q(l,u),pipe:(w,m,P)=>x(w,m,P,p)})}var I=async(t,e,r)=>{process.platform==="win32"&&await x("git",["config","--global","core.longpaths","true"]);let o=`https://${t.token?t.token+"@":t.token}github.com/${t.owner}/${t.repository}.git`,n=mt.join(zt.tmpdir(),`${t.repository}-${Date.now()}${Math.random().toString(16).slice(2,6)}`);e.watch||console.log(`
5
+ \u{1F50D} Picking ${t.type}${t.type==="repository"?" without .git":" from repository"} ...`);let s=performance.now();await x("git",["clone",o,n,"--branch",t.branch,"--depth","1","--single-branch",...e.recursive?["--recursive"]:[]]);let i=mt.join(n,t.path);(await E.promises.stat(i)).isDirectory()?(await E.promises.mkdir(r,{recursive:!0}),await B(i,r)):(await E.promises.mkdir(r,{recursive:!0}),await E.promises.copyFile(i,r+"/"+t.path.split("/").pop())),e.watch?console.log("- Synced at "+new Date().toLocaleTimeString()):console.log(`
6
+ \u{1F389} Picked ${t.type}${t.type==="repository"?" without .git":" from repository"} in ${((performance.now()-s)/1e3).toFixed(2)} seconds!`),await E.promises.rm(n,{recursive:!0,force:!0})};import Kt from"node:tty";var ht,ut,R,dt,ft,Qt=(ft=(dt=(R=(ut=(ht=Kt)==null?void 0:ht.WriteStream)==null?void 0:ut.prototype)==null?void 0:R.hasColors)==null?void 0:dt.call(R))!=null?ft:!1,h=(t,e)=>{if(!Qt)return n=>n;let r=`\x1B[${t}m`,o=`\x1B[${e}m`;return n=>{let s=n+"",i=s.indexOf(o);if(i===-1)return r+s+o;let a=r,c=0;for(;i!==-1;)a+=s.slice(c,i)+r,c=i+o.length,i=s.indexOf(o,c);return a+=s.slice(c)+o,a}},Ke=h(0,0),d=h(1,22),Qe=h(2,22),Ye=h(3,23),Ze=h(4,24),Xe=h(53,55),tr=h(7,27),er=h(8,28),rr=h(9,29),or=h(30,39),H=h(31,39),A=h(32,39),j=h(33,39),sr=h(34,39),nr=h(35,39),f=h(36,39),ir=h(37,39),ar=h(90,39);function N(t){if(typeof t=="number"||/^\d+$/.test(t))return typeof t=="number"?t:parseInt(t,10);let e=/(\d+)([hms])/g,r=0,o;for(;(o=e.exec(t))!==null;){let n=parseInt(o[1],10);switch(o[2]){case"h":r+=n*36e5;break;case"m":r+=n*6e4;break;case"s":r+=n*1e3;break}}return r}var gt=async t=>{var n,s;let e=(await x("git",["ls-remote",t])).stdout,r=(n=e.match(/(.+)\s+HEAD/))==null?void 0:n[1],o=(s=e.match(new RegExp(`${r}\\s+refs/heads/(.+)`)))==null?void 0:s[1];if(!o)throw new Error("Could not determine default branch!");return o};async function wt(t,{branch:e,target:r}){let o=/^https:\/\/([^@]+)@github\.com/,n=t.match(o),s="";n&&(s=n[1],t=t.replace(o,"https://github.com"));let i=["git@github.com:","https://github.com/","https://raw.githubusercontent.com/"];for(let P of i)if(t.startsWith(P)){t=t.replace(P,"");break}let a=t.split("/"),c=a[0],p=a[1].endsWith(".git")?a[1].slice(0,-4):a[1],l=a[2]==="blob"?"blob":a[2]==="tree"?"tree":a[2]+a[3]==="refsheads"?"raw":"repository",u=e||(l==="repository"?await gt(`https://${s&&s+"@"}github.com/${c}/${p}`):l==="raw"?a[4]:a[3]),w=l?l==="raw"?a.slice(5).join("/"):a.slice(4).join("/"):a.slice(2).join("/")||"/",m=r||(l==="blob"?".":w.split("/").pop()||p);return{token:s,owner:c,repository:p,type:l,branch:u,path:w,target:m}}var bt="gitpick",$t="4.0.0";var Xt=`
7
+ ${d("With GitPick, you can clone precisely what you need.")}
4
8
 
5
- ${r.cyan("gitpick <url>")} ${r.green("[target]")} ${r.blue("[options]")}
9
+ ${d("gitpick")} ${j("<url>")} ${A("[target]")} ${f("[options]")}
6
10
 
7
- ${r.bold("Hint:")} Target is optional, and follows default git clone behavior.
11
+ ${d("Hint:")} Target is optional, and follows default git clone behavior.
8
12
 
9
- ${r.bold("Arguments:")}
10
- ${r.cyan("url")} GitHub URL with path to file/folder/repository
11
- ${r.green("target")} Directory to clone into (optional)
13
+ ${d("Arguments:")}
14
+ ${j("url")} GitHub URL with path to file/folder/repository
15
+ ${A("target")} Directory to clone into (optional)
12
16
 
13
- ${r.bold("Options:")}
14
- ${r.blue("-b, --branch ")} Branch to clone
15
- ${r.blue("-o, --overwrite")} Skip overwrite prompt
16
- ${r.blue("-w, --watch [time]")} Watch the repository and sync every [time]
17
- (e.g. 1h, 30m, 15s) default: 1m
18
- ${r.blue("-h, --help")} display help for command
19
- ${r.blue("-v, --version")} display the version number
17
+ ${d("Options:")}
18
+ ${f("-b, --branch ")} Branch to clone
19
+ ${f("-o, --overwrite")} Skip overwrite prompt
20
+ ${f("-r, --recursive")} Clone submodules
21
+ ${f("-w, --watch [time]")} Watch the repository and sync every [time]
22
+ (e.g. 1h, 30m, 15s)
23
+ ${f("-h, --help")} display help for command
24
+ ${f("-v, --version")} display the version number
20
25
 
21
- ${r.bold("Examples:")}
26
+ ${d("Examples:")}
22
27
  $ gitpick <url>
23
28
  $ gitpick <url> [target]
24
29
  $ gitpick <url> [target] -b [branch]
25
30
  $ gitpick <url> [target] -w [time]
26
31
  $ gitpick <url> [target] -b [branch] -w [time]
27
32
 
28
- \u{1F680} More awesome tools at ${r.cyan("https://github.com/nrjdalal")}`,it=t=>{try{return X(t)}catch(i){throw new Error(`Error parsing arguments: ${i.message}`)}},st=async()=>{try{let{positionals:t,values:i}=it({allowPositionals:!0,options:{branch:{type:"string",short:"b"},overwrite:{type:"boolean",short:"o"},force:{type:"boolean",short:"f"},watch:{type:"string",short:"w"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}}});t.length||(i.version&&(console.log(`${F}@${I}`),process.exit(0)),console.log(rt),process.exit(0)),t[0]==="clone"&&t.shift();let[n,s]=t,o={branch:i.branch,overwrite:i.overwrite,force:i.force,watch:i.watch};o.overwrite=o.overwrite||o.force,o.watch&&(typeof o.watch=="boolean"&&(o.watch="1m"),console.log(`\u{1F440} Watching every ${b(o.watch)/1e3+"s"}
29
- `));let e=await W(n,{branch:o.branch,target:s});console.log(r.white(`
30
- ${r.bold("GitPick")} - Clone specific directories or files from GitHub!
31
- `)),et(`${r.bold(e.owner)}/${r.bold(e.repository)} ${r.green(`<${e.type}:${e.branch}>`)} ${e.type==="repository"?`> ${r.cyan(e.target)}`:`${r.yellow(e.path)} > ${r.cyan(`${e.target}${e.type==="blob"?`/${e.path.split("/").pop()}`:""}`)}`}`);let c=Z.resolve(e.target);if(o.watch&&(o.overwrite=!0),P.existsSync(c+(e.type==="blob"?"/"+e.path.split("/").pop():""))&&(await P.promises.readdir(c)).length&&!o.overwrite){let a=e.type==="tree"?"The target directory is not empty. Do you want to overwrite the files?":"The target file already exists. Do you want to overwrite the file?",p=await tt({message:a});ot(p)&&(_("Operation cancelled."),process.exit(0)),p||(S.info("Chose not to overwrite files."),process.exit(0)),S.info("You can use -o | --overwrite or -f | --force flag to skip this prompt next time.")}if(await y(e,o,c),o.watch){let a=b(o.watch);setInterval(async()=>await y(e,o,c),a)}process.exit(0)}catch(t){console.error(`
32
- Error: ${t.message}`),process.exit(1)}};st();
33
+ \u{1F680} More awesome tools at ${f("https://github.com/nrjdalal")}`,te=t=>{try{return Yt(t)}catch(e){throw new Error(`Error parsing arguments: ${e.message}`)}},ee=async()=>{try{let{positionals:t,values:e}=te({allowPositionals:!0,options:{branch:{type:"string",short:"b"},force:{type:"boolean",short:"f"},help:{type:"boolean",short:"h"},overwrite:{type:"boolean",short:"o"},recursive:{type:"boolean",short:"r"},version:{type:"boolean",short:"v"},watch:{type:"string",short:"w"}}});t.length||(e.version&&(console.log(`
34
+ ${bt}@${$t}`),process.exit(0)),console.log(Xt),process.exit(0)),t[0]==="clone"&&t.shift();let[r,o]=t,n={branch:e.branch,force:e.force,overwrite:e.overwrite,recursive:e.recursive,watch:e.watch};console.log(`
35
+ ${d("GitPick")} - Clone specific directories or files from GitHub!`),n.overwrite=n.overwrite||n.force;let s=await wt(r,{branch:n.branch,target:o});console.info(`
36
+ ${d(s.owner)}/${d(s.repository)} ${A(`<${s.type}:${s.branch}>`)} ${s.type==="repository"?`> ${f(s.target)}`:`${j(s.path)} > ${f(`${s.target}${s.type==="blob"?`/${s.path.split("/").pop()}`:""}`)}`}`);let i=Zt.resolve(s.target);if(n.watch&&(n.overwrite=!0),xt.existsSync(i+(s.type==="blob"?"/"+s.path.split("/").pop():""))&&(await xt.promises.readdir(i)).length&&!n.overwrite&&(console.log(d(`${j(`
37
+ Warning: The target directory is not empty. Use ${f("-f")} | ${f("-o")} to overwrite.`)}`)),process.exit(0)),n.watch){console.log(`
38
+ \u{1F440} Watching every ${N(n.watch)/1e3+"s"}
39
+ `),await I(s,n,i);let a=N(n.watch);setInterval(async()=>await I(s,n,i),a)}else await I(s,n,i),process.exit(0)}catch(t){t instanceof Error?console.log(d(`
40
+ ${H("Error: ")}`)+t.message):console.log(d(`${H(`
41
+ Unexpected Error: `)}`)+JSON.stringify(t,null,2)),process.exit(1)}};ee();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gitpick",
3
- "version": "3.27.0-canary.9",
4
- "description": "With gitpick, you can clone precisely what you need.",
3
+ "version": "4.0.0",
4
+ "description": "Clone exactly what you need aka straightforward project scaffolding",
5
5
  "keywords": [
6
6
  "clone",
7
7
  "degit",
@@ -10,6 +10,7 @@
10
10
  "folder",
11
11
  "git",
12
12
  "github",
13
+ "repository",
13
14
  "scaffolding",
14
15
  "template",
15
16
  "url"
@@ -31,9 +32,5 @@
31
32
  },
32
33
  "files": [
33
34
  "dist"
34
- ],
35
- "dependencies": {
36
- "@clack/prompts": "^0.10.0",
37
- "nano-spawn": "^0.2.0"
38
- }
35
+ ]
39
36
  }