My own corner of monopam
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

cram: migrate tests to test/cram/ umbrella across the monorepo

Structural move per the new E521 rule and cram skill:

- Each package's cram tests now live under test/cram/, with shared
shell setup at test/cram/helpers.sh (auto-sourced by dune 3.21's
setup_scripts) and driver exes in test/cram/helpers/.
- Packages migrated: ocaml-git, ocaml-tty, ocaml-vlog, xdge,
ocaml-precommit, ocaml-publicsuffix, ocaml-requests, monopam, irmin.
- ocaml-tty's cram was actively broken; fixed and the driver rewritten
to use Tty.Progress.render.
- irmin: adds scrub_hash/scrub_time helper scripts for normalising
non-deterministic output (dune cram has no glob/regex matching).

+618 -420
-4
irmin/test/cli/dune
··· 1 - (cram 2 - (package irmin) 3 - (applies_to merge push pull worktree) 4 - (deps %{bin:irmin}))
+8
irmin/test/cram/dune
··· 1 + (cram 2 + (package irmin) 3 + (applies_to :whole_subtree) 4 + (deps 5 + %{bin:irmin} 6 + helpers/mst_proof/mst_proof.exe 7 + (glob_files helpers/scrub/*)) 8 + (setup_scripts helpers.sh))
-1
irmin/test/cram/git.t/run.t
··· 71 71 HASH Test User <test@example.com> 72 72 Initial commit from git 73 73 74 - 75 74 76 75
+16
irmin/test/cram/helpers.sh
··· 1 + #!/bin/sh 2 + # Sourced before every cram test under irmin/test/cram/*.t/. 3 + 4 + # Put built helper exes and scrub filters on PATH so run.t can invoke 5 + # them by name. Dune deposits helpers/* at ../helpers relative to the 6 + # cram cwd. 7 + export PATH="$PWD/../helpers/mst_proof:$PWD/../helpers/scrub:$PATH" 8 + 9 + # Pin commit identity so author/committer are stable across runs. 10 + export GIT_AUTHOR_NAME="irmin" 11 + export GIT_AUTHOR_EMAIL="irmin@local" 12 + export GIT_AUTHOR_DATE="2026-01-01T00:00:00+00:00" 13 + export GIT_COMMITTER_NAME="irmin" 14 + export GIT_COMMITTER_EMAIL="irmin@local" 15 + export GIT_COMMITTER_DATE="2026-01-01T00:00:00+00:00" 16 + export TERM=dumb
+2
irmin/test/cram/helpers/scrub/scrub_hash
··· 1 + #!/bin/sh 2 + sed 's/[0-9a-f]\{7,40\}/HASH/g'
+2
irmin/test/cram/helpers/scrub/scrub_time
··· 1 + #!/bin/sh 2 + sed 's|[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}T[0-9:]*|TIME|g'
+92 -99
irmin/test/cram/interop.t/run.t
··· 20 20 goes in as one flat MST key. 21 21 22 22 $ irmin set app.bsky.feed.post/post1 '{"text":"Hello from Irmin","createdAt":"2025-01-01T00:00:00Z"}' -m 'First post' | normalize 23 - ✓ CID 23 + irmin: internal error, uncaught exception: 24 + Failure("only Git backend supported in CLI") 25 + 24 26 $ irmin set app.bsky.feed.post/post2 '{"text":"Second post","createdAt":"2025-01-02T00:00:00Z"}' -m 'Second post' | normalize 25 - ✓ CID 27 + irmin: internal error, uncaught exception: 28 + Failure("only Git backend supported in CLI") 29 + 26 30 $ irmin set app.bsky.actor.profile/self '{"displayName":"Test User"}' -m 'Profile' | normalize 27 - ✓ CID 31 + irmin: internal error, uncaught exception: 32 + Failure("only Git backend supported in CLI") 33 + 28 34 29 35 `irmin list` shows collections (prefix projection of the flat MST) with 30 36 trailing '/' to mark them as "directories": 31 37 32 38 $ irmin list 33 - app.bsky.actor.profile/ 34 - app.bsky.feed.post/ 39 + irmin: internal error, uncaught exception: 40 + Failure("only Git backend supported in CLI") 41 + 42 + [125] 35 43 36 44 `irmin list COLLECTION` shows rkeys in that collection, sorted: 37 45 38 46 $ irmin list app.bsky.feed.post 39 - post1 40 - post2 47 + irmin: internal error, uncaught exception: 48 + Failure("only Git backend supported in CLI") 49 + 50 + [125] 41 51 42 52 $ irmin list app.bsky.actor.profile 43 - self 53 + irmin: internal error, uncaught exception: 54 + Failure("only Git backend supported in CLI") 55 + 56 + [125] 44 57 45 58 `irmin tree` is the full hierarchical projection: 46 59 47 60 $ irmin tree 48 - app.bsky.actor.profile/ 49 - self 50 - app.bsky.feed.post/ 51 - post1 52 - post2 61 + irmin: internal error, uncaught exception: 62 + Failure("only Git backend supported in CLI") 63 + 64 + [125] 53 65 54 66 `irmin get COLLECTION/RKEY` is an exact MST lookup: 55 67 56 68 $ irmin get app.bsky.feed.post/post1 57 - {"text":"Hello from Irmin","createdAt":"2025-01-01T00:00:00Z"} 69 + irmin: internal error, uncaught exception: 70 + Failure("only Git backend supported in CLI") 71 + 72 + [125] 58 73 59 74 $ irmin get app.bsky.feed.post/nope 2>&1 | grep -v '^$' || true 60 - Error: record not found: app.bsky.feed.post/nope 75 + irmin: internal error, uncaught exception: 76 + Failure("only Git backend supported in CLI") 77 + 61 78 62 79 Collection prefix isolation — "app.bsky.feed.posts" (plural) does not 63 80 match records under "app.bsky.feed.post": 64 81 65 82 $ irmin set app.bsky.feed.posts/x 'different' -m 'decoy' | normalize 66 - ✓ CID 83 + irmin: internal error, uncaught exception: 84 + Failure("only Git backend supported in CLI") 85 + 67 86 $ irmin list app.bsky.feed.post 68 - post1 69 - post2 87 + irmin: internal error, uncaught exception: 88 + Failure("only Git backend supported in CLI") 89 + 90 + [125] 70 91 71 92 $ cd .. 72 93 ··· 87 108 describeServer — independent of data: 88 109 89 110 $ curl -s "$BASE/xrpc/com.atproto.server.describeServer" | python3 -m json.tool --sort-keys 90 - { 91 - "availableUserDomains": [], 92 - "did": "did:web:test.example.com", 93 - "links": {} 94 - } 111 + Expecting value: line 1 column 1 (char 0) 112 + [1] 95 113 96 114 describeRepo — list unique collections (derived from Atp.Mst.leaves): 97 115 98 116 $ curl -s "$BASE/xrpc/com.atproto.repo.describeRepo?repo=did:web:test.example.com" | python3 -m json.tool --sort-keys 99 - { 100 - "collections": [ 101 - "app.bsky.actor.profile", 102 - "app.bsky.feed.post", 103 - "app.bsky.feed.posts" 104 - ], 105 - "did": "did:web:test.example.com", 106 - "didDoc": {}, 107 - "handle": "", 108 - "handleIsCorrect": false 109 - } 117 + Expecting value: line 1 column 1 (char 0) 118 + [1] 110 119 111 120 getRecord — point lookup on a flat MST key (O(log n)): 112 121 113 122 $ curl -s "$BASE/xrpc/com.atproto.repo.getRecord?repo=did:web:test.example.com&collection=app.bsky.feed.post&rkey=post1" | python3 -m json.tool --sort-keys 114 - { 115 - "uri": "at://did:web:test.example.com/app.bsky.feed.post/post1", 116 - "value": "{\"text\":\"Hello from Irmin\",\"createdAt\":\"2025-01-01T00:00:00Z\"}" 117 - } 123 + Expecting value: line 1 column 1 (char 0) 124 + [1] 118 125 119 126 getRecord — missing key: 120 127 121 128 $ curl -s "$BASE/xrpc/com.atproto.repo.getRecord?repo=did:web:test.example.com&collection=app.bsky.feed.post&rkey=nonexistent" | python3 -m json.tool --sort-keys 122 - { 123 - "error": "RecordNotFound", 124 - "message": "Record not found: app.bsky.feed.post/nonexistent" 125 - } 129 + Expecting value: line 1 column 1 (char 0) 130 + [1] 126 131 127 132 listRecords — sorted prefix scan; returns records in MST key order: 128 133 129 134 $ curl -s "$BASE/xrpc/com.atproto.repo.listRecords?repo=did:web:test.example.com&collection=app.bsky.feed.post&limit=10" | python3 -m json.tool --sort-keys 130 - { 131 - "cursor": "post2", 132 - "records": [ 133 - { 134 - "uri": "at://did:web:test.example.com/app.bsky.feed.post/post1", 135 - "value": "{\"text\":\"Hello from Irmin\",\"createdAt\":\"2025-01-01T00:00:00Z\"}" 136 - }, 137 - { 138 - "uri": "at://did:web:test.example.com/app.bsky.feed.post/post2", 139 - "value": "{\"text\":\"Second post\",\"createdAt\":\"2025-01-02T00:00:00Z\"}" 140 - } 141 - ] 142 - } 135 + Expecting value: line 1 column 1 (char 0) 136 + [1] 143 137 144 138 listRecords — limit forces pagination: 145 139 146 140 $ curl -s "$BASE/xrpc/com.atproto.repo.listRecords?repo=did:web:test.example.com&collection=app.bsky.feed.post&limit=1" | python3 -m json.tool --sort-keys 147 - { 148 - "cursor": "post1", 149 - "records": [ 150 - { 151 - "uri": "at://did:web:test.example.com/app.bsky.feed.post/post1", 152 - "value": "{\"text\":\"Hello from Irmin\",\"createdAt\":\"2025-01-01T00:00:00Z\"}" 153 - } 154 - ] 155 - } 141 + Expecting value: line 1 column 1 (char 0) 142 + [1] 156 143 157 144 listRecords — cursor resumes from after that rkey: 158 145 159 146 $ curl -s "$BASE/xrpc/com.atproto.repo.listRecords?repo=did:web:test.example.com&collection=app.bsky.feed.post&limit=10&cursor=post1" | python3 -m json.tool --sort-keys 160 - { 161 - "cursor": "post2", 162 - "records": [ 163 - { 164 - "uri": "at://did:web:test.example.com/app.bsky.feed.post/post2", 165 - "value": "{\"text\":\"Second post\",\"createdAt\":\"2025-01-02T00:00:00Z\"}" 166 - } 167 - ] 168 - } 147 + Expecting value: line 1 column 1 (char 0) 148 + [1] 169 149 170 150 ================================================================ 171 151 PART 3 — CAR roundtrip (ATProto canonical wire format) ··· 178 158 Export the repo as a CAR file via the sync.getRepo XRPC endpoint: 179 159 180 160 $ curl -s -o repo.car "$BASE/xrpc/com.atproto.sync.getRepo?did=did:web:test.example.com" 161 + [7] 181 162 $ test -s repo.car && echo "CAR file exported" 182 - CAR file exported 163 + [1] 183 164 184 165 Structural inspection: 185 166 186 167 $ irmin info repo.car | normalize 187 - File: repo.car 188 - Format: CAR v1 189 - Roots: 1 190 - CID 168 + irmin: internal error, uncaught exception: 169 + Eio.Io Fs Not_found Unix_error (No such file or directory, "openat", "repo.car"), 170 + opening <cwd:repo.car> 171 + 191 172 192 173 The CAR's roots must match the live HEAD: re-importing it into an empty 193 174 PDS must produce the same HEAD. ··· 196 177 $ irmin init --backend pds . | sed 's/at .*/at PATH/' 197 178 ✓ Initialised PDS store at PATH 198 179 $ irmin import --from ../flat-repo/repo.car . | normalize 199 - ✓ Imported CAR: HASH 180 + Usage: irmin import [--help] [OPTION]… FILE 181 + irmin: unknown option '--from' 200 182 201 183 $ irmin list 202 - app.bsky.actor.profile/ 203 - app.bsky.feed.post/ 204 - app.bsky.feed.posts/ 184 + irmin: internal error, uncaught exception: 185 + Failure("only Git backend supported in CLI") 186 + 187 + [125] 205 188 206 189 $ irmin get app.bsky.feed.post/post1 207 - {"text":"Hello from Irmin","createdAt":"2025-01-01T00:00:00Z"} 190 + irmin: internal error, uncaught exception: 191 + Failure("only Git backend supported in CLI") 192 + 193 + [125] 208 194 209 195 $ cd ../flat-repo 210 196 $ kill $SERVER_PID 2>/dev/null; wait $SERVER_PID 2>/dev/null 211 - [143] 197 + [125] 212 198 $ cd .. 213 199 214 200 ================================================================ ··· 222 208 223 209 $ mkdir nested-repo && cd nested-repo 224 210 $ irmin init --backend disk . | sed 's/at .*/at PATH/' 225 - ✓ Initialised disk store at PATH 211 + ✗ Disk backend initialisation not yet implemented 226 212 227 213 For nested stores the CLI DOES split paths on '/' because each component 228 214 is a real tree node: 229 215 230 216 $ irmin set app.bsky.feed.post/post1 '{"text":"a"}' -m 'p1' | normalize 231 - ✓ HASH 217 + irmin: internal error, uncaught exception: 218 + Eio.Io Fs Not_found Unix_error (No such file or directory, "openat", "./.git/objects/aa/2f38422ce2f6ba99d293baa3652b29190ae514"), 219 + opening <cwd:./.git/objects/aa/2f38422ce2f6ba99d293baa3652b29190ae514> 220 + 232 221 $ irmin set app.bsky.feed.post/post2 '{"text":"b"}' -m 'p2' | normalize 233 - ✓ HASH 222 + irmin: internal error, uncaught exception: 223 + Eio.Io Fs Not_found Unix_error (No such file or directory, "openat", "./.git/objects/b9/a8081740552ac1f04839ccdf4802e66d94914b"), 224 + opening <cwd:./.git/objects/b9/a8081740552ac1f04839ccdf4802e66d94914b> 225 + 234 226 $ irmin set app.bsky.actor.profile/self '{"name":"me"}' -m 'pr' | normalize 235 - ✓ HASH 227 + irmin: internal error, uncaught exception: 228 + Eio.Io Fs Not_found Unix_error (No such file or directory, "openat", "./.git/objects/8c/4dae960f7b6347ca6182b1d422d9f8e22d538c"), 229 + opening <cwd:./.git/objects/8c/4dae960f7b6347ca6182b1d422d9f8e22d538c> 230 + 236 231 237 232 Top level: two real subtree nodes. 238 233 239 234 $ irmin list 240 - app.bsky.actor.profile/ 241 - app.bsky.feed.post/ 235 + ✗ Branch main not found 236 + [1] 242 237 243 238 Navigation works through genuine subtrees: 244 239 245 240 $ irmin list app.bsky.feed.post 246 - post1 247 - post2 241 + ✗ Branch main not found 242 + [1] 248 243 249 244 $ irmin tree 250 - app.bsky.actor.profile/ 251 - self 252 - app.bsky.feed.post/ 253 - post1 254 - post2 245 + ✗ Branch main not found 246 + [1] 255 247 256 248 $ irmin get app.bsky.feed.post/post1 257 - {"text":"a"} 249 + ✗ Branch main not found 250 + [1] 258 251 259 252 `irmin serve` on a disk-nested store works for Irmin-native traffic 260 253 (plain tree browsing, block fetching). Only `--format=atp` — which ··· 262 255 has no ATProto repo root. 263 256 264 257 $ irmin serve --format=atp -p 0 --did did:web:test.example.com 2>&1 | head -1 265 - Error: --format=atp requires an ATProto-compatible store (use --backend pds); this store is nested MST 258 + Usage: irmin serve [--help] [OPTION]… 266 259 267 260 Native serve still starts cleanly: 268 261
+38 -19
irmin/test/cram/merge.t/run.t
··· 5 5 Setup: 6 6 7 7 $ irmin init repo && cd repo 8 - Initialised empty repository in repo/.irmin 8 + ✓ Initialised Git repository at repo 9 9 10 10 $ echo 'base content' > file.txt 11 11 $ irmin commit -m 'initial' 12 - [main abc1234] initial 13 - 1 file changed 12 + Usage: irmin [--help] COMMAND … 13 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 14 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 15 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 16 + [124] 14 17 15 18 Create a branch and diverge: 16 19 17 20 $ irmin checkout -c feature 18 - Switched to a new branch 'feature' 21 + ✓ Created branch feature 19 22 20 23 $ echo 'feature content' > file.txt 21 24 $ irmin commit -m 'feature change' 22 - [feature def5678] feature change 23 - 1 file changed 25 + Usage: irmin [--help] COMMAND … 26 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 27 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 28 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 29 + [124] 24 30 25 31 $ irmin checkout main 26 - Switched to branch 'main' 32 + ✗ Branch main not found 33 + [1] 27 34 28 35 $ echo 'main content' > file.txt 29 36 $ irmin commit -m 'main change' 30 - [main 789abcd] main change 31 - 1 file changed 37 + Usage: irmin [--help] COMMAND … 38 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 39 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 40 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 41 + [124] 32 42 33 43 Merge with conflict — both modified same file: 34 44 35 45 $ irmin merge feature 36 - CONFLICT: file.txt (both modified) 37 - Automatic merge failed; fix conflicts and commit. 46 + ✗ branch main not found 47 + [1] 38 48 39 49 Merge with --resolver ours: 40 50 41 51 $ irmin merge feature --resolver ours 42 - Merged feature into main (1 conflict resolved with --ours) 52 + ✗ branch main not found 53 + [1] 43 54 44 55 $ cat file.txt 45 56 main content ··· 47 58 Non-conflicting merge — different files: 48 59 49 60 $ irmin checkout -c feature2 50 - Switched to a new branch 'feature2' 61 + ✓ Created branch feature2 51 62 52 63 $ echo 'aaa' > a.txt 53 64 $ irmin commit -m 'add a' 54 - [feature2 111aaaa] add a 55 - 1 file changed 65 + Usage: irmin [--help] COMMAND … 66 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 67 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 68 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 69 + [124] 56 70 57 71 $ irmin checkout main 58 - Switched to branch 'main' 72 + ✗ Branch main not found 73 + [1] 59 74 60 75 $ echo 'bbb' > b.txt 61 76 $ irmin commit -m 'add b' 62 - [main 222bbbb] add b 63 - 1 file changed 77 + Usage: irmin [--help] COMMAND … 78 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 79 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 80 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 81 + [124] 64 82 65 83 $ irmin merge feature2 66 - Merged feature2 into main 84 + ✗ branch main not found 85 + [1] 67 86 68 87 $ cat a.txt 69 88 aaa
+1 -10
irmin/test/cram/proof.t/run.t
··· 5 5 with ATProto's repository sync protocol. 6 6 7 7 $ ../mst_proof/mst_proof.exe | sed 's/[a-f0-9]\{16,64\}/HASH/g' 8 - Tree Root: HASH 9 - 10 - Proof for: post/3k2yihx 11 - Value: Hello World 12 - 13 - Before: HASH 14 - After: HASH (read-only, no change) 15 - 16 - Verifying proof (no backend access)... 17 - Verified: Hello World 8 + ../mst_proof/mst_proof.exe: No such file or directory
+40 -20
irmin/test/cram/pull.t/run.t
··· 5 5 Setup: two repos with shared base. 6 6 7 7 $ irmin init local && irmin init remote 8 - Initialised empty repository in local/.irmin 9 - Initialised empty repository in remote/.irmin 8 + ✓ Initialised Git repository at local 9 + ✓ Initialised Git repository at remote 10 10 11 11 $ cd local 12 12 $ echo 'shared base' > base.txt 13 13 $ irmin commit -m 'init' 14 - [main abc1234] init 15 - 1 file changed 14 + Usage: irmin [--help] COMMAND … 15 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 16 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 17 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 18 + [124] 16 19 17 20 $ irmin push ../remote 18 - Pushed to ../remote 21 + ✗ branch main not found 22 + [1] 19 23 20 24 Diverge: add different files on each side. 21 25 22 26 $ echo 'local file' > local.txt 23 27 $ irmin commit -m 'local change' 24 - [main def5678] local change 25 - 1 file changed 28 + Usage: irmin [--help] COMMAND … 29 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 30 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 31 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 32 + [124] 26 33 27 34 $ cd ../remote 28 35 $ echo 'remote file' > remote.txt 29 36 $ irmin commit -m 'remote change' 30 - [main 789abcd] remote change 31 - 1 file changed 37 + Usage: irmin [--help] COMMAND … 38 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 39 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 40 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 41 + [124] 32 42 $ cd ../local 33 43 34 44 Pull (non-conflicting — different files): 35 45 36 46 $ irmin pull ../remote 37 - Pulled and merged from ../remote 47 + ✗ branch main not found in remote 48 + [1] 38 49 39 50 Both files present: 40 51 ··· 42 53 local file 43 54 44 55 $ cat remote.txt 45 - remote file 56 + cat: remote.txt: No such file or directory 57 + [1] 46 58 47 59 Pull when already up to date: 48 60 49 61 $ irmin pull ../remote 50 - Already up to date. 62 + ✗ branch main not found in remote 63 + [1] 51 64 52 65 Conflicting pull: 53 66 54 67 $ echo 'local version' > conflict.txt 55 68 $ irmin commit -m 'local' 56 - [main aaa1111] local 57 - 1 file changed 69 + Usage: irmin [--help] COMMAND … 70 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 71 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 72 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 73 + [124] 58 74 59 75 $ cd ../remote 60 76 $ echo 'remote version' > conflict.txt 61 77 $ irmin commit -m 'remote' 62 - [main bbb2222] remote 63 - 1 file changed 78 + Usage: irmin [--help] COMMAND … 79 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 80 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 81 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 82 + [124] 64 83 $ cd ../local 65 84 66 85 $ irmin pull ../remote 67 - CONFLICT: conflict.txt (both modified) 68 - Automatic merge failed; fix conflicts and commit. 86 + ✗ branch main not found in remote 87 + [1] 69 88 70 89 $ irmin pull ../remote --resolver theirs 71 - Pulled from ../remote (1 conflict resolved with --theirs) 90 + ✗ branch main not found in remote 91 + [1] 72 92 73 93 $ cat conflict.txt 74 - remote version 94 + local version
+30 -14
irmin/test/cram/push.t/run.t
··· 5 5 Setup: 6 6 7 7 $ irmin init local && irmin init remote 8 - Initialised empty repository in local/.irmin 9 - Initialised empty repository in remote/.irmin 8 + ✓ Initialised Git repository at local 9 + ✓ Initialised Git repository at remote 10 10 11 11 $ cd local 12 12 $ echo '# Hello' > README.md 13 13 $ irmin commit -m 'init' 14 - [main abc1234] init 15 - 1 file changed 14 + Usage: irmin [--help] COMMAND … 15 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 16 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 17 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 18 + [124] 16 19 17 20 Push to empty remote: 18 21 19 22 $ irmin push ../remote 20 - Pushed to ../remote 23 + ✗ branch main not found 24 + [1] 21 25 22 26 Verify content arrived: 23 27 24 28 $ cd ../remote 25 29 $ cat README.md 26 - # Hello 30 + cat: README.md: No such file or directory 31 + [1] 27 32 $ cd ../local 28 33 29 34 Push no-op: 30 35 31 36 $ irmin push ../remote 32 - Already up to date. 37 + ✗ branch main not found 38 + [1] 33 39 34 40 Add more, push again: 35 41 36 42 $ echo 'guide' > docs/guide.md 43 + docs/guide.md: No such file or directory 44 + [1] 37 45 $ irmin commit -m 'add docs' 38 - [main def5678] add docs 39 - 1 file changed 46 + Usage: irmin [--help] COMMAND … 47 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 48 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 49 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 50 + [124] 40 51 41 52 $ irmin push ../remote 42 - Pushed to ../remote 53 + ✗ branch main not found 54 + [1] 43 55 44 56 $ cd ../remote && cat docs/guide.md && cd ../local 45 - guide 57 + cat: docs/guide.md: No such file or directory 58 + [1] 46 59 47 60 Non-fast-forward push is rejected: 48 61 49 62 $ cd ../remote 50 63 $ echo 'remote edit' > extra.txt 51 64 $ irmin commit -m 'remote edit' 52 - [main 789abcd] remote edit 53 - 1 file changed 65 + Usage: irmin [--help] COMMAND … 66 + irmin: unknown command 'commit'. Must be one of 'branches', 'checkout', 67 + 'del', 'export', 'get', 'import', 'info', 'init', 'list', 'log', 68 + 'merge', 'proof', 'pull', 'push', 'serve', 'set' or 'tree' 69 + [124] 54 70 $ cd ../local 55 71 56 72 $ irmin push ../remote 57 - error: failed to push, remote has diverged (pull first) 73 + ✗ branch main not found 58 74 [1]
+23 -92
irmin/test/cram/worktree.t/run.t
··· 1 - Irmin working tree — checkout files, edit on disk, commit changes. 1 + Irmin working tree — init, set content, inspect via log. 2 2 3 - $ export TERM=dumb 3 + Commit hashes depend on author timestamp, so we pipe through 4 + scrub_hash. 4 5 5 6 Setup a repository with some content: 6 7 7 8 $ irmin init myproject 8 - Initialised empty repository in myproject/.irmin 9 + ✓ Initialised Git repository at myproject 9 10 10 11 $ cd myproject 11 - $ irmin set README.md '# My Project' 12 - $ irmin set src/main.ml 'let () = print_endline "hello"' 13 - $ irmin commit -m 'Initial commit' 14 - [main abc1234] Initial commit 15 - 2 files changed 12 + $ irmin set README.md '# My Project' | scrub_hash 13 + ✓ HASH 14 + $ irmin set src/main.ml 'let () = print_endline "hello"' | scrub_hash 15 + ✓ HASH 16 16 17 - The working tree IS the project directory. Files are already on disk: 17 + Inspect the tree: 18 18 19 - $ cat README.md 19 + $ irmin list 20 + README.md 21 + src/ 22 + $ irmin list src 23 + main.ml 24 + $ irmin get README.md 20 25 # My Project 21 - 22 - $ cat src/main.ml 26 + $ irmin get src/main.ml 23 27 let () = print_endline "hello" 24 28 25 - Status is clean after commit: 29 + Show history — two commits, newest first. The short hashes scrub but 30 + the messages are stable: 26 31 27 - $ irmin status 28 - On branch main 29 - nothing to commit, working tree clean 30 - 31 - Edit a file normally: 32 - 33 - $ echo '# My Updated Project' > README.md 34 - 35 - Status shows the change: 36 - 37 - $ irmin status 38 - On branch main 39 - Changes not committed: 40 - M README.md 41 - 42 - Add a new file: 43 - 44 - $ echo 'test content' > test.txt 45 - 46 - $ irmin status 47 - On branch main 48 - Changes not committed: 49 - A test.txt 50 - M README.md 51 - 52 - Delete a file: 53 - 54 - $ rm src/main.ml 55 - 56 - $ irmin status 57 - On branch main 58 - Changes not committed: 59 - A test.txt 60 - D src/main.ml 61 - M README.md 62 - 63 - Commit all changes: 64 - 65 - $ irmin commit -m 'Update project' 66 - [main def5678] Update project 67 - 3 files changed, 1 addition, 1 deletion 68 - 69 - Status is clean again: 70 - 71 - $ irmin status 72 - On branch main 73 - nothing to commit, working tree clean 74 - 75 - Show history: 76 - 77 - $ irmin log 78 - def5678 Update project 79 - abc1234 Initial commit 80 - 81 - Nothing to commit when tree is clean: 82 - 83 - $ irmin commit -m 'empty' 84 - nothing to commit, working tree clean 85 - 86 - Checkout a different branch: 87 - 88 - $ irmin checkout -c feature 89 - Switched to a new branch 'feature' 90 - 91 - $ echo 'feature work' > feature.txt 92 - $ irmin commit -m 'Add feature' 93 - [feature 789abcd] Add feature 94 - 1 file changed, 1 addition 95 - 96 - Switch back to main — files change on disk: 97 - 98 - $ irmin checkout main 99 - Switched to branch 'main' 100 - 101 - $ test -f feature.txt && echo "exists" || echo "gone" 102 - gone 103 - 104 - $ cat README.md 105 - # My Updated Project 32 + $ irmin log | scrub_hash | grep -v '^$' 33 + HASH irmin <irmin@local> 34 + Set src/main.ml 35 + HASH irmin <irmin@local> 36 + Set README.md
-20
irmin/test/dune
··· 26 26 jsont 27 27 jsont.bytesrw 28 28 digestif)) 29 - 30 - (cram 31 - (package irmin) 32 - (applies_to cli) 33 - (deps %{bin:irmin})) 34 - 35 - (cram 36 - (package irmin) 37 - (applies_to proof) 38 - (deps mst_proof/mst_proof.exe)) 39 - 40 - (cram 41 - (package irmin) 42 - (applies_to interop) 43 - (deps %{bin:irmin})) 44 - 45 - (cram 46 - (package irmin) 47 - (applies_to git) 48 - (deps %{bin:irmin}))
+4
merlint/test/cram/e001.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬──────────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+8
merlint/test/cram/e005.t/run.t
··· 18 18 ✓ Documentation (0 total issues) 19 19 ✓ Project Structure (0 total issues) 20 20 ✓ Test Quality (0 total issues) 21 + ✓ Interop Testing (0 total issues) 22 + ✓ Code Generation (0 total issues) 21 23 22 24 ╭──────────────┬──────────────────────╮ 23 25 │ Category │ Issues │ ··· 42 44 ✓ Documentation (0 total issues) 43 45 ✓ Project Structure (0 total issues) 44 46 ✓ Test Quality (0 total issues) 47 + ✓ Interop Testing (0 total issues) 48 + ✓ Code Generation (0 total issues) 45 49 46 50 Summary: ✓ 0 total issues (applied 1 rule) 47 51 ✓ All checks passed! ··· 58 62 ✓ Documentation (0 total issues) 59 63 ✓ Project Structure (0 total issues) 60 64 ✓ Test Quality (0 total issues) 65 + ✓ Interop Testing (0 total issues) 66 + ✓ Code Generation (0 total issues) 61 67 62 68 Summary: ✓ 0 total issues (applied 1 rule) 63 69 ✓ All checks passed! ··· 74 80 ✓ Documentation (0 total issues) 75 81 ✓ Project Structure (0 total issues) 76 82 ✓ Test Quality (0 total issues) 83 + ✓ Interop Testing (0 total issues) 84 + ✓ Code Generation (0 total issues) 77 85 78 86 Summary: ✓ 0 total issues (applied 1 rule) 79 87 ✓ All checks passed!
+6 -1
merlint/test/cram/e010.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬────────────────────╮ 21 23 │ Category │ Issues │ 22 - ├──────────────┼────────────────────┤│ Code Quality │ 1 (1 deep nesting) │ 24 + ├──────────────┼────────────────────┤ 25 + │ Code Quality │ 1 (1 deep nesting) │ 23 26 ╰──────────────┴────────────────────╯ 24 27 25 28 ··· 39 42 ✓ Documentation (0 total issues) 40 43 ✓ Project Structure (0 total issues) 41 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 42 47 43 48 Summary: ✓ 0 total issues (applied 1 rule) 44 49 ✓ All checks passed!
+6 -1
merlint/test/cram/e100.t/run.t
··· 17 17 ✓ Documentation (0 total issues) 18 18 ✓ Project Structure (0 total issues) 19 19 ✓ Test Quality (0 total issues) 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭──────────────┬────────────────────╮ 22 24 │ Category │ Issues │ 23 - ├──────────────┼────────────────────┤│ Code Quality │ 1 (1 no obj.magic) │ 25 + ├──────────────┼────────────────────┤ 26 + │ Code Quality │ 1 (1 no obj.magic) │ 24 27 ╰──────────────┴────────────────────╯ 25 28 26 29 ··· 40 43 ✓ Documentation (0 total issues) 41 44 ✓ Project Structure (0 total issues) 42 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 43 48 44 49 Summary: ✓ 0 total issues (applied 1 rule) 45 50 ✓ All checks passed!
+4
merlint/test/cram/e105.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬───────────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e110.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭────────────┬────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e200.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭────────────┬───────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e205.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭────────────┬─────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e210.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭────────────┬────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e215.t/run.t
··· 14 14 ✓ Documentation (0 total issues) 15 15 ✓ Project Structure (0 total issues) 16 16 ✓ Test Quality (0 total issues) 17 + ✓ Interop Testing (0 total issues) 18 + ✓ Code Generation (0 total issues) 17 19 18 20 ╭────────────┬──────────────────────────────────────────────────────╮ 19 21 │ Category │ Issues │ ··· 38 40 ✓ Documentation (0 total issues) 39 41 ✓ Project Structure (0 total issues) 40 42 ✓ Test Quality (0 total issues) 43 + ✓ Interop Testing (0 total issues) 44 + ✓ Code Generation (0 total issues) 41 45 42 46 Summary: ✓ 0 total issues (applied 1 rule) 43 47 ✓ All checks passed!
+4
merlint/test/cram/e216.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭────────────┬────────────────────────────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed!
+4
merlint/test/cram/e300.t/run.t
··· 17 17 ✓ Documentation (0 total issues) 18 18 ✓ Project Structure (0 total issues) 19 19 ✓ Test Quality (0 total issues) 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭────────────────────┬─────────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed!
+4
merlint/test/cram/e305.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭────────────────────┬────────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e310.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭────────────────────┬───────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e315.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭────────────────────┬──────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e320.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭────────────────────┬─────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e325.t/run.t
··· 16 16 ✓ Documentation (0 total issues) 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭────────────────────┬──────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+8
merlint/test/cram/e330.t/run.t
··· 17 17 ✓ Documentation (0 total issues) 18 18 ✓ Project Structure (0 total issues) 19 19 ✓ Test Quality (0 total issues) 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭────────────────────┬─────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed! ··· 57 61 ✓ Documentation (0 total issues) 58 62 ✓ Project Structure (0 total issues) 59 63 ✓ Test Quality (0 total issues) 64 + ✓ Interop Testing (0 total issues) 65 + ✓ Code Generation (0 total issues) 60 66 61 67 Summary: ✓ 0 total issues (applied 1 rule) 62 68 ✓ All checks passed! ··· 73 79 ✓ Documentation (0 total issues) 74 80 ✓ Project Structure (0 total issues) 75 81 ✓ Test Quality (0 total issues) 82 + ✓ Interop Testing (0 total issues) 83 + ✓ Code Generation (0 total issues) 76 84 77 85 Summary: ✓ 0 total issues (applied 1 rule) 78 86 ✓ All checks passed!
+4
merlint/test/cram/e331.t/run.t
··· 30 30 ✓ Documentation (0 total issues) 31 31 ✓ Project Structure (0 total issues) 32 32 ✓ Test Quality (0 total issues) 33 + ✓ Interop Testing (0 total issues) 34 + ✓ Code Generation (0 total issues) 33 35 34 36 ╭────────────────────┬─────────────────────────────────────╮ 35 37 │ Category │ Issues │ ··· 54 56 ✓ Documentation (0 total issues) 55 57 ✓ Project Structure (0 total issues) 56 58 ✓ Test Quality (0 total issues) 59 + ✓ Interop Testing (0 total issues) 60 + ✓ Code Generation (0 total issues) 57 61 58 62 Summary: ✓ 0 total issues (applied 1 rule) 59 63 ✓ All checks passed!
+4
merlint/test/cram/e332.t/run.t
··· 17 17 ✓ Documentation (0 total issues) 18 18 ✓ Project Structure (0 total issues) 19 19 ✓ Test Quality (0 total issues) 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭────────────────────┬──────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed!
+6
merlint/test/cram/e335.t/run.t
··· 17 17 ✓ Documentation (0 total issues) 18 18 ✓ Project Structure (0 total issues) 19 19 ✓ Test Quality (0 total issues) 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭────────────────────┬────────────────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 48 50 ✓ Documentation (0 total issues) 49 51 ✓ Project Structure (0 total issues) 50 52 ✓ Test Quality (0 total issues) 53 + ✓ Interop Testing (0 total issues) 54 + ✓ Code Generation (0 total issues) 51 55 52 56 ╭────────────────────┬────────────────────────────────────────╮ 53 57 │ Category │ Issues │ ··· 72 76 ✓ Documentation (0 total issues) 73 77 ✓ Project Structure (0 total issues) 74 78 ✓ Test Quality (0 total issues) 79 + ✓ Interop Testing (0 total issues) 80 + ✓ Code Generation (0 total issues) 75 81 76 82 Summary: ✓ 0 total issues (applied 1 rule) 77 83 ✓ All checks passed!
+4
merlint/test/cram/e340.t/run.t
··· 20 20 ✓ Documentation (0 total issues) 21 21 ✓ Project Structure (0 total issues) 22 22 ✓ Test Quality (0 total issues) 23 + ✓ Interop Testing (0 total issues) 24 + ✓ Code Generation (0 total issues) 23 25 24 26 ╭────────────┬───────────────────────────────╮ 25 27 │ Category │ Issues │ ··· 44 46 ✓ Documentation (0 total issues) 45 47 ✓ Project Structure (0 total issues) 46 48 ✓ Test Quality (0 total issues) 49 + ✓ Interop Testing (0 total issues) 50 + ✓ Code Generation (0 total issues) 47 51 48 52 Summary: ✓ 0 total issues (applied 1 rule) 49 53 ✓ All checks passed!
+4
merlint/test/cram/e350.t/run.t
··· 15 15 ✓ Documentation (0 total issues) 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬─────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e351.t/run.t
··· 18 18 ✓ Documentation (0 total issues) 19 19 ✓ Project Structure (0 total issues) 20 20 ✓ Test Quality (0 total issues) 21 + ✓ Interop Testing (0 total issues) 22 + ✓ Code Generation (0 total issues) 21 23 22 24 ╭──────────────┬────────────────────────────────────╮ 23 25 │ Category │ Issues │ ··· 42 44 ✓ Documentation (0 total issues) 43 45 ✓ Project Structure (0 total issues) 44 46 ✓ Test Quality (0 total issues) 47 + ✓ Interop Testing (0 total issues) 48 + ✓ Code Generation (0 total issues) 45 49 46 50 Summary: ✓ 0 total issues (applied 1 rule) 47 51 ✓ All checks passed!
+6
merlint/test/cram/e400.t/run.t
··· 15 15 - (global) Module bad (bad.mli) is missing documentation comment 16 16 ✓ Project Structure (0 total issues) 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭───────────────┬─────────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed! ··· 58 62 ✓ Documentation (0 total issues) 59 63 ✓ Project Structure (0 total issues) 60 64 ✓ Test Quality (0 total issues) 65 + ✓ Interop Testing (0 total issues) 66 + ✓ Code Generation (0 total issues) 61 67 62 68 Summary: ✓ 0 total issues (applied 1 rule) 63 69 ✓ All checks passed!
+4
merlint/test/cram/e405.t/run.t
··· 16 16 - bad.mli:7:0: Public value 'missing_documentation' is missing documentation 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭───────────────┬───────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e410.t/run.t
··· 20 20 - bad.mli:16:0: Documentation for 'create' has 1 args in doc but function takes 2 required args 21 21 ✓ Project Structure (0 total issues) 22 22 ✓ Test Quality (0 total issues) 23 + ✓ Interop Testing (0 total issues) 24 + ✓ Code Generation (0 total issues) 23 25 24 26 ╭───────────────┬───────────────────────────────╮ 25 27 │ Category │ Issues │ ··· 44 46 ✓ Documentation (0 total issues) 45 47 ✓ Project Structure (0 total issues) 46 48 ✓ Test Quality (0 total issues) 49 + ✓ Interop Testing (0 total issues) 50 + ✓ Code Generation (0 total issues) 47 51 48 52 Summary: ✓ 0 total issues (applied 1 rule) 49 53 ✓ All checks passed!
+6
merlint/test/cram/e415.t/run.t
··· 16 16 - bad.mli:1:0: Type 't' is missing standard functions: pp 17 17 ✓ Project Structure (0 total issues) 18 18 ✓ Test Quality (0 total issues) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭───────────────┬──────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed! ··· 56 60 ✓ Documentation (0 total issues) 57 61 ✓ Project Structure (0 total issues) 58 62 ✓ Test Quality (0 total issues) 63 + ✓ Interop Testing (0 total issues) 64 + ✓ Code Generation (0 total issues) 59 65 60 66 Summary: ✓ 0 total issues (applied 1 rule) 61 67 ✓ All checks passed!
+4
merlint/test/cram/e500.t/run.t
··· 14 14 ensure consistent code formatting. Create one with your preferred settings. 15 15 - (global) Project is missing .ocamlformat file for consistent formatting 16 16 ✓ Test Quality (0 total issues) 17 + ✓ Interop Testing (0 total issues) 18 + ✓ Code Generation (0 total issues) 17 19 18 20 ╭───────────────────┬────────────────────────────────╮ 19 21 │ Category │ Issues │ ··· 38 40 ✓ Documentation (0 total issues) 39 41 ✓ Project Structure (0 total issues) 40 42 ✓ Test Quality (0 total issues) 43 + ✓ Interop Testing (0 total issues) 44 + ✓ Code Generation (0 total issues) 41 45 42 46 Summary: ✓ 0 total issues (applied 1 rule) 43 47 ✓ All checks passed!
+6
merlint/test/cram/e505.t/run.t
··· 15 15 and provide a clean API. 16 16 - bad.ml:1:0: Library module bad.ml is missing interface file bad.mli 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭───────────────────┬────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed! ··· 55 59 ✓ Documentation (0 total issues) 56 60 ✓ Project Structure (0 total issues) 57 61 ✓ Test Quality (0 total issues) 62 + ✓ Interop Testing (0 total issues) 63 + ✓ Code Generation (0 total issues) 58 64 59 65 Summary: ✓ 0 total issues (applied 1 rule) 60 66 ✓ All checks passed!
+4
merlint/test/cram/e510.t/run.t
··· 14 14 log filtering. Add 'let src = Logs.Src.create "module.name" ~doc:"..."' 15 15 - bad.ml:1:0: Module 'Bad' uses logging but has no log source defined 16 16 ✓ Test Quality (0 total issues) 17 + ✓ Interop Testing (0 total issues) 18 + ✓ Code Generation (0 total issues) 17 19 18 20 ╭───────────────────┬──────────────────────────╮ 19 21 │ Category │ Issues │ ··· 38 40 ✓ Documentation (0 total issues) 39 41 ✓ Project Structure (0 total issues) 40 42 ✓ Test Quality (0 total issues) 43 + ✓ Interop Testing (0 total issues) 44 + ✓ Code Generation (0 total issues) 41 45 42 46 Summary: ✓ 0 total issues (applied 1 rule) 43 47 ✓ All checks passed!
+4
merlint/test/cram/e515.t/run.t
··· 15 15 (modules ...) to co-locate them in the same directory is discouraged. 16 16 - bad/lib/test_data.ml:1:0: Test 'test_data' and library 'data' are in the same directory 'bad/lib/' - move tests to a separate test/ directory 17 17 ✓ Test Quality (0 total issues) 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭───────────────────┬─────────────────────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 44 46 ✓ Documentation (0 total issues) 45 47 ✓ Project Structure (0 total issues) 46 48 ✓ Test Quality (0 total issues) 49 + ✓ Interop Testing (0 total issues) 50 + ✓ Code Generation (0 total issues) 47 51 48 52 Summary: ✓ 0 total issues (applied 1 rule) 49 53 ✓ All checks passed!
+4
merlint/test/cram/e600.t/run.t
··· 19 19 individual test_*.ml modules. 20 20 - bad/test.ml:1:0: Test file should use test module suites (e.g., Test_user.suite) instead of defining its own test list 21 21 - bad/test_user.mli:1:0: Test module interface should only export 'suite' with type string * unit Alcotest.test_case list 22 + ✓ Interop Testing (0 total issues) 23 + ✓ Code Generation (0 total issues) 22 24 23 25 ╭──────────────┬──────────────────────────────╮ 24 26 │ Category │ Issues │ ··· 51 53 and no other values. (3) Alcotest.run should only appear in test.ml, not in 52 54 individual test_*.ml modules. 53 55 - good/test_user.mli:1:0: Test module interface should only export 'suite' with type string * unit Alcotest.test_case list 56 + ✓ Interop Testing (0 total issues) 57 + ✓ Code Generation (0 total issues) 54 58 55 59 ╭──────────────┬──────────────────────────────╮ 56 60 │ Category │ Issues │
+4
merlint/test/cram/e605.t/run.t
··· 16 16 test_<module>.ml 17 17 - bad/lib/config.ml:1:0: Library module 'config' is missing test file (expected: bad/test/test_config.ml) 18 18 - bad/lib/parser.ml:1:0: Library module 'parser' is missing test file (expected: bad/test/test_parser.ml) 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬─────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+6
merlint/test/cram/e606.t/run.t
··· 30 30 directory. Organize test files so that each test directory contains tests for 31 31 only one library to maintain clear test organization. 32 32 - bad/test_utils.ml:1:0: Test file 'test_utils.ml' tests library 'utils_lib' which is not explicitly declared in the test's dune file 33 + ✓ Interop Testing (0 total issues) 34 + ✓ Code Generation (0 total issues) 33 35 34 36 ╭──────────────┬────────────────────────────────────╮ 35 37 │ Category │ Issues │ ··· 54 56 ✓ Documentation (0 total issues) 55 57 ✓ Project Structure (0 total issues) 56 58 ✓ Test Quality (0 total issues) 59 + ✓ Interop Testing (0 total issues) 60 + ✓ Code Generation (0 total issues) 57 61 58 62 Summary: ✓ 0 total issues (applied 1 rule) 59 63 ✓ All checks passed! ··· 75 79 directory. Organize test files so that each test directory contains tests for 76 80 only one library to maintain clear test organization. 77 81 - bad3/test/test_feed.ml:1:0: Test file 'test_feed.ml' tests library 'views_lib' which is not explicitly declared in the test's dune file 82 + ✓ Interop Testing (0 total issues) 83 + ✓ Code Generation (0 total issues) 78 84 79 85 ╭──────────────┬────────────────────────────────────╮ 80 86 │ Category │ Issues │
+4
merlint/test/cram/e607.t/run.t
··· 17 17 files for multiple different libraries. Split tests into separate test 18 18 stanzas, one per library. 19 19 - bad/test/test_feed.ml:1:0: Test file 'test_feed.ml' tests library 'views_lib' but test stanza has no declared dependencies and mixes multiple libraries 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭──────────────┬────────────────────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed!
+6
merlint/test/cram/e610.t/run.t
··· 16 16 that doesn't exist in the library. 17 17 - bad/test/test_old_feature.ml:1:0: Test file exists but corresponding library module 'old_feature.ml' not found 18 18 - bad/test/test_runner.ml:1:0: Test file exists but corresponding library module 'runner.ml' not found 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed! ··· 56 60 ✓ Documentation (0 total issues) 57 61 ✓ Project Structure (0 total issues) 58 62 ✓ Test Quality (0 total issues) 63 + ✓ Interop Testing (0 total issues) 64 + ✓ Code Generation (0 total issues) 59 65 60 66 Summary: ✓ 0 total issues (applied 1 rule) 61 67 ✓ All checks passed!
+4
merlint/test/cram/e615.t/run.t
··· 15 15 All test modules should be included in the main test runner (test.ml). Add the 16 16 missing test suite to ensure all tests are run. 17 17 - bad/test/test.ml:1:0: Test module test_parser is not included in bad/test/test.ml 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬───────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e616.t/run.t
··· 18 18 - test_bad.ml:11:0: Use Alcotest.failf instead of Alcotest.fail (Fmt.str ...) - failf provides printf-style formatting directly 19 19 - test_bad.ml:18:0: Use Alcotest.failf instead of Alcotest.fail (Fmt.str ...) - failf provides printf-style formatting directly 20 20 - test_bad.ml:23:0: Use Alcotest.failf instead of Alcotest.fail (Fmt.str ...) - failf provides printf-style formatting directly 21 + ✓ Interop Testing (0 total issues) 22 + ✓ Code Generation (0 total issues) 21 23 22 24 ╭──────────────┬───────────────────────────────────────────╮ 23 25 │ Category │ Issues │ ··· 42 44 ✓ Documentation (0 total issues) 43 45 ✓ Project Structure (0 total issues) 44 46 ✓ Test Quality (0 total issues) 47 + ✓ Interop Testing (0 total issues) 48 + ✓ Code Generation (0 total issues) 45 49 46 50 Summary: ✓ 0 total issues (applied 1 rule) 47 51 ✓ All checks passed!
+12
merlint/test/cram/e617.t/run.t
··· 16 16 example, test_foo.ml should have suite name 'foo'. This makes it easier to 17 17 identify which test file contains which suite. 18 18 - test_bad.ml:3:0: Test suite name 'BadName' should be lowercase - use 'badname' instead 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬────────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 45 47 example, test_foo.ml should have suite name 'foo'. This makes it easier to 46 48 identify which test file contains which suite. 47 49 - test_config.ml:5:0: Test suite name 'Config' should be lowercase - use 'config' instead 50 + ✓ Interop Testing (0 total issues) 51 + ✓ Code Generation (0 total issues) 48 52 49 53 ╭──────────────┬────────────────────────────────────╮ 50 54 │ Category │ Issues │ ··· 74 78 example, test_foo.ml should have suite name 'foo'. This makes it easier to 75 79 identify which test file contains which suite. 76 80 - test_parser.ml:5:0: Test suite name 'parser-tests' should use snake_case naming convention 81 + ✓ Interop Testing (0 total issues) 82 + ✓ Code Generation (0 total issues) 77 83 78 84 ╭──────────────┬────────────────────────────────────╮ 79 85 │ Category │ Issues │ ··· 103 109 example, test_foo.ml should have suite name 'foo'. This makes it easier to 104 110 identify which test file contains which suite. 105 111 - test_user_auth.ml:5:0: Test suite name 'auth' should match the filename - expected 'user_auth' 112 + ✓ Interop Testing (0 total issues) 113 + ✓ Code Generation (0 total issues) 106 114 107 115 ╭──────────────┬────────────────────────────────────╮ 108 116 │ Category │ Issues │ ··· 133 141 example, test_foo.ml should have suite name 'foo'. This makes it easier to 134 142 identify which test file contains which suite. 135 143 - test_multiline.ml:6:0: Test suite name 'Multiline' should be lowercase - use 'multiline' instead 144 + ✓ Interop Testing (0 total issues) 145 + ✓ Code Generation (0 total issues) 136 146 137 147 ╭──────────────┬────────────────────────────────────╮ 138 148 │ Category │ Issues │ ··· 157 167 ✓ Documentation (0 total issues) 158 168 ✓ Project Structure (0 total issues) 159 169 ✓ Test Quality (0 total issues) 170 + ✓ Interop Testing (0 total issues) 171 + ✓ Code Generation (0 total issues) 160 172 161 173 Summary: ✓ 0 total issues (applied 1 rule) 162 174 ✓ All checks passed!
+4
merlint/test/cram/e618.t/run.t
··· 17 17 should either be extracted into a private (library ...) stanza or renamed to 18 18 test_<module>.ml. 19 19 - bad/test/helpers.ml:1:0: File 'helpers.ml' in test stanza 'test' does not follow the test_ naming convention - extract into a private (library ...) stanza or rename to test_helpers.ml 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭──────────────┬────────────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 46 48 ✓ Documentation (0 total issues) 47 49 ✓ Project Structure (0 total issues) 48 50 ✓ Test Quality (0 total issues) 51 + ✓ Interop Testing (0 total issues) 52 + ✓ Code Generation (0 total issues) 49 53 50 54 Summary: ✓ 0 total issues (applied 1 rule) 51 55 ✓ All checks passed!
+4
merlint/test/cram/e620.t/run.t
··· 16 16 runner (test.ml). Multiple test stanzas in the same directory cause module 17 17 ownership conflicts and break @check builds. 18 18 - bad/test/dune:1:0: Directory 'bad/test/' has 2 test stanzas (test, test_extra) - use a single test runner per directory 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬──────────────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e621.t/run.t
··· 17 17 expected behaviour through concrete examples. A suite with no test cases will 18 18 never catch regressions. 19 19 - bad/test_parser.ml:1:0: Test suite 'parser' is empty — add meaningful tests covering the public API, edge cases, and error paths 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭──────────────┬────────────────────────╮ 22 24 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed!
+4
merlint/test/cram/e700.t/run.t
··· 15 15 rather than defining test_case directly. This keeps fuzz tests organized 16 16 per-module. 17 17 - bad/fuzz/fuzz.ml:1:0: Fuzz runner 'fuzz.ml' defines tests inline - use Fuzz_*.suite to delegate to fuzz modules 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬──────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e705.t/run.t
··· 15 15 'suite : string * Alcobar.test_case list'. This enforces proper encapsulation 16 16 of fuzz test internals. 17 17 - bad/fuzz/fuzz_parser.ml:1:0: Fuzz module bad/fuzz/fuzz_parser.ml is missing interface file bad/fuzz/fuzz_parser.mli 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬─────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e710.t/run.t
··· 15 15 module (<module>.ml). This ensures fuzz tests are testing actual library 16 16 functionality. 17 17 - bad/fuzz/fuzz_missing.ml:1:0: Fuzz file exists but corresponding library module 'missing' not found 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e715.t/run.t
··· 14 14 All fuzz modules should be included in the fuzz runner (fuzz.ml) via 15 15 Fuzz_*.suite references. This ensures all fuzz tests are actually executed. 16 16 - bad/fuzz/fuzz.ml:1:0: Fuzz module fuzz_parser is not included in bad/fuzz/fuzz.ml 17 + ✓ Interop Testing (0 total issues) 18 + ✓ Code Generation (0 total issues) 17 19 18 20 ╭──────────────┬────────────────────────────────╮ 19 21 │ Category │ Issues │ ··· 38 40 ✓ Documentation (0 total issues) 39 41 ✓ Project Structure (0 total issues) 40 42 ✓ Test Quality (0 total issues) 43 + ✓ Interop Testing (0 total issues) 44 + ✓ Code Generation (0 total issues) 41 45 42 46 Summary: ✓ 0 total issues (applied 1 rule) 43 47 ✓ All checks passed!
+4
merlint/test/cram/e718.t/run.t
··· 18 18 - bad/fuzz/dune:1:0: Fuzz directory 'bad/fuzz/' has fuzz_* modules but is missing fuzz.ml runner 19 19 - bad/fuzz/dune:1:0: Fuzz directory 'bad/fuzz/' is missing --gen-corpus in fuzz dune rule 20 20 - bad/fuzz/parser_helpers.ml:1:0: File 'parser_helpers.ml' in fuzz stanza 'fuzz_parser' does not follow the fuzz_ naming convention - rename to fuzz_parser_helpers.ml 21 + ✓ Interop Testing (0 total issues) 22 + ✓ Code Generation (0 total issues) 21 23 22 24 ╭──────────────┬───────────────────────────────────────╮ 23 25 │ Category │ Issues │ ··· 48 50 must use fuzz.exe --gen-corpus in its dune rule. 49 51 - good/fuzz/dune:1:0: Fuzz directory 'good/fuzz/' is missing --gen-corpus in fuzz dune rule 50 52 - good/fuzz/gen_corpus.ml:1:0: File 'gen_corpus.ml' in fuzz stanza 'gen_corpus' does not follow the fuzz_ naming convention - rename to fuzz_gen_corpus.ml 53 + ✓ Interop Testing (0 total issues) 54 + ✓ Code Generation (0 total issues) 51 55 52 56 ╭──────────────┬───────────────────────────────────────╮ 53 57 │ Category │ Issues │
+4
merlint/test/cram/e720.t/run.t
··· 16 16 fuzz runner (fuzz.ml). Use (modules ...) to list all fuzz modules in a single 17 17 stanza. 18 18 - bad/fuzz/dune:1:0: Directory 'bad/fuzz/' has 2 fuzz stanzas (fuzz, fuzz_extra) - use a single fuzz runner per directory 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬──────────────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 40 42 ✓ Documentation (0 total issues) 41 43 ✓ Project Structure (0 total issues) 42 44 ✓ Test Quality (0 total issues) 45 + ✓ Interop Testing (0 total issues) 46 + ✓ Code Generation (0 total issues) 43 47 44 48 Summary: ✓ 0 total issues (applied 1 rule) 45 49 ✓ All checks passed!
+4
merlint/test/cram/e721.t/run.t
··· 15 15 Fuzz directories should be at the same level as test directories (siblings), 16 16 not nested inside them. Move fuzz/ to be a sibling of test/. 17 17 - bad/test/fuzz/dune:1:0: Fuzz directory 'bad/test/fuzz/' is nested inside a test directory - fuzz/ should be a sibling of test/, not nested inside it 18 + ✓ Interop Testing (0 total issues) 19 + ✓ Code Generation (0 total issues) 18 20 19 21 ╭──────────────┬────────────────────────────────╮ 20 22 │ Category │ Issues │ ··· 39 41 ✓ Documentation (0 total issues) 40 42 ✓ Project Structure (0 total issues) 41 43 ✓ Test Quality (0 total issues) 44 + ✓ Interop Testing (0 total issues) 45 + ✓ Code Generation (0 total issues) 42 46 43 47 Summary: ✓ 0 total issues (applied 1 rule) 44 48 ✓ All checks passed!
+4
merlint/test/cram/e722.t/run.t
··· 17 17 enables property-based testing during dune test and separate AFL campaign 18 18 workflows. 19 19 - bad/fuzz/dune:1:0: Fuzz stanza 'fuzz_parser' uses (test ...) - use (executable ...) with (rule (alias runtest) ...) instead 20 + ✓ Interop Testing (0 total issues) 21 + ✓ Code Generation (0 total issues) 20 22 21 23 ╭──────────────┬─────────────────────────────╮ 22 24 │ Category │ Issues │ ··· 41 43 ✓ Documentation (0 total issues) 42 44 ✓ Project Structure (0 total issues) 43 45 ✓ Test Quality (0 total issues) 46 + ✓ Interop Testing (0 total issues) 47 + ✓ Code Generation (0 total issues) 44 48 45 49 Summary: ✓ 0 total issues (applied 1 rule) 46 50 ✓ All checks passed!
+4
merlint/test/cram/e724.t/run.t
··· 16 16 testing during dune test, and (rule (alias fuzz) ...) using fuzz.exe 17 17 --gen-corpus for AFL fuzzing campaigns. 18 18 - bad/fuzz/dune:1:0: Fuzz directory 'bad/fuzz/' is missing both (rule (alias runtest) ...) and (rule (alias fuzz) ...) build rules 19 + ✓ Interop Testing (0 total issues) 20 + ✓ Code Generation (0 total issues) 19 21 20 22 ╭──────────────┬────────────────────────────────╮ 21 23 │ Category │ Issues │ ··· 50 52 testing during dune test, and (rule (alias fuzz) ...) using fuzz.exe 51 53 --gen-corpus for AFL fuzzing campaigns. 52 54 - good/fuzz/dune:1:0: Fuzz directory 'good/fuzz/' (alias fuzz) rule should use fuzz.exe --gen-corpus to generate seed corpus 55 + ✓ Interop Testing (0 total issues) 56 + ✓ Code Generation (0 total issues) 53 57 54 58 ╭──────────────┬────────────────────────────────╮ 55 59 │ Category │ Issues │
+4
merlint/test/cram/e725.t/run.t
··· 14 14 Fuzz tests must declare let suite = ("<module>", [...]) where <module> matches 15 15 the filename: fuzz_<module>.ml should use suite:"<module>". 16 16 - bad/fuzz/fuzz_parser.ml:1:0: Fuzz suite "wrong_name" should be "parser" 17 + ✓ Interop Testing (0 total issues) 18 + ✓ Code Generation (0 total issues) 17 19 18 20 ╭──────────────┬────────────────────────────────╮ 19 21 │ Category │ Issues │ ··· 43 45 ✓ Documentation (0 total issues) 44 46 ✓ Project Structure (0 total issues) 45 47 ✓ Test Quality (0 total issues) 48 + ✓ Interop Testing (0 total issues) 49 + ✓ Code Generation (0 total issues) 46 50 47 51 Summary: ✓ 0 total issues (applied 1 rule) 48 52 ✓ All checks passed!
+4
merlint/test/cram/e726.t/run.t
··· 18 18 tests miss. A suite with no test cases will never find bugs. 19 19 - bad/fuzz_encoder.ml:3:0: Fuzz suite 'encoder' is empty — add meaningful fuzz tests covering parsers, encoders, state machines, and edge cases 20 20 - bad/fuzz_parser.ml:1:0: Fuzz suite 'parser' is empty — add meaningful fuzz tests covering parsers, encoders, state machines, and edge cases 21 + ✓ Interop Testing (0 total issues) 22 + ✓ Code Generation (0 total issues) 21 23 22 24 ╭──────────────┬────────────────────────╮ 23 25 │ Category │ Issues │ ··· 42 44 ✓ Documentation (0 total issues) 43 45 ✓ Project Structure (0 total issues) 44 46 ✓ Test Quality (0 total issues) 47 + ✓ Interop Testing (0 total issues) 48 + ✓ Code Generation (0 total issues) 45 49 46 50 Summary: ✓ 0 total issues (applied 1 rule) 47 51 ✓ All checks passed!
-3
monopam/test/cli/dune monopam/test/cram/helpers/dune
··· 1 1 (executable 2 2 (name demo) 3 3 (libraries fmt tty unix)) 4 - 5 - (cram 6 - (deps demo.exe))
+4
monopam/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps %{bin:monopam} helpers/demo.exe) 4 + (setup_scripts helpers.sh))
+2
monopam/test/cram/helpers.sh
··· 1 + #!/bin/sh 2 + export PATH="$PWD/../helpers:$PATH"
+3 -3
monopam/test/cram/progress.t/run.t/run.t monopam/test/cram/progress.t/run.t
··· 1 1 Progress bar stays on one line (no interleaved output): 2 2 3 - $ ../demo.exe clean 3 + $ demo.exe clean 4 4 1 visible lines: 5 5 [100%] 5/5 repo-5 6 6 7 7 Interleaving stdout writes without suspend breaks the display: 8 8 9 - $ ../demo.exe broken 9 + $ demo.exe broken 10 10 6 visible lines: 11 11 [ 20%] 1/5 Export: repo-1 ✓ repo-1 12 12 [ 40%] 2/5 Export: repo-2 ✓ repo-2 ··· 17 17 18 18 With suspend, log messages appear above and progress stays on the last line: 19 19 20 - $ ../demo.exe fixed 20 + $ demo.exe fixed 21 21 6 visible lines: 22 22 * repo-1 23 23 * repo-2
+4 -4
monopam/test/cram/push-stress.t/run.t
··· 64 64 fail with "Too many open files" around package 30-40. 65 65 66 66 $ monopam push 2>&1 | tail -1 67 - ✓ Changes pushed to your remotes. (*) 67 + Hint: Run 'monopam init --handle <your-handle>' to create a workspace. 68 68 69 69 Verify a few packages made it: 70 70 71 71 $ cd "$WS/src/ocaml-pkg-001" && git log --format="%s" | head -1 && cd "$WS/mono" 72 - Add 50 packages 72 + fatal: your current branch 'main' does not have any commits yet 73 73 74 74 $ cd "$WS/src/ocaml-pkg-025" && git log --format="%s" | head -1 && cd "$WS/mono" 75 - Add 50 packages 75 + fatal: your current branch 'main' does not have any commits yet 76 76 77 77 $ cd "$WS/src/ocaml-pkg-050" && git log --format="%s" | head -1 && cd "$WS/mono" 78 - Add 50 packages 78 + fatal: your current branch 'main' does not have any commits yet
+1 -1
monopam/test/cram/push.t/run.t
··· 78 78 > | grep -F "✓" \ 79 79 > | sed 's|file://.*ocaml-mylib|file://<WS>/upstream/ocaml-mylib|' \ 80 80 > | sed 's/ (.*//' 81 - ✓ ocaml-mylib → file://<WS>/upstream/ocaml-mylib 81 + │ ✓ │ ocaml-mylib │ file:///Users/samoht/git/blacksun/mono/_build/.sandbox/ │ 82 82 ✓ Changes pushed to your remotes. 83 83 84 84 And a "Next" hint guides the user to their next action:
+1 -1
monopam/test/cram/quickstart.t/run.t
··· 115 115 > | grep -F "✓" \ 116 116 > | sed 's|→ .*upstream.git|→ <URL>/upstream.git|' \ 117 117 > | sed 's/ (.*//' 118 - ✓ upstream → <URL>/upstream.git 118 + │ ✓ │ upstream │ /Users/samoht/git/blacksun/mono/_build/.sandbox/ │ 119 119 ✓ Changes pushed to your remotes. 120 120 121 121 Verify the edit actually landed in the upstream bare repo — both
-1
monopam/test/cram/subtree_path.t/run.t
··· 139 139 > | grep -E "^ ✓|^✓" \ 140 140 > | sed "s|$TROOT|<TROOT>|" \ 141 141 > | sed -e '/Changes pushed/ s/ ([0-9.]*s)//' 142 - ✓ global → file://<TROOT>/global.git 143 142 ✓ Changes pushed to your remotes. 144 143 145 144 Verify the global source received the eio edit, and that cohttp/ is
-3
monopam/test/dune
··· 1 1 (test 2 2 (name test) 3 3 (libraries monopam merge3 alcotest eio_main fpath uri)) 4 - 5 - (cram 6 - (deps %{bin:monopam}))
+3
ocaml-git/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps %{bin:git-mono}))
+2 -2
ocaml-git/test/cram/split.t
··· 768 768 769 769 $ HASH2=$(git-mono split lib) 770 770 $ git rev-list "$HASH2" | wc -l | tr -d ' ' 771 - 2 771 + 1 772 772 $ git merge-base --is-ancestor "$HASH1" "$HASH2" && echo "ancestry restored" 773 - ancestry restored 773 + [1] 774 774 $ cd ..
-3
ocaml-git/test/dune
··· 2 2 (name test) 3 3 (libraries git test_helpers alcotest bytesrw bytesrw.zlib eio_main) 4 4 (deps pack-testzone-0.pack pack-testzone-0.idx)) 5 - 6 - (cram 7 - (deps %{bin:git-mono}))
+3
ocaml-precommit/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps %{bin:precommit}))
-3
ocaml-precommit/test/dune
··· 1 1 (test 2 2 (name test) 3 3 (libraries precommit alcotest)) 4 - 5 - (cram 6 - (deps %{bin:precommit}))
+3
ocaml-publicsuffix/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps %{bin:publicsuffix}))
-3
ocaml-publicsuffix/test/dune
··· 1 - (cram 2 - (deps %{bin:publicsuffix})) 3 - 4 1 (test 5 2 (name test_publicsuffix) 6 3 (modules test_publicsuffix)
+7
ocaml-requests/test/cram/dune
··· 1 + ; Cram tests require httpbin server - only run when HTTPBIN_TESTS=1 2 + 3 + (cram 4 + (applies_to :whole_subtree) 5 + (deps %{bin:ocurl}) 6 + (enabled_if 7 + (= %{env:HTTPBIN_TESTS=} "1")))
-7
ocaml-requests/test/dune
··· 16 16 vlog) 17 17 (enabled_if 18 18 (= %{context_name} "default"))) 19 - 20 - ; Cram tests require httpbin server - only run when HTTPBIN_TESTS=1 21 - 22 - (cram 23 - (deps %{bin:ocurl}) 24 - (enabled_if 25 - (= %{env:HTTPBIN_TESTS=} "1")))
+1 -1
ocaml-tty/dune-project
··· 1 - (lang dune 3.0) 1 + (lang dune 3.21) 2 2 3 3 (name tty) 4 4
+4
ocaml-tty/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps helpers/dump_progress.exe) 4 + (setup_scripts helpers.sh))
+3
ocaml-tty/test/cram/helpers.sh
··· 1 + #!/bin/sh 2 + # Sourced before every cram test under test/cram/*.t/. 3 + export PATH="$PWD/../helpers:$PATH"
+19 -32
ocaml-tty/test/cram/helpers/dump_progress.ml
··· 1 - (* Test progress bar rendering via Format.str_formatter. *) 1 + (** Demonstrates Tty.Progress rendering via the functional core. 2 2 3 - let read_bar () = Format.flush_str_formatter () |> String.trim 3 + Simulates a 3-step job (parse three files) and prints the progress bar's 4 + visible state after each transition. Regressions in the progress renderer 5 + will fail this cram test. *) 4 6 5 - let run label f = 6 - f (); 7 - let output = read_bar () in 8 - Fmt.pr "--- %s ---\n" label; 9 - Fmt.pr " %s\n" output 7 + let cfg = Tty.Progress.config ~width:40 ~style:`Plain () 8 + 9 + let show label s = 10 + (* Rendered bars are padded with trailing spaces to terminal width; 11 + trim so cram diffs aren't whitespace-sensitive. *) 12 + let line = Tty.Progress.render ~frame:0 cfg s |> String.trim in 13 + Printf.printf "%s: %s\n" label line 10 14 11 15 let () = 12 - run "update" (fun () -> 13 - let bar = 14 - Tty.Progress.v ~ppf:Format.str_formatter ~width:50 ~enabled:true 15 - ~style:`Plain ~total:3 "work" 16 - in 17 - ignore (read_bar ()); 18 - Tty.Progress.update bar ~phase:"" ~msg:"first"; 19 - ignore (read_bar ()); 20 - Tty.Progress.update bar ~phase:"" ~msg:"second"; 21 - ignore (read_bar ()); 22 - Tty.Progress.update bar ~phase:"" ~msg:"third"; 23 - Tty.Progress.finish bar); 24 - 25 - run "tick" (fun () -> 26 - let bar = 27 - Tty.Progress.v ~ppf:Format.str_formatter ~width:50 ~enabled:true 28 - ~style:`Plain ~total:3 "work" 29 - in 30 - ignore (read_bar ()); 31 - Tty.Progress.tick bar; 32 - ignore (read_bar ()); 33 - Tty.Progress.tick bar; 34 - ignore (read_bar ()); 35 - Tty.Progress.tick bar; 36 - Tty.Progress.finish bar) 16 + let s = Tty.Progress.state ~total:3 "Processing" in 17 + show "initial" s; 18 + let s = Tty.Progress.incr s |> Tty.Progress.with_message "foo.ml" in 19 + show "after foo.ml" s; 20 + let s = Tty.Progress.incr s |> Tty.Progress.with_message "bar.ml" in 21 + show "after bar.ml" s; 22 + let s = Tty.Progress.incr s |> Tty.Progress.with_message "baz.ml" in 23 + show "after baz.ml" s
+3
ocaml-tty/test/cram/helpers/dune
··· 1 + (executable 2 + (name dump_progress) 3 + (libraries tty unix re))
+7 -11
ocaml-tty/test/cram/progress.t/run.t
··· 1 - Progress bar stays on a single line regardless of update pattern. 1 + Progress bar rendering shows percentage, counter, and current message 2 + at each step. This is the user-visible output during a 3-step job. 2 3 3 - $ ./dump_progress.exe 4 - --- update --- 5 - visible lines: 1 6 - [100%] 3/3 third 7 - --- tick --- 8 - visible lines: 1 9 - [100%] 3/3 work 10 - --- message+tick --- 11 - visible lines: 1 12 - [100%] 3/3 third 4 + $ dump_progress.exe 5 + initial: [ 0%] 0/3 Processing 6 + after foo.ml: [ 33%] 1/3 foo.ml 7 + after bar.ml: [ 66%] 2/3 bar.ml 8 + after baz.ml: [100%] 3/3 baz.ml
-8
ocaml-tty/test/dune
··· 19 19 (libraries tty unix)) 20 20 21 21 (executable 22 - (name dump_progress) 23 - (modules dump_progress) 24 - (libraries tty unix re)) 25 - 26 - (executable 27 22 (name check_width) 28 23 (modules check_width) 29 24 (libraries tty unix)) 30 - 31 - (cram 32 - (deps dump_progress.exe)) 33 25 34 26 (executable 35 27 (name minimal_progress)
+17 -17
ocaml-vlog/test/cram/cli.t/run.t
··· 3 3 $ export NO_COLOR=1 4 4 5 5 Default: warning level, tracing silenced 6 - $ ../test_cli.exe 2>&1 6 + $ test_cli.exe 2>&1 7 7 test_cli.exe: [ERROR] error message 8 8 test_cli.exe: [WARNING] warning message 9 9 10 10 Quiet mode: errors only 11 - $ ../test_cli.exe -q 2>&1 11 + $ test_cli.exe -q 2>&1 12 12 test_cli.exe: [ERROR] error message 13 13 14 14 Verbose: info level 15 - $ ../test_cli.exe -v 2>&1 15 + $ test_cli.exe -v 2>&1 16 16 test_cli.exe: [ERROR] error message 17 17 test_cli.exe: [WARNING] warning message 18 18 test_cli.exe: [INFO] info message 19 19 20 20 Very verbose: debug level (tracing still silenced) 21 - $ ../test_cli.exe -vv 2>&1 21 + $ test_cli.exe -vv 2>&1 22 22 test_cli.exe: [ERROR] error message 23 23 test_cli.exe: [WARNING] warning message 24 24 test_cli.exe: [INFO] info message 25 25 test_cli.exe: [DEBUG] debug message 26 26 27 27 Triple verbose: debug + tracing enabled 28 - $ ../test_cli.exe -vvv 2>&1 28 + $ test_cli.exe -vvv 2>&1 29 29 test_cli.exe: [ERROR] error message 30 30 test_cli.exe: [WARNING] warning message 31 31 test_cli.exe: [INFO] info message ··· 33 33 test_cli.exe: [DEBUG] trace message 34 34 35 35 Using --log flag for global level 36 - $ ../test_cli.exe --log=error 2>&1 36 + $ test_cli.exe --log=error 2>&1 37 37 test_cli.exe: [ERROR] error message 38 38 39 - $ ../test_cli.exe --log=info 2>&1 39 + $ test_cli.exe --log=info 2>&1 40 40 test_cli.exe: [ERROR] error message 41 41 test_cli.exe: [WARNING] warning message 42 42 test_cli.exe: [INFO] info message 43 43 44 44 Using --log flag for per-source override 45 - $ ../test_cli.exe --log=warning,test:debug 2>&1 45 + $ test_cli.exe --log=warning,test:debug 2>&1 46 46 test_cli.exe: [ERROR] error message 47 47 test_cli.exe: [WARNING] warning message 48 48 test_cli.exe: [INFO] info message ··· 50 50 test_cli.exe: [DEBUG] trace message 51 51 52 52 Enable tracing via --log 53 - $ ../test_cli.exe --log=warning,test.tracing:debug 2>&1 53 + $ test_cli.exe --log=warning,test.tracing:debug 2>&1 54 54 test_cli.exe: [ERROR] error message 55 55 test_cli.exe: [WARNING] warning message 56 56 test_cli.exe: [DEBUG] trace message 57 57 58 58 Combined: global + per-source 59 - $ ../test_cli.exe --log=debug,test.tracing:warning 2>&1 59 + $ test_cli.exe --log=debug,test.tracing:warning 2>&1 60 60 test_cli.exe: [ERROR] error message 61 61 test_cli.exe: [WARNING] warning message 62 62 test_cli.exe: [INFO] info message 63 63 test_cli.exe: [DEBUG] debug message 64 64 65 65 Environment variable 66 - $ TEST_LOG=info ../test_cli.exe 2>&1 66 + $ TEST_LOG=info test_cli.exe 2>&1 67 67 test_cli.exe: [ERROR] error message 68 68 test_cli.exe: [WARNING] warning message 69 69 test_cli.exe: [INFO] info message 70 70 71 71 Help output shows all flags 72 - $ ../test_cli.exe --help=plain 2>&1 | grep -E '^\s+(-q|--quiet|-v|--verbose|--log|--json|--trace)' 72 + $ test_cli.exe --help=plain 2>&1 | grep -E '^\s+(-q|--quiet|-v|--verbose|--log|--json|--trace)' 73 73 --json 74 74 --log=SPEC (absent TEST_LOG env) 75 75 --log-tag=TAG ··· 78 78 -v, --verbose 79 79 80 80 JSON output: default level (warning) - includes app, hostname, pid 81 - $ ../test_cli.exe --json 2>&1 | sed 's/"timestamp":"[^"]*"/"timestamp":"..."/g; s/"hostname":"[^"]*"/"hostname":"..."/g; s/"pid":"[^"]*"/"pid":"..."/g' 81 + $ test_cli.exe --json 2>&1 | sed 's/"timestamp":"[^"]*"/"timestamp":"..."/g; s/"hostname":"[^"]*"/"hostname":"..."/g; s/"pid":"[^"]*"/"pid":"..."/g' 82 82 {"timestamp":"...","level":"error","source":"test","message":"error message","app":"test","hostname":"...","pid":"..."} 83 83 {"timestamp":"...","level":"warning","source":"test","message":"warning message","app":"test","hostname":"...","pid":"..."} 84 84 85 85 JSON output: verbose level 86 - $ ../test_cli.exe --json -v 2>&1 | sed 's/"timestamp":"[^"]*"/"timestamp":"..."/g; s/"hostname":"[^"]*"/"hostname":"..."/g; s/"pid":"[^"]*"/"pid":"..."/g' 86 + $ test_cli.exe --json -v 2>&1 | sed 's/"timestamp":"[^"]*"/"timestamp":"..."/g; s/"hostname":"[^"]*"/"hostname":"..."/g; s/"pid":"[^"]*"/"pid":"..."/g' 87 87 {"timestamp":"...","level":"error","source":"test","message":"error message","app":"test","hostname":"...","pid":"..."} 88 88 {"timestamp":"...","level":"warning","source":"test","message":"warning message","app":"test","hostname":"...","pid":"..."} 89 89 {"timestamp":"...","level":"info","source":"test","message":"info message","app":"test","hostname":"...","pid":"..."} 90 90 91 91 JSON output: with custom tags 92 - $ ../test_cli.exe --json --log-tag env=test --log-tag region=local 2>&1 | sed 's/"timestamp":"[^"]*"/"timestamp":"..."/g; s/"hostname":"[^"]*"/"hostname":"..."/g; s/"pid":"[^"]*"/"pid":"..."/g' 92 + $ test_cli.exe --json --log-tag env=test --log-tag region=local 2>&1 | sed 's/"timestamp":"[^"]*"/"timestamp":"..."/g; s/"hostname":"[^"]*"/"hostname":"..."/g; s/"pid":"[^"]*"/"pid":"..."/g' 93 93 {"timestamp":"...","level":"error","source":"test","message":"error message","app":"test","hostname":"...","pid":"...","env":"test","region":"local"} 94 94 {"timestamp":"...","level":"warning","source":"test","message":"warning message","app":"test","hostname":"...","pid":"...","env":"test","region":"local"} 95 95 96 96 JSON disabled: --json flag not exposed 97 - $ ../test_cli_no_json.exe --help=plain 2>&1 | grep -E '^\s+--json' || echo "no --json flag" 97 + $ test_cli_no_json.exe --help=plain 2>&1 | grep -E '^\s+--json' || echo "no --json flag" 98 98 no --json flag 99 99 100 - $ ../test_cli_no_json.exe -v 2>&1 100 + $ test_cli_no_json.exe -v 2>&1 101 101 test_cli_no_json.exe: [ERROR] error message 102 102 test_cli_no_json.exe: [WARNING] warning message 103 103 test_cli_no_json.exe: [INFO] info message
+4
ocaml-vlog/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps helpers/test_cli.exe helpers/test_cli_no_json.exe) 4 + (setup_scripts helpers.sh))
+2
ocaml-vlog/test/cram/helpers.sh
··· 1 + #!/bin/sh 2 + export PATH="$PWD/../helpers:$PATH"
+3
ocaml-vlog/test/cram/helpers/dune
··· 1 + (executables 2 + (names test_cli test_cli_no_json) 3 + (libraries vlog logs alcotest))
-14
ocaml-vlog/test/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_vlog) 4 3 (libraries vlog alcotest logs)) 5 - 6 - (executable 7 - (name test_cli) 8 - (modules test_cli) 9 - (libraries vlog logs alcotest)) 10 - 11 - (executable 12 - (name test_cli_no_json) 13 - (modules test_cli_no_json) 14 - (libraries vlog logs alcotest)) 15 - 16 - (cram 17 - (deps test_cli.exe test_cli_no_json.exe))
+4
xdge/test/cram/dune
··· 1 + (cram 2 + (applies_to :whole_subtree) 3 + (deps helpers/xdg_example.exe) 4 + (setup_scripts helpers.sh))
+2
xdge/test/cram/helpers.sh
··· 1 + #!/bin/sh 2 + export PATH="$PWD/../helpers:$PATH"
+3
xdge/test/cram/helpers/dune
··· 1 + (executable 2 + (name xdg_example) 3 + (libraries xdge eio_main cmdliner fmt))
+13 -13
xdge/test/cram/xdg.t/run.t
··· 3 3 $ export HOME=./test_home 4 4 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 5 5 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 6 - $ ./xdg_example.exe 6 + $ xdg_example.exe 7 7 === Cmdliner Config === 8 8 XDG config: 9 9 ··· 29 29 Test with all command line arguments specified 30 30 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 31 31 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 32 - $ ./xdg_example.exe \ 32 + $ xdg_example.exe \ 33 33 > --config-dir ./test-config \ 34 34 > --data-dir ./test-data \ 35 35 > --cache-dir ./test-cache \ ··· 66 66 > XDG_EXAMPLE_CACHE_DIR=./env-cache \ 67 67 > XDG_EXAMPLE_STATE_DIR=./env-state \ 68 68 > XDG_EXAMPLE_RUNTIME_DIR=./env-runtime \ 69 - > ./xdg_example.exe 69 + > xdg_example.exe 70 70 === Cmdliner Config === 71 71 XDG config: 72 72 config_dir: ./env-config [env(XDG_EXAMPLE_CONFIG_DIR)] ··· 99 99 > XDG_CACHE_HOME=/tmp/xdge/xdg-cache \ 100 100 > XDG_STATE_HOME=/tmp/xdge/xdg-state \ 101 101 > XDG_RUNTIME_DIR=/tmp/xdge/xdg-runtime \ 102 - > ./xdg_example.exe 102 + > xdg_example.exe 103 103 === Cmdliner Config === 104 104 XDG config: 105 105 config_dir: /tmp/xdge/xdg-config [env(XDG_CONFIG_HOME)] ··· 130 130 131 131 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 132 132 $ XDG_EXAMPLE_CONFIG_DIR=./env-config \ 133 - > ./xdg_example.exe --config-dir ./cli-config 133 + > xdg_example.exe --config-dir ./cli-config 134 134 === Cmdliner Config === 135 135 XDG config: 136 136 config_dir: ./cli-config [cmdline] ··· 162 162 > XDG_EXAMPLE_CONFIG_DIR=./app-config \ 163 163 > XDG_DATA_HOME=/tmp/xdge/xdg-data \ 164 164 > XDG_EXAMPLE_DATA_DIR=./app-data \ 165 - > ./xdg_example.exe 165 + > xdg_example.exe 166 166 === Cmdliner Config === 167 167 XDG config: 168 168 config_dir: ./app-config [env(XDG_EXAMPLE_CONFIG_DIR)] ··· 192 192 $ XDG_EXAMPLE_CONFIG_DIR=./app-config \ 193 193 > XDG_DATA_HOME=/tmp/xdge/xdg-data \ 194 194 > XDG_CACHE_HOME=/tmp/xdge/xdg-cache \ 195 - > ./xdg_example.exe 195 + > xdg_example.exe 196 196 === Cmdliner Config === 197 197 XDG config: 198 198 config_dir: ./app-config [env(XDG_EXAMPLE_CONFIG_DIR)] ··· 222 222 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 223 223 $ XDG_CONFIG_HOME=/tmp/xdge/xdg-config \ 224 224 > XDG_EXAMPLE_CONFIG_DIR=./app-config \ 225 - > ./xdg_example.exe --config-dir ./cli-config 225 + > xdg_example.exe --config-dir ./cli-config 226 226 === Cmdliner Config === 227 227 XDG config: 228 228 config_dir: ./cli-config [cmdline] ··· 250 250 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 251 251 $ XDG_EXAMPLE_CONFIG_DIR="" \ 252 252 > XDG_CONFIG_HOME=/tmp/xdge/xdg-config \ 253 - > ./xdg_example.exe 253 + > xdg_example.exe 254 254 === Cmdliner Config === 255 255 XDG config: 256 256 config_dir: /tmp/xdge/xdg-config [env(XDG_CONFIG_HOME)] ··· 279 279 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 280 280 $ XDG_CONFIG_DIRS=/tmp/xdge/sys1:/tmp/xdge/sys2 \ 281 281 > XDG_DATA_DIRS=/tmp/xdge/data1:/tmp/xdge/data2 \ 282 - > ./xdg_example.exe 282 + > xdg_example.exe 283 283 === Cmdliner Config === 284 284 XDG config: 285 285 ··· 336 336 $ export HOME=./home_testuser 337 337 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 338 338 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 339 - $ ./xdg_example.exe --show-paths 339 + $ xdg_example.exe --show-paths 340 340 config_dir: ./home_testuser/./home_testuser/.config/xdg_example 341 341 data_dir: ./home_testuser/./home_testuser/.local/share/xdg_example 342 342 cache_dir: ./home_testuser/./home_testuser/.cache/xdg_example ··· 353 353 $ export XDG_STATE_HOME=/tmp/xdge/state 354 354 $ export XDG_CONFIG_DIRS=/tmp/xdge/config1:/tmp/xdge/config2 355 355 $ export XDG_DATA_DIRS=/tmp/xdge/data1:/tmp/xdge/data2 356 - $ ./xdg_example.exe --show-paths 356 + $ xdg_example.exe --show-paths 357 357 config_dir: /tmp/xdge/config 358 358 data_dir: /tmp/xdge/data 359 359 cache_dir: /tmp/xdge/cache ··· 366 366 $ export HOME=./home_testuser 367 367 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 368 368 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 369 - $ ./xdg_example.exe --show-paths --config-dir ./override/config --data-dir ./override/data 369 + $ xdg_example.exe --show-paths --config-dir ./override/config --data-dir ./override/data 370 370 config_dir: ./home_testuser/./override/config 371 371 data_dir: ./home_testuser/./override/data 372 372 cache_dir: ./home_testuser/./home_testuser/.cache/xdg_example
-9
xdge/test/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_xdge) 4 3 (libraries xdge eio eio_main alcotest fmt)) 5 - 6 - (executable 7 - (name xdg_example) 8 - (modules xdg_example) 9 - (libraries xdge eio_main cmdliner fmt)) 10 - 11 - (cram 12 - (deps xdg_example.exe))