gitpick 0.0.0-8803aa0 → 0.0.0-c952e88

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
@@ -1,158 +1,197 @@
1
1
  # GitPick
2
2
 
3
- With [gitpick](https://www.npmjs.com/package/gitpick), you can clone precisely what you need.
3
+ <!-- -->
4
4
 
5
+ **Clone exactly what you need aka straightforward project scaffolding!**
6
+
7
+ šŸ“¦ `Zero dependencies` / `Un/packed (~19/8kb)` / `Faster and more features` yet drop-in replacement for `degit`
8
+
9
+ [![Twitter](https://img.shields.io/twitter/follow/nrjdalal_dev?label=%40nrjdalal_dev)](https://twitter.com/nrjdalal_dev)
5
10
  [![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)
11
+ [![downloads](https://img.shields.io/npm/dt/gitpick?color=red&logo=npm)](https://www.npmjs.com/package/gitpick)
12
+ [![stars](https://img.shields.io/github/stars/nrjdalal/gitpick?color=blue)](https://github.com/nrjdalal/gitpick)
8
13
 
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!
14
+ > #### Just `copy-and-paste` any GitHub URL - no editing required (shorthands work too) - to clone individual files, folders, branches, commits, raw content or even entire repositories without the `.git` directory.
10
15
 
11
- Simply copy the Github URL and run with `npx gitpick <url>`, be that a public or a private repository.
16
+ Unlike other tools that force you to tweak URLs or follow strict formats to clone files, folders, branches or commits GitPick works seamlessly with any URL.
12
17
 
13
- - Target is optional, and `gitpick` follows default git clone behavior. Read [usage](#usage) for more details.
18
+ <img width="400" alt="GitPick Meme" src="https://github.com/user-attachments/assets/180c3e5b-320c-48d7-aaf9-a7402e74c882" />
14
19
 
15
- <img width="400" alt="GitPick Meme" src="https://github.com/user-attachments/assets/dde09ae9-1ee4-4cd8-a181-91f8e6ed6ba6" />
20
+ ---
16
21
 
17
- ## Features
22
+ ## šŸ“– Some Examples
18
23
 
19
- Shorthand (or use full URL):
24
+ ### See [Quick Usage](#-quick-usage) for to learn more.
20
25
 
21
26
  ```sh
22
- npx gitpick TanStack/router
27
+ # clone a repo without .git
28
+ npx gitpick owner/repo
29
+ npx gitpick https://github.com/owner/repo
30
+ # clone a folder aka tree
31
+ npx gitpick owner/repo/tree/main/path/to/folder
32
+ npx gitpick https://github.com/owner/repo/tree/main/path/to/folder
33
+ # clone a file aka blob
34
+ npx gitpick owner/repo/blob/main/path/to/file
35
+ npx gitpick https://github.com/owner/repo/blob/main/path/to/file
36
+ # clone a branch
37
+ npx gitpick owner/repo -b canary
38
+ npx gitpick https://github.com/owner/repo -b canary
39
+ npx gitpick owner/repo/tree/canary
40
+ npx gitpick https://github.com/owner/repo/tree/canary
41
+ # clone a commit SHA
42
+ npx gitpick owner/repo -b cc8e93
43
+ npx gitpick https://github.com/owner/repo/commit/cc8e93
44
+ # clone submodules
45
+ npx gitpick owner/repo -r
46
+ npx gitpick https://github.com/owner/repo -r
47
+ # clone a private repo
48
+ npx gitpick https://<token>@github.com/owner/repo
23
49
  ```
24
50
 
25
- Or clone a repository:
51
+ ---
26
52
 
27
- ```sh
28
- npx gitpick https://github.com/TanStack/router
29
- # npx gitpick TanStack/router
30
- ```
53
+ ## ✨ Features
31
54
 
32
- Or clone a specific directory:
55
+ - šŸ” Clone individual files or folders from any GitHub repository
56
+ - āš™ļø Auto-detects branches and target directory (if not specified) like `git clone`
57
+ - 🧠 Use shorthands `TanStack/router` or full URL's `https://github.com/TanStack/router`
58
+ - šŸ—‘ļø Overwrite or replace existing files without a prompt using `-o` | `--overwrite`
59
+ - šŸ“¦ Can easily clone all submodules with `-r` | `--recursive`
60
+ - šŸ” Sync changes remotely with `--watch` using intervals (e.g., `15s`, `1m`, `1h`)
61
+ - šŸ” Seamlessly works with both public and private repositories using a PAT
62
+ - šŸ“‹ Config file support (`.gitpick.json` / `.gitpick.jsonc`) for multi-path picks
33
63
 
34
- ```sh
35
- npx gitpick https://github.com/TanStack/router/tree/main/examples
36
- # npx gitpick TanStack/router/tree/main/examples
37
- ```
64
+ ---
38
65
 
39
- Or clone a specific file:
66
+ ## šŸš€ Quick Usage
40
67
 
41
68
  ```sh
42
- npx gitpick https://github.com/TanStack/router/tree/main/package.json
43
- # npx gitpick TanStack/router/tree/main/package.json
69
+ npx gitpick <url/shorthand> [target] [options]
44
70
  ```
45
71
 
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.
72
+ - [target] and [options] are optional, if not specified, GitPick fallbacks to the default behavior of `git clone`
52
73
 
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
74
+ Examples:
61
75
 
62
- -------------------------------------
63
- gitpick <url> [target] [options]
64
- -------------------------------------
76
+ ```sh
77
+ npx gitpick https://github.com/owner/repo # repo without .git
78
+ npx gitpick owner/repo/tree/main/path/to/folder # a folder aka tree
79
+ npx gitpick owner/repo/blob/main/path/to/file # a file aka blob
80
+
81
+ npx gitpick <url/shorthand> # default git behavior
82
+ npx gitpick <url/shorthand> [target] # with optional target
83
+ npx gitpick <url/shorthand> -b [branch/SHA] # branch or commit SHA
84
+ npx gitpick <url/shorthand> -o # overwrite if exists
85
+ npx gitpick <url/shorthand> -r # clone submodules
86
+ npx gitpick <url/shorthand> -w 30s # sync every 30 seconds
87
+ npx gitpick https://<token>@github.com/owner/repo # private repository
88
+ ```
65
89
 
66
- Hint: Target is optional, and follows default git clone behavior.
90
+ <img width="720" alt="Image" src="https://github.com/user-attachments/assets/ddbc41b4-bfc6-4287-bb85-eb949d723591" />
67
91
 
68
- Arguments:
69
- url GitHub URL with path to file/folder
70
- target Directory to clone into (optional)
92
+ ---
71
93
 
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
94
+ ## šŸ”§ Options
79
95
 
80
- 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]
96
+ ```
97
+ -b, --branch Branch/SHA to clone
98
+ -o, --overwrite Skip overwrite prompt
99
+ -r, --recursive Clone submodules
100
+ -w, --watch [time] Watch the repository and sync every [time]
101
+ (e.g. 1h, 30m, 15s)
102
+ -h, --help display help for command
103
+ -v, --version display the version number
86
104
  ```
87
105
 
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.
106
+ ---
95
107
 
96
- ## Installation
108
+ ## šŸ” Private Repos
97
109
 
98
- You can install GitPick globally using npm:
110
+ 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:
99
111
 
100
112
  ```sh
101
- npm install -g gitpick
113
+ npx gitpick https://<token>@github.com/owner/repo
102
114
  ```
103
115
 
104
- After installing, you can run the command:
116
+ ---
105
117
 
106
- ```sh
107
- gitpick <url> [target] [options]
118
+ ## šŸ“‹ Config File
119
+
120
+ Create a `.gitpick.json` or `.gitpick.jsonc` in your project to pick multiple files/folders in one command:
121
+
122
+ ```jsonc
123
+ // .gitpick.jsonc
124
+ [
125
+ // clone a repo without .git
126
+ "owner/repo",
127
+ "https://github.com/owner/repo",
128
+ // clone a folder aka tree
129
+ "owner/repo/tree/main/path/to/folder",
130
+ "https://github.com/owner/repo/tree/main/path/to/folder",
131
+ // clone a file aka blob
132
+ "owner/repo/blob/main/path/to/file",
133
+ "https://github.com/owner/repo/blob/main/path/to/file",
134
+ // clone a branch
135
+ "owner/repo -b canary",
136
+ "https://github.com/owner/repo -b canary",
137
+ "owner/repo/tree/canary",
138
+ "https://github.com/owner/repo/tree/canary",
139
+ // clone a commit SHA
140
+ "owner/repo -b cc8e93",
141
+ "https://github.com/owner/repo/commit/cc8e93",
142
+ // clone submodules
143
+ "owner/repo -r",
144
+ "https://github.com/owner/repo -r",
145
+ // clone a private repo
146
+ "https://<token>@github.com/owner/repo",
147
+ ]
108
148
  ```
109
149
 
110
- Or use `npx` to run the command without installing:
150
+ Then just run:
111
151
 
112
152
  ```sh
113
- npx gitpick <url> [target] [options]
153
+ npx gitpick
114
154
  ```
115
155
 
116
- ## Usage
117
-
118
- Run `npx gitpick <url> [target] [options]` to clone a file or directory from a GitHub repository.
156
+ Each entry follows the same `<url> [target]` syntax as the CLI. All entries are cloned with `-o` (overwrite) by default.
119
157
 
120
158
  ---
121
159
 
122
- Say your files are located at following GitHub URL with a directory:
123
-
124
- > https://github.com/nrjdalal/nrjdalal/tree/main/.config
160
+ ## šŸ“¦ Install Globally (Optional)
125
161
 
126
- You can sync them to a target directory in your project using:
127
-
128
- ```bash
129
- npx gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config config
162
+ ```sh
163
+ npm install -g gitpick
164
+ gitpick <url/shorthand> [target] [options]
130
165
  ```
131
166
 
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
167
  ---
135
168
 
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`):
169
+ ## šŸ›  More Tools
137
170
 
138
- ```bash
139
- gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config -w
140
- ```
171
+ Check out more projects at [github.com/nrjdalal](https://github.com/nrjdalal)
141
172
 
142
- ---
173
+ ## šŸ”— Related Projects
143
174
 
144
- Additionally, you can use this tool to clone any file or directory from any repository. For example:
175
+ - [tiged](https://github.com/tiged/tiged) - community driven fork of degit
176
+ - [giget](https://github.com/unjs/giget) - alternative approach
145
177
 
146
- ```bash
147
- gitpick https://github.com/nrjdalal/awesome-templates/tree/main/next.js-apps/next.js-pro
148
- ```
178
+ [![Star History Chart](https://api.star-history.com/svg?repos=nrjdalal/gitpick,tiged/tiged,unjs/giget&type=timeline&logscale&legend=top-left)](https://www.star-history.com/#nrjdalal/gitpick&tiged/tiged&unjs/giget&type=timeline&logscale&legend=top-left)
149
179
 
150
- The above command will clone the `next.js-pro` template from that particular repository.
180
+ ## šŸ¤ Contributing
151
181
 
152
- ---
182
+ Contributions welcome — any help is appreciated!
183
+
184
+ - Fork the repo and create a branch (use descriptive names, e.g. feat/<name> or fix/<name>).
185
+ - Make your changes, add tests if applicable, and run the checks:
186
+ - bun install
187
+ - bun test
188
+ - Follow the existing code style and commit message conventions (use conventional commits: feat, fix, docs, chore).
189
+ - Open a PR describing the change, motivation, and any migration notes; link related issues.
190
+ - For breaking changes or large features, open an issue first to discuss the approach.
191
+ - By contributing you agree to the MIT license and the project's Code of Conduct.
153
192
 
154
- I would love feedback from you all. Let's go!
193
+ Thank you for helping improve GitPick!
155
194
 
156
- ## License
195
+ ## šŸ“„ License
157
196
 
158
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
197
+ MIT – [LICENSE](LICENSE)
package/dist/index.mjs ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import e from"node:fs";import t from"node:path";import{parseArgs as n,stripVTControlCharacters as r}from"node:util";import i from"node:tty";import a from"node:os";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";const d=i?.WriteStream?.prototype?.hasColors?.()??!1,f=(e,t)=>{if(!d)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}},p=f(1,22),m=f(31,39),h=f(32,39),g=f(33,39),_=f(36,39);var v=class extends Error{constructor(...e){super(...e),this.name=`SubprocessError`,this.stdout=``,this.stderr=``}};const y=[`.exe`,`.com`],b={},x=e=>(...t)=>b[t.join(`\0`)]??=e(...t),S=x(async(...e)=>{try{return await c.access(e[0]),!0}catch{return!1}}),C=x(async(e,n,r)=>{let i=r.split(t.delimiter).filter(Boolean).map(e=>e.replace(/^"(.*)"$/,`$1`));try{await Promise.any([n,...i].flatMap(n=>y.map(r=>S(`${t.resolve(n,e)}${r}`))))}catch{return!1}return!0}),w=async(e,t)=>l.platform===`win32`&&!t.shell&&!y.some(t=>e.toLowerCase().endsWith(t))&&!await C(e,t.cwd??`.`,(l.env.PATH||l.env.Path)??``),T=e=>e.replaceAll(/([()\][%!^"`<>&|;, *?])/g,`^$1`),E=e=>T(T(`"${e.replaceAll(/(\\*)"/g,`$1$1\\"`).replace(/(\\*)$/,`$1$1`)}"`)),D=e=>/[^\w./-]/.test(e)?`'${e.replaceAll(`'`,`'\\''`)}'`:e;async function O(e,n=[],i={}){let{stdin:a,stdout:c,stderr:d,stdio:f,cwd:p=`.`,env:m,...h}=i,g=p instanceof URL?u(p):t.resolve(p),_=m?{...l.env,...m}:void 0,y=f??[a,c,d],b=[e,...n].map(e=>D(r(e))).join(` `);[`node`,`node.exe`].includes(e.toLowerCase())&&(e=l.execPath,n=[...l.execArgv.filter(e=>!e.startsWith(`--inspect`)),...n]);let x={...h,stdio:y,env:_,cwd:g};await w(e,x)&&(n=n.map(e=>E(e)),e=T(e),x={...x,shell:!0}),x.shell&&n.length>0&&(e=[e,...n].join(` `),n=[]);let S=o(e,n,x),C=``,O=``;S.stdout&&(S.stdout.setEncoding(`utf8`),S.stdout.on(`data`,e=>C+=e)),S.stderr&&(S.stderr.setEncoding(`utf8`),S.stderr.on(`data`,e=>O+=e)),S.once(`error`,()=>{});try{await s(S,`spawn`)}catch(e){throw Object.assign(new v(`Command failed: ${b}`,{cause:e}),{stdout:C,stderr:O})}await s(S,`close`);let k=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 v(`Command failed with exit code ${S.exitCode}: ${b}`),{stdout:k(C),stderr:k(O),exitCode:S.exitCode});if(S.signalCode)throw Object.assign(new v(`Command was terminated with ${S.signalCode}: ${b}`),{stdout:k(C),stderr:k(O)});return{stdout:k(C),stderr:k(O)}}const k=l.platform!==`win32`||!!l.env.WT_SESSION||l.env.TERM_PROGRAM===`vscode`,A=e=>!!(e.isTTY&&l.env.TERM!==`dumb`&&!(`CI`in l.env)),j=h(k?`āœ”`:`√`),M=k?[`ā ‹`,`ā ™`,`ā ¹`,`ā ø`,`ā ¼`,`ā “`,`ā ¦`,`ā §`,`ā ‡`,`ā `]:[`-`,`\\`,`|`,`/`],N=(e={})=>{let t=-1,n,i=e.text??``,a=e.stream??l.stderr,o=A(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=r(e).split(`
4
+ `),i=0;for(let e of n)i+=Math.max(1,Math.ceil(e.length/t));return i},m=()=>{let e=Date.now();(t===-1||e-c>=80)&&(t=++t%M.length,c=e);let n=M[t],r=`${_(n)} ${i}`;o?(f(),d(r),s=p(r)):d(r+`
5
+ `)};return{start(e){return i=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(`${j} ${e??i}\n`),this):this}}},P=async(n,r)=>{let i=await e.promises.readdir(n,{withFileTypes:!0});await e.promises.mkdir(r,{recursive:!0});for(let a of i){if(a.name===`.git`)continue;let i=t.join(n,a.name),o=t.join(r,a.name);if(a.isDirectory())await P(i,o);else if(a.isSymbolicLink()){let t=await e.promises.readlink(i);await e.promises.symlink(t,o)}else await e.promises.copyFile(i,o)}},F=async(n,r,i)=>{process.platform===`win32`&&await O(`git`,[`config`,`--global`,`core.longpaths`,`true`]);let o=`https://${n.token?n.token+`@`:n.token}${n.host}/${n.owner}/${n.repository}.git`,s=t.resolve(a.tmpdir(),`${n.repository}-${Date.now()}${Math.random().toString(16).slice(2,6)}`),c=N(),l=performance.now();r.watch||c.start(`Picking ${n.type}${n.type===`repository`?` without .git`:` from repository`}...`);try{await O(`git`,[`clone`,o,s,`--branch`,n.branch,`--depth`,`1`,`--single-branch`,...r.recursive?[`--recursive`]:[]])}catch{await O(`git`,[`clone`,o,s,...r.recursive?[`--recursive`]:[]]),await O(`git`,[`checkout`,n.branch],{cwd:s})}let u=t.resolve(s,n.path);(await e.promises.stat(u)).isDirectory()?(await e.promises.mkdir(i,{recursive:!0}),await P(u,i)):(await e.promises.mkdir(t.dirname(i),{recursive:!0}),await e.promises.copyFile(u,i)),r.watch?console.log(`- Synced at `+new Date().toLocaleTimeString()):c.success(`Picked ${n.type}${n.type===`repository`?` without .git`:` from repository`} in ${((performance.now()-l)/1e3).toFixed(2)} seconds.`),await e.promises.rm(s,{recursive:!0,force:!0})};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 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=Symbol(`singleComment`),V=Symbol(`multiComment`),H=(e,t,n)=>e.slice(t,n).replace(/[^ \t\r\n]/g,` `),U=(e,t)=>{let n=t-1,r=0;for(;e[n]===`\\`;)--n,r+=1;return!!(r%2)};function W(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===`"`&&(U(e,s)||(t=!t)),!t)if(!n&&c+l===`//`)i+=e.slice(r,s),r=s,n=B,s++;else if(n===B&&c+l===`\r
6
+ `){s++,n=!1,i+=H(e,r,s),r=s;continue}else if(n===B&&c===`
7
+ `)n=!1,i+=H(e,r,s),r=s;else if(!n&&c+l===`/*`){i+=e.slice(r,s),r=s,n=V,s++;continue}else if(n===V&&c+l===`*/`){s++,n=!1,i+=H(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+=H(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===B?H(e,r):e.slice(r);return a+i+s}const G=[`.gitpick.json`,`.gitpick.jsonc`],K=async()=>{let n;for(let r of G){let i=t.resolve(r);if(e.existsSync(i)){n=i;break}}if(!n)return!1;let r=await e.promises.readFile(n,`utf-8`),i=JSON.parse(W(r));if(!Array.isArray(i)||!i.every(e=>typeof e==`string`))throw Error(`${t.basename(n)} 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 q=`gitpick`,J=`0.0.0-c952e88`;const Y=(e,t)=>`\x1b]8;;${t}\x07${e}\x1b]8;;\x07`,X=`
9
+ With ${p(`${Y(`GitPick`,`https://github.com/nrjdalal/gitpick`)}`)} clone specific directories or files from GitHub, GitLab and Bitbucket!
10
+
11
+ $ gitpick ${g(`<url>`)} ${h(`[target]`)} ${_(`[options]`)}
12
+
13
+ ${p(`Hint:`)}
14
+ [target] and [options] are optional and if not specified,
15
+ GitPick fallbacks to the default behavior of \`git clone\`
16
+
17
+ ${p(`Arguments:`)}
18
+ ${g(`url`)} GitHub/GitLab/Bitbucket URL with path to file/folder/repository
19
+ ${h(`target`)} Directory to clone into (optional)
20
+
21
+ ${p(`Options:`)}
22
+ ${_(`-b, --branch `)} Branch/SHA to clone
23
+ ${_(`-n, --dry-run`)} Show what would be cloned without cloning
24
+ ${_(`-o, --overwrite`)} Skip overwrite prompt
25
+ ${_(`-r, --recursive`)} Clone submodules
26
+ ${_(`-w, --watch [time]`)} Watch the repository and sync every [time]
27
+ (e.g. 1h, 30m, 15s)
28
+ ${_(`-h, --help`)} display help for command
29
+ ${_(`-v, --version`)} display the version number
30
+
31
+ ${p(`Examples:`)}
32
+ $ gitpick <url>
33
+ $ gitpick <url> [target]
34
+ $ gitpick <url> [target] -b [branch/SHA]
35
+ $ gitpick <url> [target] -w [time]
36
+ $ gitpick <url> [target] -b [branch/SHA] -w [time]
37
+
38
+ šŸš€ More awesome tools at ${_(`https://github.com/nrjdalal`)}`,Z=e=>{try{return n(e)}catch(e){throw Error(`Error parsing arguments: ${e.message}`)}};(async()=>{try{let{positionals:n,values:r}=Z({allowPositionals:!0,options:{branch:{type:`string`,short:`b`},"dry-run":{type:`boolean`,short:`n`},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`}}});n.length||(r.version&&(console.log(`\n${q}@${J}`),process.exit(0)),await K()&&process.exit(0),console.log(X),process.exit(0)),n[0]===`clone`&&n.shift();let[i,a]=n,o={branch:r.branch,dryRun:r[`dry-run`],force:r.force,overwrite:r.overwrite,recursive:r.recursive,watch:r.watch};console.log(`\nWith ${p(`${Y(`GitPick`,`https://github.com/nrjdalal/gitpick`)}`)} clone specific files, folders, branches, commits and more from GitHub, GitLab and Bitbucket!`);let s=await z(i,{branch:o.branch,target:a});if(s.type===`blob`){let e=s.target.split(/[/\\]/).filter(e=>e!==``),t=e[e.length-1];t!==`.`&&t!==`..`&&t.includes(`.`)?e.pop():t=s.path.split(`/`).pop()||t,s.target=[...e,t].join(`/`)}console.info(`\n${h(`āœ”`)} ${s.owner}/${s.repository} ${_(s.type+`:`+s.branch)} ${s.type===`repository`?`> ${h(s.target)}`:`${s.path.length?g(s.path)+` >`:`>`} ${h(s.target)}`}`),o.dryRun&&(console.log(),process.exit(0));let c=t.resolve(s.target);if(o.overwrite=o.overwrite||o.force,o.watch&&(o.overwrite=!0),e.existsSync(c)&&!o.overwrite&&(s.type===`blob`&&(console.log(`${g(`\nWarning: The target file exists at ${h(s.target)}. Use ${_(`-f`)} or ${_(`-o`)} to overwrite.`)}`),process.exit(1)),(await e.promises.readdir(c)).length&&(console.log(`${g(`\nWarning: The target directory exists at ${h(s.target)} and is not empty. Use ${_(`-f`)} or ${_(`-o`)} to overwrite.`)}`),process.exit(1))),o.watch){console.log(`\nšŸ‘€ Watching every ${I(o.watch)/1e3+`s`}\n`),await F(s,o,c);let e=I(o.watch);setInterval(async()=>await F(s,o,c),e)}else await F(s,o,c),process.exit(0)}catch(e){e instanceof Error?console.log(p(`\n${m(`Error: `)}`)+e.message):console.log(p(`${m(`
39
+ Unexpected Error: `)}`)+JSON.stringify(e,null,2)),process.exit(1)}})();export{};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gitpick",
3
- "version": "0.0.0-8803aa0",
4
- "description": "With gitpick, you can clone precisely what you need.",
3
+ "version": "0.0.0-c952e88",
4
+ "description": "Clone exactly what you need aka straightforward project scaffolding!",
5
5
  "keywords": [
6
6
  "clone",
7
7
  "degit",
@@ -10,26 +10,27 @@
10
10
  "folder",
11
11
  "git",
12
12
  "github",
13
+ "repository",
13
14
  "scaffolding",
14
15
  "template",
15
16
  "url"
16
17
  ],
17
18
  "homepage": "https://github.com/nrjdalal/gitpick#readme",
18
19
  "bugs": "https://github.com/nrjdalal/gitpick/issues",
19
- "repository": "nrjdalal/gitpick",
20
- "funding": "https://github.com/sponsors/nrjdalal",
21
20
  "license": "MIT",
22
21
  "author": {
23
22
  "name": "Neeraj Dalal",
24
23
  "email": "admin@nrjdalal.com",
25
24
  "url": "https://nrjdalal.com"
26
25
  },
27
- "type": "module",
26
+ "repository": "nrjdalal/gitpick",
27
+ "funding": "https://github.com/sponsors/nrjdalal",
28
28
  "bin": {
29
- "degit": "./dist/index.js",
30
- "gitpick": "./dist/index.js"
29
+ "degit": "./dist/index.mjs",
30
+ "gitpick": "./dist/index.mjs"
31
31
  },
32
32
  "files": [
33
33
  "dist"
34
- ]
34
+ ],
35
+ "type": "module"
35
36
  }
