gitpick 3.27.0-canary.9 → 4.1.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/README.md +51 -118
- package/dist/index.js +29 -20
- package/package.json +4 -7
package/README.md
CHANGED
|
@@ -1,158 +1,91 @@
|
|
|
1
1
|
# GitPick
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Clone exactly what you need aka straightforward project scaffolding**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
[](https://www.npmjs.com/package/gitpick)
|
|
7
|
-
[](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
|
-
|
|
7
|
+
[](https://twitter.com/nrjdalal_com)
|
|
8
|
+
[](https://www.npmjs.com/package/gitpick)
|
|
9
|
+
[](https://www.npmjs.com/package/gitpick)
|
|
10
|
+
[](https://github.com/nrjdalal/gitpick)
|
|
20
11
|
|
|
21
|
-
|
|
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
|
-
|
|
14
|
+
---
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
npx gitpick https://github.com/TanStack/router
|
|
29
|
-
# npx gitpick TanStack/router
|
|
30
|
-
```
|
|
16
|
+
## ✨ Features
|
|
31
17
|
|
|
32
|
-
|
|
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 `-o` | `--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
|
-
|
|
35
|
-
npx gitpick https://github.com/TanStack/router/tree/main/examples
|
|
36
|
-
# npx gitpick TanStack/router/tree/main/examples
|
|
37
|
-
```
|
|
25
|
+
---
|
|
38
26
|
|
|
39
|
-
|
|
27
|
+
## 🚀 Quick Usage
|
|
40
28
|
|
|
41
29
|
```sh
|
|
42
|
-
npx gitpick
|
|
43
|
-
# npx gitpick TanStack/router/tree/main/package.json
|
|
30
|
+
npx gitpick <url/shorthand> [target] [options]
|
|
44
31
|
```
|
|
45
32
|
|
|
46
|
-
-
|
|
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, if not specified, it will use the default behavior of `git clone`
|
|
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
|
-
|
|
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
|
+
|
|
42
|
+
npx gitpick <url/shorthand> # default git behavior
|
|
43
|
+
npx gitpick <url/shorthand> [target] # target is optional
|
|
44
|
+
npx gitpick <url/shorthand> -b [branch] # a branch
|
|
45
|
+
npx gitpick <url/shorthand> -o # overwrite if exists
|
|
46
|
+
npx gitpick <url/shorthand> -r # clone submodules
|
|
47
|
+
npx gitpick <url/shorthand> -w 30s # sync every 30 seconds
|
|
48
|
+
npx gitpick https://<token>@github.com/owner/repo # private repo
|
|
102
49
|
```
|
|
103
50
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```sh
|
|
107
|
-
gitpick <url> [target] [options]
|
|
108
|
-
```
|
|
51
|
+
---
|
|
109
52
|
|
|
110
|
-
|
|
53
|
+
## 🔧 Options
|
|
111
54
|
|
|
112
|
-
```
|
|
113
|
-
|
|
55
|
+
```txt
|
|
56
|
+
-b, --branch Branch to clone from
|
|
57
|
+
-o, --overwrite Skip overwrite prompt
|
|
58
|
+
-r, --recursive Clone submodules
|
|
59
|
+
-w, --watch [time] Sync at intervals
|
|
60
|
+
-h, --help Show help
|
|
61
|
+
-v, --version Show version
|
|
114
62
|
```
|
|
115
63
|
|
|
116
|
-
## Usage
|
|
117
|
-
|
|
118
|
-
Run `npx gitpick <url> [target] [options]` to clone a file or directory from a GitHub repository.
|
|
119
|
-
|
|
120
64
|
---
|
|
121
65
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
> https://github.com/nrjdalal/nrjdalal/tree/main/.config
|
|
66
|
+
## 🔐 Private Repos
|
|
125
67
|
|
|
126
|
-
|
|
68
|
+
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
69
|
|
|
128
|
-
```bash
|
|
129
|
-
npx gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config config
|
|
130
70
|
```
|
|
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
|
|
71
|
+
npx gitpick https://<token>@github.com/owner/repo
|
|
140
72
|
```
|
|
141
73
|
|
|
142
74
|
---
|
|
143
75
|
|
|
144
|
-
|
|
76
|
+
## 📦 Install Globally (Optional)
|
|
145
77
|
|
|
146
|
-
```
|
|
147
|
-
|
|
78
|
+
```sh
|
|
79
|
+
npm install -g gitpick
|
|
80
|
+
gitpick <url/shorthand> [target] [options]
|
|
148
81
|
```
|
|
149
82
|
|
|
150
|
-
The above command will clone the `next.js-pro` template from that particular repository.
|
|
151
|
-
|
|
152
83
|
---
|
|
153
84
|
|
|
154
|
-
|
|
85
|
+
## 🛠 More Tools
|
|
86
|
+
|
|
87
|
+
Check out more projects at [github.com/nrjdalal](https://github.com/nrjdalal)
|
|
155
88
|
|
|
156
|
-
## License
|
|
89
|
+
## 📄 License
|
|
157
90
|
|
|
158
|
-
|
|
91
|
+
MIT – [LICENSE](LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
${r.
|
|
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.1.0";var Xt=`
|
|
7
|
+
${d("With GitPick, you can clone precisely what you need.")}
|
|
4
8
|
|
|
5
|
-
${
|
|
9
|
+
${d("gitpick")} ${j("<url>")} ${A("[target]")} ${f("[options]")}
|
|
6
10
|
|
|
7
|
-
${
|
|
11
|
+
${d("Hint:")} Target is optional, and follows default git clone behavior.
|
|
8
12
|
|
|
9
|
-
${
|
|
10
|
-
${
|
|
11
|
-
${
|
|
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
|
-
${
|
|
14
|
-
${
|
|
15
|
-
${
|
|
16
|
-
${
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
${
|
|
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
|
-
${
|
|
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 ${
|
|
29
|
-
`));let
|
|
30
|
-
${
|
|
31
|
-
|
|
32
|
-
|
|
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": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "4.1.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
|
}
|