Skip to content

tests failing on my machine aka windows/wsl, and bun install is also failing #70

Description

@sidgaikwad
gaikw@Sidd24:/mnt/d/zerostart$ bun i
bun install v1.3.5 (1e86cebd)

$ bunx lefthook install
│  > git rev-parse --path-format=absolute --show-toplevel --git-path hooks --git-path info --git-dir
│    fatal: not a git repository (or any of the parent directories): .git
│
exit status 128
error: prepare script from "gitpick" exited with 1
gaikw@Sidd24:/mnt/d/zerostart$ bun i --no-scripts
bun install v1.3.5 (1e86cebd)

$ bunx lefthook install
│  > git rev-parse --path-format=absolute --show-toplevel --git-path hooks --git-path info --git-dir
│    fatal: not a git repository (or any of the parent directories): .git
│
exit status 128
error: prepare script from "gitpick" exited with 1
gaikw@Sidd24:/mnt/d/zerostart$ bun i --ignore-scripts
bun install v1.3.5 (1e86cebd)

Checked 171 installs across 232 packages (no changes) [67.00ms]
gaikw@Sidd24:/mnt/d/zerostart$ bun run test
$ tsdown && bun test tests/
ℹ tsdown v0.21.4 powered by rolldown v1.0.0-rc.9
ℹ config file: D:\zerostart\tsdown.config.ts
ℹ entry: bin\index.ts
ℹ tsconfig: tsconfig.json
ℹ Build start
ℹ Granting execute permission to dist\index.mjs
ℹ dist\index.mjs  59.98 kB │ gzip: 22.20 kB
ℹ 1 files, total: 59.98 kB
✔ Build complete in 364ms
bun test v1.3.5 (1e86cebd)