package/dist/index.js DELETED
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env node
2
- var vt=Object.defineProperty,kt=Object.defineProperties;var Et=Object.getOwnPropertyDescriptors;var S=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,o)=>e in t?vt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o,f=(t,e)=>{for(var o in e||(e={}))_.call(e,o)&&T(t,o,e[o]);if(S)for(var o of S(e))J.call(e,o)&&T(t,o,e[o]);return t},b=(t,e)=>kt(t,Et(e));var D=(t,e)=>{var o={};for(var r in t)_.call(t,r)&&e.indexOf(r)<0&&(o[r]=t[r]);if(t!=null&&S)for(var r of S(t))e.indexOf(r)<0&&J.call(t,r)&&(o[r]=t[r]);return o};var V=(t,e,o)=>T(t,typeof e!="symbol"?e+"":e,o);var y=function(t,e){this[0]=t,this[1]=e},F=(t,e,o)=>{var r=(i,a,c,p)=>{try{var l=o[i](a),u=(a=l.value)instanceof y,w=l.done;Promise.resolve(u?a[0]:a).then(m=>u?r(i==="return"?i:"next",a[1]?{done:m.done,value:m.value}:m,c,p):c({value:m,done:w})).catch(m=>r("throw",m,c,p))}catch(m){p(m)}},n=i=>s[i]=a=>new Promise((c,p)=>r(i,a,c,p)),s={};return o=o.apply(t,e),s[v("asyncIterator")]=()=>s,n("next"),n("throw"),n("return"),s},q=t=>{var e=t[v("asyncIterator")],o=!1,r,n={};return e==null?(e=t[v("iterator")](),r=s=>n[s]=i=>e[s](i)):(e=e.call(t),r=s=>n[s]=i=>{if(o){if(o=!1,s==="throw")throw i;return i}return o=!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,r("next"),"throw"in e?r("throw"):n.throw=s=>{throw s},"return"in e&&r("return"),n},C=(t,e,o)=>(e=t[v("asyncIterator")])?e.call(t):(t=t[v("iterator")](),e={},o=(r,n)=>(n=t[r])&&(e[r]=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)))),o("next"),o("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 W=async(t,e)=>{let o=await O.promises.readdir(t,{withFileTypes:!0});await O.promises.mkdir(e,{recursive:!0});for(let r of o){if(r.name===".git")continue;let n=z.join(t,r.name),s=z.join(e,r.name);r.isDirectory()?await W(n,s):await O.promises.copyFile(n,s)}};import Pt from"node:process";import{stripVTControlCharacters as St}from"node:util";var K=t=>({start:Pt.hrtime.bigint(),command:t.map(e=>Ct(St(e))).join(" "),state:{stdout:"",stderr:"",output:""}}),Ct=t=>/[^\w./-]/.test(t)?`'${t.replaceAll("'","'\\''")}'`:t;var B=function(r,n,s){return F(this,arguments,function*(t,{state:e},o){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{[o]:l}=yield new y(t.nodeChildProcess);if(!l)return;let u="";try{for(var i=C(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:o,done:r},n]=yield new y(Promise.race(e.map((i,a)=>Promise.all([i,a])))),[s]=t.splice(n,1);e.splice(n,1),r||(t.push(s),yield o)}}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:o,stdio:r=[t,e,o],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?f(f({},Y.env),n):void 0,w=(m=r[0])==null?void 0:m.string;return b(f({},a),{input:w,stdio:w===void 0?r:["pipe",...r.slice(1)],env:s?At(u!=null?u:Y.env,l):u,cwd:l})},At=(n,r)=>{var s=n,{Path:t="",PATH:e=t}=s,o=D(s,["Path","PATH"]);let i=e.split(k.delimiter),a=X([],k.resolve(r)).map(c=>k.join(c,"node_modules/.bin")).filter(c=>!i.includes(c));return b(f({},o),{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 r;let[[e,o]]=await Promise.all([Promise.allSettled(t),Dt(t)]);if(o.reason)throw o.reason.pipedFrom=(r=e.reason)!=null?r:e.value,o.reason;if(e.reason)throw e.reason;return b(f({},o.value),{pipedFrom:e.value})},Dt=async t=>{try{let[{stdout:e},{stdin:o}]=await Promise.all(t.map(({nodeChildProcess:r})=>r));if(o===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,o).catch(()=>{})}catch(e){throw await Promise.allSettled(t.map(({nodeChildProcess:o})=>Ft(o))),e}},Ft=async t=>{let{stdin:e}=await t;e.end()};import{on as Ot,once as Wt}from"node:events";import Bt from"node:process";var et=async(t,{input:e},o)=>{let r=await t;e!==void 0&&r.stdin.end(e);let n=Wt(r,"close");try{return await Promise.race([n,...r.stdio.filter(Boolean).map(s=>Lt(s))]),Ut(o,ot(r)),rt(o)}catch(s){throw await Promise.allSettled([n]),U(s,r,o)}},Lt=async t=>{try{for(var e=C(Ot(t,"error")),o,r,n;o=!(r=await e.next()).done;o=!1){let[s]=r.value;if(!["ERR_STREAM_PREMATURE_CLOSE","EPIPE"].includes(s==null?void 0:s.code))throw s}}catch(r){n=[r]}finally{try{o&&(r=e.return)&&await r.call(e)}finally{if(n)throw n[0]}}},Ut=({command:t},{exitCode:e,signalName:o})=>{if(o!==void 0)throw new $(`Command was terminated with ${o}: ${t}`);if(e!==void 0)throw new $(`Command failed with exit code ${e}: ${t}`)},U=(t,e,o)=>Object.assign(Mt(t,o),ot(e),rt(o)),Mt=(t,{command:e})=>t instanceof $?t:new $(`Command failed: ${e}`,{cause:t}),$=class extends Error{constructor(){super(...arguments);V(this,"name","SubprocessError")}},ot=({exitCode:t,signalCode:e})=>f(f({},t<1?{}:{exitCode:t}),e===null?{}:{signalName:e}),rt=({state:{stdout:t,stderr:e,output:o},command:r,start:n})=>({stdout:L(t),stderr:L(e),output:L(o),command:r,durationMs:Number(Bt.hrtime.bigint()-n)/1e6}),L=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,o)=>await Ht(t,o)?[G(t),e.map(r=>Jt(r)),b(f({},o),{shell:!0})]:[t,e,o],Ht=async(t,{shell:e,cwd:o,env:r=nt.env})=>nt.platform==="win32"&&!e&&!await Nt(t,o,r),Nt=async(t,e,{Path:o="",PATH:r=o})=>{var n,s;return at.some(i=>t.toLowerCase().endsWith(i))||((s=M[n=`${t}\0${e}\0${r}`])!=null?s:M[n]=await _t(t,e,r))},M={},_t=async(t,e,o)=>{let r=o.split(st.delimiter).filter(Boolean).map(n=>n.replace(/^"(.*)"$/,"$1"));try{await Promise.all(at.flatMap(n=>[e,...r].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,o,r)=>{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,o));return pt(n.stdout,r,"stdout"),pt(n.stderr,r,"stderr"),n.once("error",()=>{}),await qt(n,"spawn"),n}catch(n){throw U(n,{},r)}},pt=(t,{state:e},o)=>{t&&(t.setEncoding("utf8"),e.isIterating||(e.isIterating=!1,t.on("data",r=>{e[o]+=r,e.output+=r})))};function x(t,e,o,r){let[n=[],s={}]=Array.isArray(e)?[e,o]:[[],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=r?tt([r,p]):p;let l=B(p,i,"stdout"),u=B(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,o)=>{process.platform==="win32"&&await x("git",["config","--global","core.longpaths","true"]);let r=`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",r,n,"--branch",t.branch,"--depth","1","--single-branch"]);let i=mt.join(n,t.path);(await E.promises.stat(i)).isDirectory()?(await E.promises.mkdir(o,{recursive:!0}),await W(i,o)):(await E.promises.mkdir(o,{recursive:!0}),await E.promises.copyFile(i,o+"/"+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 o=`\x1B[${t}m`,r=`\x1B[${e}m`;return n=>{let s=n+"",i=s.indexOf(r);if(i===-1)return o+s+r;let a=o,c=0;for(;i!==-1;)a+=s.slice(c,i)+o,c=i+r.length,i=s.indexOf(r,c);return a+=s.slice(c)+r,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),to=h(7,27),eo=h(8,28),oo=h(9,29),ro=h(30,39),H=h(31,39),A=h(32,39),j=h(33,39),so=h(34,39),no=h(35,39),g=h(36,39),io=h(37,39),ao=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,o=0,r;for(;(r=e.exec(t))!==null;){let n=parseInt(r[1],10);switch(r[2]){case"h":o+=n*36e5;break;case"m":o+=n*6e4;break;case"s":o+=n*1e3;break}}return o}var gt=async t=>{var n,s;let e=(await x("git",["ls-remote",t])).stdout,o=(n=e.match(/(.+)\s+HEAD/))==null?void 0:n[1],r=(s=e.match(new RegExp(`${o}\\s+refs/heads/(.+)`)))==null?void 0:s[1];if(!r)throw new Error("Could not determine default branch!");return r};async function wt(t,{branch:e,target:o}){let r=/^https:\/\/([^@]+)@github\.com/,n=t.match(r),s="";n&&(s=n[1],t=t.replace(r,"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=o||(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="0.0.0-8803aa0";var Xt=`
7
- ${d("With GitPick, you can clone precisely what you need.")}
8
-
9
- ${d("gitpick")} ${j("<url>")} ${A("[target]")} ${g("[options]")}
10
-
11
- ${d("Hint:")} Target is optional, and follows default git clone behavior.
12
-
13
- ${d("Arguments:")}
14
- ${j("url")} GitHub URL with path to file/folder/repository
15
- ${A("target")} Directory to clone into (optional)
16
-
17
- ${d("Options:")}
18
- ${g("-b, --branch ")} Branch to clone
19
- ${g("-o, --overwrite")} Skip overwrite prompt
20
- ${g("-w, --watch [time]")} Watch the repository and sync every [time]
21
- (e.g. 1h, 30m, 15s) default: 1m
22
- ${g("-h, --help")} display help for command
23
- ${g("-v, --version")} display the version number
24
-
25
- ${d("Examples:")}
26
- $ gitpick <url>
27
- $ gitpick <url> [target]
28
- $ gitpick <url> [target] -b [branch]
29
- $ gitpick <url> [target] -w [time]
30
- $ gitpick <url> [target] -b [branch] -w [time]
31
-
32
- \u{1F680} More awesome tools at ${g("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"},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||(e.version&&(console.log(`
33
- ${bt}@${$t}`),process.exit(0)),console.log(Xt),process.exit(0)),t[0]==="clone"&&t.shift();let[o,r]=t,n={branch:e.branch,overwrite:e.overwrite,force:e.force,watch:e.watch};console.log(`
34
- ${d("GitPick")} - Clone specific directories or files from GitHub!`),n.overwrite=n.overwrite||n.force;let s=await wt(o,{branch:n.branch,target:r});console.info(`
35
- ${d(s.owner)}/${d(s.repository)} ${A(`<${s.type}:${s.branch}>`)} ${s.type==="repository"?`> ${g(s.target)}`:`${j(s.path)} > ${g(`${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(`
36
- Warning: The target directory is not empty. Use ${g("-f")} | ${g("-o")} to overwrite.`)}`)),process.exit(0)),n.watch){console.log(`
37
- \u{1F440} Watching every ${N(n.watch)/1e3+"s"}
38
- `),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(`
39
- ${H("Error: ")}`)+t.message):console.log(d(`${H(`
40
- Unexpected Error: `)}`)+JSON.stringify(t,null,2)),process.exit(1)}};ee();