gitpick 6.0.2 → 6.1.0-canary.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 CHANGED
@@ -9,11 +9,11 @@
9
9
  [![downloads](https://img.shields.io/npm/dt/gitpick?color=red&logo=npm)](https://www.npmjs.com/package/gitpick)
10
10
  [![stars](https://img.shields.io/github/stars/nrjdalal/gitpick?color=blue)](https://github.com/nrjdalal/gitpick)
11
11
 
12
- 📦 `Zero dependencies` / `Un/packed (~72/26kb)` / `Faster and more features` yet drop-in replacement for `degit`
12
+ 📦 `Zero dependencies` / `Un/packed (~67/25kb)` / `Faster and more features` yet drop-in replacement for `degit`
13
13
 
14
14
  > #### Just `copy-and-paste` any GitHub, GitLab, Bitbucket or Codeberg URL - no editing required (shorthands work too) - to clone individual files, folders, branches, commits, raw content or even entire repositories without the `.git` directory.
15
15
 
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.
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.
17
17
 
18
18
  **You can also try [Interactive Mode](#-interactive-mode)**. Browse any repo right in your terminal. See every file, pick what you want, skip what you don't. Just `gitpick owner/repo -i` and you're in. No more guessing paths.
19
19
 
@@ -30,7 +30,6 @@ Unlike other tools that force you to tweak URLs or follow strict formats to clon
30
30
  - [Interactive Mode](#-interactive-mode)
31
31
  - [Private Repos](#-private-repos)
32
32
  - [Config File](#-config-file)
33
- - [.gitpickignore](#-gitpickignore)
34
33
  - [Install Globally](#-install-globally-optional)
35
34
  - [Used By](#-used-by)
36
35
  - [Related Projects](#-related-projects)
@@ -40,7 +39,7 @@ Unlike other tools that force you to tweak URLs or follow strict formats to clon
40
39
 
41
40
  ## 📖 Some Examples
42
41
 
43
- See [Quick Usage](#-quick-usage) to learn more.
42
+ ### See [Quick Usage](#-quick-usage) for to learn more.
44
43
 
45
44
  ```sh
46
45
  # interactive mode - browse and pick files/folders
@@ -175,19 +174,7 @@ npx gitpick https://codeberg.org/owner/repo -i
175
174
 
176
175
  <img width="900" alt="gitpick interactive mode: browse and pick files/folders" src="https://raw.githubusercontent.com/nrjdalal/demo-kit/main/gitpick/demo-interactive.gif" />
177
176
 
178
- Navigate with arrow keys, `space` to select, `enter` to expand a folder or preview a file, `.` to select all, `c` to confirm, `q` to quit. File previews come with syntax highlighting for 38 languages. Works with GitHub, GitLab, Bitbucket, Codeberg, public and private repos.
179
-
180
- ### Pick from a local folder
181
-
182
- Interactive mode also works on any folder already on your machine, so you can use GitPick as a local file cherry-picker:
183
-
184
- ```sh
185
- npx gitpick -i # browse the current directory
186
- npx gitpick -i my-app # browse cwd, copy the selection into ./my-app
187
- npx gitpick ./src -i my-app # browse ./src, copy the selection into ./my-app
188
- ```
189
-
190
- Inside a git repo it respects your `.gitignore` (via `git ls-files`) and preserves symlinks when copying.
177
+ Navigate with arrow keys, select with space, expand/collapse with enter, `.` to select all, `c` to confirm. Works with GitHub, GitLab, Bitbucket, Codeberg, public and private repos.
191
178
 
192
179
  ---
193
180
 
@@ -268,36 +255,6 @@ Each entry follows the same `<url> [target]` syntax as the CLI. All entries are
268
255
 
269
256
  ---
270
257
 
271
- ## 🚫 .gitpickignore
272
-
273
- Add a `.gitpickignore` file at the root of the path you are picking to keep matching files out of the copy. It uses gitignore-style patterns, so the syntax is already familiar:
274
-
275
- ```gitignore
276
- # .gitpickignore lives at the root of the picked folder or repo
277
-
278
- # any .log file, at any depth
279
- *.log
280
-
281
- # a directory named node_modules, anywhere (trailing slash means directory only)
282
- node_modules/
283
-
284
- # only the dist at the picked root (a leading slash anchors the pattern)
285
- /dist
286
-
287
- # every png under docs, at any depth
288
- docs/**/*.png
289
-
290
- # re-include a file an earlier rule excluded (! negates, last match wins)
291
- !docs/logo.png
292
- ```
293
-
294
- - The file must sit at the **root of what you pick** - the folder for a `tree` URL, or the repo root for a full clone.
295
- - `*` matches within a path segment, `**` spans directories, `?` matches a single character, and a trailing `/` limits a rule to directories.
296
- - A leading or embedded `/` anchors a pattern to the picked root; otherwise it matches by basename at any depth.
297
- - Full-line `#` comments and blank lines are ignored, and the `.gitpickignore` file itself is never copied.
298
-
299
- ---
300
-
301
258
  ## 📦 Install Globally (Optional)
302
259
 
303
260
  ```sh
@@ -305,8 +262,6 @@ npm install -g gitpick
305
262
  gitpick <url/shorthand> [target] [options]
306
263
  ```
307
264
 
308
- This installs two commands, `gitpick` and `degit`, so existing `degit owner/repo` workflows keep working unchanged.
309
-
310
265
  ---
311
266
 
312
267
  ## 🌍 Used By
package/dist/index.mjs CHANGED
@@ -19,7 +19,7 @@ Skipping commit: nothing was cloned to commit.`));return}let u=i.commit||`chore:
19
19
  `;let s=f.length>r?E(`${l+1}-${Math.min(l+r,f.length)}/${f.length}`)+E(` • `):``,d=E(`↑↓:navigate esc/q:back`);i+=` ${s}${d}\n`,u.write(i)}function S(e){let t=e.toString();if(t===``){g=!1,_=null,d.removeListener(`data`,S),p(),process.removeListener(`exit`,m),process.removeListener(`SIGINT`,h),a([]);return}if(t===`\x1B`||t===`q`||t===`Q`||t===`\r`){g=!1,_=null,d.removeListener(`data`,S),d.on(`data`,x),y();return}(t===`\x1B[A`||t===`k`)&&c>0&&c--,(t===`\x1B[B`||t===`j`)&&c<f.length-1&&c++,b()}g=!0,_=b,d.on(`data`,S),b()}function x(e){let t=qn(o),n=t.length+1,r=e.toString();if(r===``||r===`q`||r===`Q`){p(),process.removeListener(`exit`,m),process.removeListener(`SIGINT`,h),a([]);return}if(r===`c`||r===`C`){p(),process.removeListener(`exit`,m),process.removeListener(`SIGINT`,h),a(Xn(o));return}if((r===`\x1B[A`||r===`k`)&&c>0&&c--,(r===`\x1B[B`||r===`j`)&&c<n-1&&c++,c===0&&(r===` `||r===`\r`)||r===`.`){let e=o.every(e=>e.selected);for(let t of o)W(t,!e)}if(r===` `&&c>0){let e=t[c-1];if(e){let t=!e.node.selected;if(W(e.node,t),t&&e.node.type===`symlink`&&e.node.linkTarget){let t=G(o,Jn(e.node.path,e.node.linkTarget));t&&W(t,!0)}Yn(o)}}if(r===`\r`&&c>0){let e=t[c-1];if(e&&e.node.type===`tree`)e.node.expanded=!e.node.expanded;else if(e&&e.node.type===`symlink`&&e.node.linkTarget.endsWith(`/`)){let t=Jn(e.node.path,e.node.linkTarget),n=t.split(`/`);for(let e=1;e<=n.length;e++){let t=G(o,n.slice(0,e).join(`/`));t&&t.type===`tree`&&(t.expanded=!0)}let r=G(o,t);if(r){r.type===`tree`&&(r.expanded=!0);let e=qn(o).findIndex(e=>e.node===r);e>=0&&(c=e+1)}}else if(e&&i&&(e.node.type===`blob`||e.node.type===`symlink`)){b(e.node);return}}if((r===`\x1B[C`||r===`l`)&&c>0){let e=t[c-1];e&&e.node.type===`tree`&&(e.node.expanded=!0)}if((r===`\x1B[D`||r===`h`)&&c>0){let e=t[c-1];e&&e.node.type===`tree`&&(e.node.expanded=!1)}y()}d.on(`data`,x),y()})}function $n(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 q=async e=>{let t=(await S(`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},er=[{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`},{prefix:`git@codeberg.org:`,host:`codeberg.org`},{prefix:`https://codeberg.org/`,host:`codeberg.org`}];async function tr(e,{branch:t,target:n}){let r=e.match(/^https:\/\/([^@]+)@(github\.com|gitlab\.com|bitbucket\.org|codeberg\.org)/),i=``;if(r)i=r[1],e=e.replace(`${r[1]}@`,``);else{let t={"github.com":process.env.GITHUB_TOKEN||process.env.GH_TOKEN||``,"gitlab.com":process.env.GITLAB_TOKEN||``,"bitbucket.org":process.env.BITBUCKET_TOKEN||``,"codeberg.org":process.env.CODEBERG_TOKEN||``};for(let{prefix:n,host:r}of er)if(e.startsWith(n)){i=t[r];break}!i&&!e.startsWith(`https://`)&&!e.startsWith(`git@`)&&(i=t[`github.com`])}let a=`github.com`;for(let{prefix:t,host:n}of er)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;if(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 q(l),f=``);else if(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 q(l),f=``);else if(a===`bitbucket.org`)o[2]===`src`?(u=`tree`,d=t||o[3],f=o.slice(4).join(`/`)):(u=`repository`,d=t||await q(l),f=``);else if(a===`codeberg.org`)[`src`,`raw`,`media`].includes(o[2])&&[`branch`,`tag`,`commit`].includes(o[3])?(u=o[2]===`src`?`tree`:`blob`,d=t||o[4],f=o.slice(5).join(`/`)):(u=`repository`,d=t||await q(l),f=``);else{let e=a;throw Error(`Unsupported host: ${e}`)}let p=n||(u===`blob`?`.`:f.split(`/`).pop()||c),m=!t&&(u===`tree`||u===`blob`)?[d,...f?f.split(`/`):[]]:void 0;return{token:i,host:a,owner:s,repository:c,type:u,branch:d,path:f,target:p,refSegments:m}}const nr=n.join(t.homedir(),`.cache`,`gitpick`),rr=n.join(nr,`update-check.json`);function ir(){try{return JSON.parse(e.readFileSync(rr,`utf-8`))}catch{return null}}function ar(t){try{e.mkdirSync(nr,{recursive:!0}),e.writeFileSync(rr,JSON.stringify(t))}catch{}}function or(){return new Promise(e=>{let t=d.get(`https://registry.npmjs.org/gitpick/latest`,{headers:{Accept:`application/json`},timeout:3e3},t=>{if(t.statusCode!==200)return t.resume(),e(null);let n=``;t.on(`data`,e=>n+=e),t.on(`end`,()=>{try{e(JSON.parse(n).version||null)}catch{e(null)}})});t.on(`error`,()=>e(null)),t.on(`timeout`,()=>{t.destroy(),e(null)})})}function sr(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){if((n[e]||0)>(r[e]||0))return!0;if((n[e]||0)<(r[e]||0))return!1}return!1}function J(e,t){if(t)return;let n=ir();n&&sr(n.latestVersion,e)&&console.log(E(`\n Update available: ${k(e)} → ${A(T(n.latestVersion))}\n Run ${A(`npm i -g gitpick`)} to update\n`))}function cr(){let e=ir();e&&Date.now()-e.lastCheck<864e5||setTimeout(async()=>{let e=await or();e&&ar({lastCheck:Date.now(),latestVersion:e})},0)}const Y=Symbol(`singleComment`),lr=Symbol(`multiComment`),X=(e,t,n)=>e.slice(t,n).replace(/[^ \t\r\n]/g,` `),ur=(e,t)=>{let n=t-1,r=0;for(;e[n]===`\\`;)--n,r+=1;return!!(r%2)};function dr(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===`"`&&(ur(e,s)||(t=!t)),!t)if(!n&&c+l===`//`)i+=e.slice(r,s),r=s,n=Y,s++;else if(n===Y&&c+l===`\r
20
20
  `){s++,n=!1,i+=X(e,r,s),r=s;continue}else if(n===Y&&c===`
21
21
  `)n=!1,i+=X(e,r,s),r=s;else if(!n&&c+l===`/*`){i+=e.slice(r,s),r=s,n=lr,s++;continue}else if(n===lr&&c+l===`*/`){s++,n=!1,i+=X(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+=X(i,0,1)+i.slice(1),i=``,r=s,o=-1):c!==` `&&c!==` `&&c!==`\r`&&c!==`
22
- `&&(i+=e.slice(r,s),r=s,o=-1))}let s=n===Y?X(e,r):e.slice(r);return a+i+s}const fr=[`.gitpick.json`,`.gitpick.jsonc`],pr=async()=>{let t;for(let r of fr){let i=n.resolve(r);if(e.existsSync(i)){t=i;break}}if(!t)return!1;let r=await e.promises.readFile(t,`utf-8`),i=JSON.parse(dr(r));if(!Array.isArray(i)||!i.every(e=>typeof e==`string`))throw Error(`${n.basename(t)} must be an array of strings`);for(let e of i)await S(process.argv[0],[...process.argv.slice(1),...e.split(/\s+/),`-o`],{stdio:`inherit`});return!0};var mr=`gitpick`,Z=`6.0.2`;const hr=(e,t)=>`\x1b]8;;${t}\x07${e}\x1b]8;;\x07`,gr=`
22
+ `&&(i+=e.slice(r,s),r=s,o=-1))}let s=n===Y?X(e,r):e.slice(r);return a+i+s}const fr=[`.gitpick.json`,`.gitpick.jsonc`],pr=async()=>{let t;for(let r of fr){let i=n.resolve(r);if(e.existsSync(i)){t=i;break}}if(!t)return!1;let r=await e.promises.readFile(t,`utf-8`),i=JSON.parse(dr(r));if(!Array.isArray(i)||!i.every(e=>typeof e==`string`))throw Error(`${n.basename(t)} must be an array of strings`);for(let e of i)await S(process.argv[0],[...process.argv.slice(1),...e.split(/\s+/),`-o`],{stdio:`inherit`});return!0};var mr=`gitpick`,Z=`6.1.0-canary.0`;const hr=(e,t)=>`\x1b]8;;${t}\x07${e}\x1b]8;;\x07`,gr=`
23
23
  With ${T(`${hr(`GitPick`,`https://github.com/nrjdalal/gitpick`)}`)} clone specific directories or files from GitHub, GitLab, Bitbucket and Codeberg!
24
24
 
25
25
  $ gitpick ${k(`<url>`)} ${O(`[target]`)} ${A(`[options]`)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitpick",
3
- "version": "6.0.2",
3
+ "version": "6.1.0-canary.0",
4
4
  "description": "Clone exactly what you need aka straightforward project scaffolding!",
5
5
  "keywords": [
6
6
  "clone",