tests\cli.test.ts:
✓ dry-run — URL parsing without cloning > shorthand repo [1063.00ms]
✓ dry-run — URL parsing without cloning > full URL repo [922.00ms]
✓ dry-run — URL parsing without cloning > shorthand tree [109.00ms]
✓ dry-run — URL parsing without cloning > full URL tree [125.00ms]
✓ dry-run — URL parsing without cloning > nested tree [141.00ms]
✓ dry-run — URL parsing without cloning > full URL nested tree [125.00ms]
✓ dry-run — URL parsing without cloning > shorthand blob [125.00ms]
✓ dry-run — URL parsing without cloning > full URL blob [140.00ms]
✓ dry-run — URL parsing without cloning > nested blob [110.00ms]
✓ dry-run — URL parsing without cloning > deep nested blob [140.00ms]
✓ dry-run — URL parsing without cloning > all-separator blob target does not crash [157.00ms]
✓ dry-run — URL parsing without cloning > -b dev [125.00ms]
✓ dry-run — URL parsing without cloning > full URL -b dev [109.00ms]
✓ dry-run — URL parsing without cloning > tree/dev [94.00ms]
✓ dry-run — URL parsing without cloning > full URL tree/dev [93.00ms]
✓ dry-run — URL parsing without cloning > -b SHA [110.00ms]
✓ dry-run — URL parsing without cloning > /commit/ URL [109.00ms]
✓ dry-run — URL parsing without cloning > -r shorthand [1266.00ms]
✓ dry-run — URL parsing without cloning > -r full URL [1000.00ms]
✓ dry-run — URL parsing without cloning > token URL [922.00ms]
✓ dry-run — URL parsing without cloning > git@ [953.00ms]
✓ dry-run — URL parsing without cloning > .git suffix [1000.00ms]
✓ dry-run — URL parsing without cloning > git@ tree [94.00ms]
✓ dry-run — URL parsing without cloning > .git tree [141.00ms]
✓ dry-run — URL parsing without cloning > branch override [109.00ms]
✓ dry-run — URL parsing without cloning > branch override URL [94.00ms]
✓ dry-run — URL parsing without cloning > custom target repo [953.00ms]
✓ dry-run — URL parsing without cloning > custom target tree [125.00ms]
✓ dry-run — URL parsing without cloning > raw URL refs/heads [109.00ms]
✓ dry-run — URL parsing without cloning > raw URL refs/tags [110.00ms]
✓ dry-run — URL parsing without cloning > raw shorthand refs/heads [94.00ms]
✓ dry-run — URL parsing without cloning > raw URL refs/remotes [109.00ms]
✓ dry-run — URL parsing without cloning > gitlab repo [94.00ms]
✓ dry-run — URL parsing without cloning > gitlab tree [140.00ms]
✓ dry-run — URL parsing without cloning > gitlab blob [141.00ms]
✓ dry-run — URL parsing without cloning > bitbucket repo [141.00ms]
✓ dry-run — URL parsing without cloning > bitbucket src path [109.00ms]
✓ dry-run — URL parsing without cloning > codeberg repo [94.00ms]
✓ dry-run — URL parsing without cloning > codeberg src/branch path [93.00ms]
✓ dry-run — URL parsing without cloning > codeberg src/tag path [110.00ms]
✓ dry-run — URL parsing without cloning > codeberg src/commit path [94.00ms]
✓ dry-run — URL parsing without cloning > codeberg raw/branch file [109.00ms]
✓ dry-run — URL parsing without cloning > codeberg media/branch file [109.00ms]
✓ dry-run — URL parsing without cloning > codeberg git@ repo [94.00ms]
✓ dry-run — URL parsing without cloning > codeberg git@ src path [109.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ default — gitpick <url/shorthand> > shorthand repo [2375.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ default — gitpick <url/shorthand> > full URL repo [2375.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ default — gitpick <url/shorthand> > git@ repo [2328.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ default — gitpick <url/shorthand> > .git suffix repo [2406.00ms]
✓ default — gitpick <url/shorthand> > shorthand tree [1563.00ms]
✓ default — gitpick <url/shorthand> > full URL tree [1469.00ms]
✓ default — gitpick <url/shorthand> > git@ tree [1515.00ms]
✓ default — gitpick <url/shorthand> > .git suffix tree [1438.00ms]
✓ default — gitpick <url/shorthand> > nested tree [1437.00ms]
✓ default — gitpick <url/shorthand> > shorthand blob [797.00ms]
✓ default — gitpick <url/shorthand> > full URL blob [531.00ms]
✓ default — gitpick <url/shorthand> > nested blob [922.00ms]
✓ default — gitpick <url/shorthand> > deep nested blob [781.00ms]
✓ transport — single-file fast path > blob pick uses a raw GET [516.00ms]
✓ transport — single-file fast path > tree pick still uses a shallow clone [1625.00ms]
✓ transport — single-file fast path > github blob → raw with correct content [500.00ms]
✓ transport — single-file fast path > gitlab blob → raw with content [1109.00ms]
✓ transport — single-file fast path > codeberg branch blob → raw with content [1828.00ms]
✓ transport — single-file fast path > codeberg tag blob → raw, not a clone fallback [1532.00ms]
✓ transport — single-file fast path > resolves a branch shadowed by a longer tag via the raw endpoint [1109.00ms]
842 |     expect(exitCode).toBe(0)
843 |
844 |     if (expectedTree === "(file)") {
845 |       expect(lstatSync(t).isFile()).toBe(true)
846 |     } else if (expectedTree) {
847 |       expect(getTree(t)).toBe(expectedTree)
                               ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at noPrefixClone (D:\zerostart\tests\cli.test.ts:847:26)
✗ no prefix — gitpick <url> (without clone keyword) > repo without clone prefix [2469.00ms]
✓ no prefix — gitpick <url> (without clone keyword) > tree without clone prefix [1484.00ms]
✓ no prefix — gitpick <url> (without clone keyword) > blob without clone prefix [531.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ target — gitpick <url> [target] > repo → custom dir [2313.00ms]
✓ target — gitpick <url> [target] > tree → custom dir [1531.00ms]
✓ target — gitpick <url> [target] > blob → custom dir [484.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ target — gitpick <url> [target] > repo → nested path [2422.00ms]
✓ target — gitpick <url> [target] > tree → nested path [1485.00ms]
✓ target — gitpick <url> [target] > blob → nested path [453.00ms]
✓ target — gitpick <url> [target] > blob → renamed.txt [500.00ms]
✓ target — gitpick <url> [target] > blob → nested renamed [484.00ms]
✓ target — gitpick <url> [target] > blob → absolute target [500.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── dev.txt
  ├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > -b dev shorthand [1500.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── dev.txt
  ├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > -b dev full URL [1578.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── dev.txt
  ├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > tree/dev [1750.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── dev.txt
  ├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > tree/dev URL [1516.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > -b short SHA [2484.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > /commit/ URL [2594.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ branch — gitpick <url> -b [branch/SHA] > -b full SHA [2469.00ms]
✓ branch — gitpick <url> -b [branch/SHA] > branch override [1422.00ms]
✓ branch — gitpick <url> -b [branch/SHA] > branch override URL [1484.00ms]
✓ branch — gitpick <url> -b [branch/SHA] > blob from dev branch [859.00ms]
✓ slash branch — gitpick <url>/tree/<branch-with-slash>/<path> > resolves a slash branch and its sub-path [2532.00ms]
1107 |       t,
1108 |       "--verbose",
1109 |     ])
1110 |     expect(exitCode).toBe(0)
1111 |     expect(stripAnsi(output)).toContain("@ feat/nested")
1112 |     expect(getTree(t)).toBe(TREE_REPO_NESTED)
                              ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── on-nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1112:24)
✗ slash branch — gitpick <url>/tree/<branch-with-slash>/<path> > resolves a slash branch with no sub-path (whole repo) [2500.00ms]
✓ slash branch — gitpick <url>/tree/<branch-with-slash>/<path> > re-anchors when a tag shadows a longer branch [3625.00ms]
✓ slash branch — gitpick <url>/tree/<branch-with-slash>/<path> > does not hijack a real-branch sub-path miss into a shadowing tag [1562.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ tag — gitpick <url>/tree/<tag> > clones a tag ref [1469.00ms]
1154 |   it("excludes matched paths and never copies .gitpickignore itself", async () => {
1155 |     const t = target()
1156 |     // picksuite `ignore` branch carries `.gitpickignore` (folder/deep/ + *.md)
1157 |     const { exitCode } = await run(["clone", "nrjdalal/picksuite/tree/ignore", t])
1158 |     expect(exitCode).toBe(0)
1159 |     expect(getTree(t)).toBe(TREE_IGNORE)
                              ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   └── nested.txt
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1159:24)
✗ gitpickignore — source .gitpickignore excludes paths from the copy > excludes matched paths and never copies .gitpickignore itself [1516.00ms]
✓ overwrite — gitpick <url> -o / -f > -o re-clone [3453.00ms]
✓ overwrite — gitpick <url> -o / -f > -f re-clone [3140.00ms]
✓ overwrite rejection > rejects non-empty dir without -o [1000.00ms]
✓ overwrite rejection > rejects existing blob without -o [94.00ms]
1216 |     const t = target()
1217 |     mkdirSync(t, { recursive: true })
1218 |
1219 |     const { exitCode } = await run(["clone", "nrjdalal/picksuite", t])
1220 |     expect(exitCode).toBe(0)
1221 |     expect(getTree(t)).toBe(TREE_REPO_MAIN)
                              ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1221:24)
✗ overwrite rejection > allows clone into empty dir [2500.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ recursive — gitpick <url> -r > -r shorthand [4156.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ recursive — gitpick <url> -r > -r full URL [3657.00ms]
✓ raw URL > raw.githubusercontent.com [546.00ms]
165 |   expect(exitCode).toBe(0)
166 |
167 |   if (expectedTree === "(file)") {
168 |     expect(lstatSync(t).isFile()).toBe(true)
169 |   } else if (expectedTree) {
170 |     expect(getTree(t)).toBe(expectedTree)
                             ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at cloneAndExpect (D:\zerostart\tests\cli.test.ts:170:24)
✗ token URL > public repo with token [2454.00ms]
✓ gitlab > repo [2296.00ms]
✓ gitlab > tree [2532.00ms]
✓ gitlab > blob [1109.00ms]
✓ CLI flags > --version [125.00ms]
✓ CLI flags > --help (no args) [125.00ms]
✓ CLI flags > --dry-run exits 0 without cloning [953.00ms]
✓ integrity — .git exclusion, symlinks, content > .git excluded
1339 |   it(".git excluded", () => {
1340 |     expect(existsSync(join(repoDir, ".git"))).toBe(false)
1341 |   })
1342 |
1343 |   it("symlink.txt is a symlink", () => {
1344 |     expect(lstatSync(join(repoDir, "symlink.txt")).isSymbolicLink()).toBe(true)
                                                                            ^
error: expect(received).toBe(expected)

Expected: true
Received: false

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1344:70)
✗ integrity — .git exclusion, symlinks, content > symlink.txt is a symlink
1343 |   it("symlink.txt is a symlink", () => {
1344 |     expect(lstatSync(join(repoDir, "symlink.txt")).isSymbolicLink()).toBe(true)
1345 |   })
1346 |
1347 |   it("symdir is a symlink", () => {
1348 |     expect(lstatSync(join(repoDir, "symdir")).isSymbolicLink()).toBe(true)
                                                                       ^
error: expect(received).toBe(expected)

Expected: true
Received: false

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1348:65)
✗ integrity — .git exclusion, symlinks, content > symdir is a symlink [16.00ms]
1347 |   it("symdir is a symlink", () => {
1348 |     expect(lstatSync(join(repoDir, "symdir")).isSymbolicLink()).toBe(true)
1349 |   })
1350 |
1351 |   it("symlink.txt → file.txt", () => {
1352 |     expect(readlinkSync(join(repoDir, "symlink.txt"))).toBe("file.txt")
                  ^
error: EINVAL: invalid argument, readlink '.test-artifacts\cli\1\symlink.txt'
      at <anonymous> (D:\zerostart\tests\cli.test.ts:1352:12)
✗ integrity — .git exclusion, symlinks, content > symlink.txt → file.txt
1351 |   it("symlink.txt → file.txt", () => {
1352 |     expect(readlinkSync(join(repoDir, "symlink.txt"))).toBe("file.txt")
1353 |   })
1354 |
1355 |   it("symdir → folder", () => {
1356 |     expect(readlinkSync(join(repoDir, "symdir"))).toBe("folder")
                  ^
error: EINVAL: invalid argument, readlink '.test-artifacts\cli\1\symdir'
      at <anonymous> (D:\zerostart\tests\cli.test.ts:1356:12)
✗ integrity — .git exclusion, symlinks, content > symdir → folder
✓ integrity — .git exclusion, symlinks, content > file.txt content [15.00ms]
✓ integrity — .git exclusion, symlinks, content > folder/nested.txt content [16.00ms]
✓ integrity — .git exclusion, symlinks, content > folder/deep/file.txt content [16.00ms]
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #1
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #2
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #3 [16.00ms]
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #4
✓ config — .gitpick.jsonc > entry #5
✓ config — .gitpick.jsonc > entry #6
✓ config — .gitpick.jsonc > entry #7
✓ config — .gitpick.jsonc > entry #8
✓ config — .gitpick.jsonc > entry #9
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── dev.txt
  ├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #10
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── dev.txt
  ├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #11 [15.00ms]
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #12
✓ config — .gitpick.jsonc > entry #13
1411 |       expect(existsSync(dir)).toBe(true)
1412 |       expect(readdirSync(dir).length).toBeGreaterThan(0)
1413 |
1414 |       const expected = CONFIG_TREES[i]
1415 |       if (expected) {
1416 |         expect(getTree(dir)).toBe(expected)
                                    ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1416:30)
✗ config — .gitpick.jsonc > entry #14
✓ config — .gitpick.jsonc > entry #15
✓ config — .gitpick.jsonc > entry #16
✓ --tree output > clone tree shows header and tree [1703.00ms]
1450 |     const t = target()
1451 |     const { output, exitCode } = await run(["clone", "nrjdalal/picksuite", t, "--tree"])
1452 |     expect(exitCode).toBe(0)
1453 |     const { header, tree } = parseTreeOutput(output)
1454 |     expect(header).toContain(fwd(t))
1455 |     expect(tree).toBe(TREE_REPO_MAIN)
                        ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1455:18)
✗ --tree output > clone repo shows header and full tree [2500.00ms]
✓ --tree output > no human-readable output with --tree [1750.00ms]
✓ --tree output > dry-run tree shows header and tree without leaving files [1594.00ms]
1482 |     const t = target()
1483 |     const { output, exitCode } = await run(["nrjdalal/picksuite", t, "--dry-run", "--tree"])
1484 |     expect(exitCode).toBe(0)
1485 |     const { header, tree } = parseTreeOutput(output)
1486 |     expect(header).toContain(fwd(t))
1487 |     expect(tree).toBe(TREE_REPO_MAIN)
                        ^
error: expect(received).toBe(expected)

  "├── file.txt
  ├── folder
  │   ├── deep
  │   │   └── file.txt
  │   └── nested.txt
  ├── README.md
- ├── symdir -> folder
- └── symlink.txt -> file.txt"
+ ├── symdir
+ └── symlink.txt"

- Expected  - 2
+ Received  + 2

      at <anonymous> (D:\zerostart\tests\cli.test.ts:1487:18)
✗ --tree output > dry-run repo shows header and full tree [2812.00ms]
✓ --tree output > header uses ./ for relative paths [1672.00ms]
✓ --tree output > blob shows parent dir header and file node [734.00ms]
✓ --tree output > dry-run blob shows parent dir header and file node [641.00ms]
✓ --quiet output > suppresses all output on clone [2125.00ms]
✓ --quiet output > suppresses all output on dry-run [1187.00ms]
✓ --verbose output > shows clone metadata and stats on success [1797.00ms]
✓ --verbose output > reports full clone strategy for SHA [2719.00ms]
✓ --quiet / --verbose interactions > --quiet with --tree shows tree only, no banner or spinner [1562.00ms]
✓ --quiet / --verbose interactions > --verbose with --tree shows tree but no verbose metadata [1610.00ms]
✓ --quiet / --verbose interactions > --quiet dry-run produces no output [140.00ms]
✓ --quiet / --verbose interactions > --verbose dry-run shows info line but no clone metadata [1063.00ms]
✓ env var token support > GITHUB_TOKEN is used for shorthand URLs [1140.00ms]
✓ env var token support > GH_TOKEN fallback works [969.00ms]
✓ env var token support > URL token takes precedence over env var [1031.00ms]
✓ non-TTY spinner suppression > no spinner frames in piped output [1610.00ms]
» SIGINT temp dir cleanup > cleans up temp dir on SIGINT
✓ interactive mode > should error on non-TTY with -i flag [172.00ms]
✓ interactive mode > should show -i in help text [140.00ms]
✓ --init / --commit > --help lists --init and --commit [125.00ms]
✓ --init / --commit > --init initializes a git repo for a directory clone [1672.00ms]
✓ --init / --commit > --init initializes in the parent dir for a blob clone [688.00ms]
✓ --init / --commit > --commit creates the initial commit for a directory clone [1890.00ms]
✓ --init / --commit > --auto-commit implies --init and uses the default message [1907.00ms]
✓ --init / --commit > a blob --commit stages ONLY the cloned file, not unrelated dir contents [796.00ms]
✓ --init / --commit > --init is idempotent when .git already exists [1547.00ms]
✓ --init / --commit > an empty pick never falls back to `git add .` (pre-existing files stay untracked) [1719.00ms]
✓ --init / --commit > --commit surfaces git's real error when the commit fails (missing identity) [1875.00ms]
✓ --init / --commit > refuses to init the current working directory (directory clone into '.') [1672.00ms]
✓ --init / --commit > a directory --commit into a pre-existing dir does not stage unrelated files [1922.00ms]
✓ --init / --commit > skip warnings are shown under --tree (only --quiet suppresses them) [1609.00ms]
✓ --init / --commit > commits cloned files even when a cloned .gitignore matches them [2203.00ms]
✓ --init / --commit > --commit with an empty message falls back to the default [1844.00ms]

tests\gitpick-ignore.test.ts:
✓ gitpick-ignore matcher > anchored directory pattern matches the dir, not unrelated paths
✓ gitpick-ignore matcher > dir-only pattern does not match a file of the same path
✓ gitpick-ignore matcher > basename pattern matches at any depth
✓ gitpick-ignore matcher > * stays within a segment
✓ gitpick-ignore matcher > **/ matches across segments
✓ gitpick-ignore matcher > ! re-includes a previously ignored path (last rule wins)
✓ gitpick-ignore matcher > ignores comments and blank lines
✓ gitpick-ignore matcher > anchored leading-slash pattern only matches at root
✓ copyDir honours .gitpickignore > excludes a directory and a file; never copies .gitpickignore itself [31.00ms]
✓ copyDir honours .gitpickignore > copies everything when no .gitpickignore is present [16.00ms]
✓ copyDir honours .gitpickignore > ! negation re-includes a file [31.00ms]
✓ createCopyContext anchors ignores at the picked root > excludes sub-path contents matched by the root ignore when copying a subdir [16.00ms]
✓ createCopyContext anchors ignores at the picked root > root context matches a directly-selected top-level file (loops skip these)

tests\raw-blob.test.ts:
✓ rawBlobUrl — per-host endpoints > github → raw.githubusercontent.com/{o}/{r}/{ref}/{path}
✓ rawBlobUrl — per-host endpoints > gitlab → /-/raw/{ref}/{path}
✓ rawBlobUrl — per-host endpoints > codeberg → auto-resolving /raw/{ref}/, NOT /raw/branch/
✓ rawBlobUrl — per-host endpoints > bitbucket → null (no blob type ever reaches the fast path)
✓ rawBlobUrl — per-host endpoints > unknown host → null
✓ rawBlobUrl — path & ref handling > empty path → null
✓ rawBlobUrl — path & ref handling > preserves nested path segments
✓ rawBlobUrl — path & ref handling > keeps a slash in the ref as a separator (slash branch)
✓ rawBlobUrl — path & ref handling > accepts a commit SHA as the ref
✓ rawBlobUrl — path & ref handling > URL-encodes spaces in a segment but keeps the slash
✓ rawBlobUrl — path & ref handling > URL-encodes reserved characters (# ? %)
✓ rawBlobUrl — path & ref handling > URL-encodes unicode segments
✓ rawBlobUrl — path & ref handling > URL-encodes owner and repository
✓ fetchRawBlob — short-circuits without touching the network > returns null for an unsupported host (never calls fetch)
✓ fetchRawBlob — short-circuits without touching the network > returns null for an empty path (never calls fetch)
✓ fetchRawBlob — fetch handling > writes the body and reports its byte size on 200 [63.00ms]
✓ fetchRawBlob — fetch handling > returns null and writes nothing on a 404
✓ fetchRawBlob — fetch handling > returns null on any 5xx [16.00ms]
✓ fetchRawBlob — fetch handling > returns null when fetch throws (network error)
✓ fetchRawBlob — fetch handling > creates missing parent directories for the target [16.00ms]
✓ fetchRawBlob — fetch handling > writes binary content byte-for-byte [15.00ms]
✓ fetchRawBlob — fetch handling > cleans up the temp file and returns null when the write cannot be finalized [16.00ms]
✓ fetchRawBlob — fetch handling > two concurrent fetches to the same target do not collide on the temp file [15.00ms]

tests\resolve-ref.test.ts:
✓ resolveRefFromClone anchors slash branches > matches a slash branch with no sub-path [62.00ms]
✓ resolveRefFromClone anchors slash branches > splits a slash branch from its sub-path [47.00ms]
✓ resolveRefFromClone anchors slash branches > prefers the longest matching ref [172.00ms]
✓ resolveRefFromClone anchors slash branches > keeps a single-segment branch with its path [63.00ms]
✓ resolveRefFromClone anchors slash branches > resolves a slash tag [46.00ms]
✓ resolveRefFromClone anchors slash branches > returns null when no ref matches (e.g. a commit SHA) [47.00ms]
✓ configFromUrl exposes refSegments for tree/blob URLs > github tree
✓ configFromUrl exposes refSegments for tree/blob URLs > github blob
✓ configFromUrl exposes refSegments for tree/blob URLs > github tree with no sub-path
✓ configFromUrl exposes refSegments for tree/blob URLs > gitlab tree
✓ configFromUrl exposes refSegments for tree/blob URLs > bitbucket src
✓ configFromUrl exposes refSegments for tree/blob URLs > codeberg src/branch
✓ configFromUrl exposes refSegments for tree/blob URLs > omits refSegments when -b is explicit
✓ configFromUrl exposes refSegments for tree/blob URLs > omits refSegments for repository URLs
✓ resolveRefFromRemote (picksuite) > prefers branch release/1.0 over the shadowing tag release [937.00ms]
✓ resolveRefFromRemote (picksuite) > resolves the slash branch feat/nested [907.00ms]
✓ resolveRefFromRemote (picksuite) > returns null for a commit SHA that is not a ref [843.00ms]

tests\transform-url.test.ts:
✓ configFromUrl — github > shorthand repo (with -b to stay offline)
✓ configFromUrl — github > full URL repo
✓ configFromUrl — github > strips a .git suffix
✓ configFromUrl — github > git@ SSH shorthand
✓ configFromUrl — github > tree with sub-path → type tree, default target = last segment
✓ configFromUrl — github > tree with no sub-path → default target = repository
✓ configFromUrl — github > blob → type blob, default target = '.'
✓ configFromUrl — github > commit URL → type repository at that ref
✓ configFromUrl — github > raw refs/heads → type raw
✓ configFromUrl — github > raw refs/tags → type raw
✓ configFromUrl — github > raw refs/remotes → branch keeps the remote prefix
✓ configFromUrl — github > explicit -b overrides the URL ref and drops refSegments
✓ configFromUrl — gitlab > repo
✓ configFromUrl — gitlab > tree via /-/tree/
✓ configFromUrl — gitlab > blob via /-/blob/
✓ configFromUrl — bitbucket > repo
✓ configFromUrl — bitbucket > a /src/ file is still typed as a tree (not blob)
✓ configFromUrl — bitbucket > a /src/ folder is typed as a tree
✓ configFromUrl — codeberg > repo
✓ configFromUrl — codeberg > src/branch → tree
✓ configFromUrl — codeberg > raw/branch → blob
✓ configFromUrl — codeberg > raw/tag → blob (kind discarded, ref name kept)
✓ configFromUrl — codeberg > raw/commit → blob
✓ configFromUrl — codeberg > media/branch → blob
✓ configFromUrl — token in URL > extracts an inline token and strips it from the host
✓ configFromUrl — token in URL > token is always a string (empty or the env token, never undefined)
✓ configFromUrl — target resolution > explicit target wins for every type
✓ configFromUrl — target resolution > repository default target = repository name

1 tests skipped:
» SIGINT temp dir cleanup > cleans up temp dir on SIGINT


35 tests failed:
✗ default — gitpick <url/shorthand> > shorthand repo [2375.00ms]
✗ default — gitpick <url/shorthand> > full URL repo [2375.00ms]
✗ default — gitpick <url/shorthand> > git@ repo [2328.00ms]
✗ default — gitpick <url/shorthand> > .git suffix repo [2406.00ms]
✗ no prefix — gitpick <url> (without clone keyword) > repo without clone prefix [2469.00ms]
✗ target — gitpick <url> [target] > repo → custom dir [2313.00ms]
✗ target — gitpick <url> [target] > repo → nested path [2422.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > -b dev shorthand [1500.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > -b dev full URL [1578.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > tree/dev [1750.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > tree/dev URL [1516.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > -b short SHA [2484.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > /commit/ URL [2594.00ms]
✗ branch — gitpick <url> -b [branch/SHA] > -b full SHA [2469.00ms]
✗ slash branch — gitpick <url>/tree/<branch-with-slash>/<path> > resolves a slash branch with no sub-path (whole repo) [2500.00ms]
✗ tag — gitpick <url>/tree/<tag> > clones a tag ref [1469.00ms]
✗ gitpickignore — source .gitpickignore excludes paths from the copy > excludes matched paths and never copies .gitpickignore itself [1516.00ms]
✗ overwrite rejection > allows clone into empty dir [2500.00ms]
✗ recursive — gitpick <url> -r > -r shorthand [4156.00ms]
✗ recursive — gitpick <url> -r > -r full URL [3657.00ms]
✗ token URL > public repo with token [2454.00ms]
✗ integrity — .git exclusion, symlinks, content > symlink.txt is a symlink
✗ integrity — .git exclusion, symlinks, content > symdir is a symlink [16.00ms]
✗ integrity — .git exclusion, symlinks, content > symlink.txt → file.txt
✗ integrity — .git exclusion, symlinks, content > symdir → folder
✗ config — .gitpick.jsonc > entry #1
✗ config — .gitpick.jsonc > entry #2
✗ config — .gitpick.jsonc > entry #3 [16.00ms]
✗ config — .gitpick.jsonc > entry #4
✗ config — .gitpick.jsonc > entry #10
✗ config — .gitpick.jsonc > entry #11 [15.00ms]
✗ config — .gitpick.jsonc > entry #12
✗ config — .gitpick.jsonc > entry #14
✗ --tree output > clone repo shows header and full tree [2500.00ms]
✗ --tree output > dry-run repo shows header and full tree [2812.00ms]

 214 pass
 1 skip
 35 fail
 565 expect() calls
Ran 250 tests across 5 files. [202.50s]
error: script "test" exited with code 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions