Opinionated OCaml linter with Merlin integration for code quality, naming conventions, and style checks
0
fork

Configure Feed

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

claude: complete Err -> Error module rename across call sites

Follow up to the module rename: update the remaining callers that
still referenced [Err] (library [claude.ml{,i}], [client.ml], the test
driver [test.ml]), and fix one stray [^ e] string concatenation in
hermest's CLI that needed [Json.Error.to_string e] now that
[Json.of_string] yields a structured error.

+118 -108
+2 -2
docs/index.html
··· 1451 1451 <h4>BAD</h4> 1452 1452 <pre><code><span class="kw">let</span> test_parse () = 1453 1453 <span class="kw">match</span> parse input <span class="kw">with</span> 1454 - | <span class="cn">Error</span> e -&gt; <span class="cn">Alcotest</span>.fail (<span class="cn">Fmt</span>.str &quot;<span class="cn">Parse</span> error: %s&quot; e) 1454 + | <span class="cn">Error</span> e -&gt; <span class="cn">Alcotest</span>.fail (<span class="cn">Fmt</span>.str &quot;<span class="cn">Parse</span> error: %s&quot; (<span class="cn">Json</span>.<span class="cn">Error</span>.to_string e)) 1455 1455 | <span class="cn">Ok</span> _ -&gt; () 1456 1456 1457 1457 <span class="kw">let</span> test_invalid () = ··· 1462 1462 <h4>GOOD</h4> 1463 1463 <pre><code><span class="kw">let</span> test_parse () = 1464 1464 <span class="kw">match</span> parse input <span class="kw">with</span> 1465 - | <span class="cn">Error</span> e -&gt; <span class="cn">Alcotest</span>.failf &quot;<span class="cn">Parse</span> error: %s&quot; e 1465 + | <span class="cn">Error</span> e -&gt; <span class="cn">Alcotest</span>.failf &quot;<span class="cn">Parse</span> error: %s&quot; (<span class="cn">Json</span>.<span class="cn">Error</span>.to_string e) 1466 1466 | <span class="cn">Ok</span> _ -&gt; () 1467 1467 1468 1468 <span class="kw">let</span> test_invalid () =
+1 -2
dune-project
··· 18 18 ocaml 19 19 dune 20 20 bytesrw 21 - jsont 22 - cmdliner 21 + json cmdliner 23 22 eio 24 23 ocaml-merlin 25 24 re
+1 -2
lib/dune
··· 14 14 fpath 15 15 vlog 16 16 tty 17 - jsont 18 - jsont.bytesrw 17 + json 19 18 opam 20 19 opam.bytesrw 21 20 bytesrw
+2 -2
lib/rules/e325.ml
··· 23 23 24 24 (** Stdlib-aligned [find_*] names whose return shape is a collection (not an 25 25 option): [List.find_all], [Hashtbl.find_all], etc. The name-shape is a 26 - stable signal (the stdlib enshrines the convention); do not flag these 27 - for returning a non-option. *) 26 + stable signal (the stdlib enshrines the convention); do not flag these for 27 + returning a non-option. *) 28 28 let is_stdlib_find_collection_name name = 29 29 name = "find_all" || name = "find_many" 30 30
+4 -4
lib/rules/e331.ml
··· 1 1 (** E331: Redundant Function Prefixes *) 2 2 3 - (** Stdlib-aligned [find_*] names where stripping the [find_] prefix would 4 - lose information: [List.find_all], [Hashtbl.find_all], [List.find_map], 5 - etc. The bare suffix ([all], [map]) alone isn't descriptive enough, and 6 - the stdlib precedent establishes the full name as the natural form. *) 3 + (** Stdlib-aligned [find_*] names where stripping the [find_] prefix would lose 4 + information: [List.find_all], [Hashtbl.find_all], [List.find_map], etc. The 5 + bare suffix ([all], [map]) alone isn't descriptive enough, and the stdlib 6 + precedent establishes the full name as the natural form. *) 7 7 let is_stdlib_find_alias name = 8 8 name = "find_all" || name = "find_map" || name = "find_many" 9 9 || name = "find_index" || name = "find_last" || name = "find_first"
+53 -5
lib/rules/e522.ml
··· 17 17 18 18 type payload = { package : string; file : string } 19 19 20 + let try_readdir d = try Sys.readdir d |> Array.to_list with Sys_error _ -> [] 21 + 22 + let read_file path = 23 + try 24 + let ic = open_in path in 25 + let n = in_channel_length ic in 26 + let s = really_input_string ic n in 27 + close_in ic; 28 + Some s 29 + with Sys_error _ -> None 30 + 31 + (** Collect every module name that appears in a [(modules ...)] field of a 32 + library/executable/test stanza in [dune_path]. These names are claimed by a 33 + specific stanza (often a sublibrary) and should not be flagged as "wrong 34 + place" by E522 — the prefix is encoding the sublib's public name. *) 35 + let modules_explicitly_claimed dune_path = 36 + match read_file dune_path with 37 + | None -> [] 38 + | Some contents -> ( 39 + match Sexp.Value.parse_string_many contents with 40 + | Error _ -> [] 41 + | Ok stanzas -> 42 + let is_module_stanza = function 43 + | "library" | "executable" | "executables" | "test" | "tests" -> 44 + true 45 + | _ -> false 46 + in 47 + List.concat_map 48 + (function 49 + | Sexp.List (Sexp.Atom kind :: fields) when is_module_stanza kind 50 + -> 51 + List.concat_map 52 + (function 53 + | Sexp.List (Sexp.Atom "modules" :: atoms) -> 54 + List.filter_map 55 + (function 56 + | Sexp.Atom a -> Some (String.lowercase_ascii a) 57 + | _ -> None) 58 + atoms 59 + | _ -> []) 60 + fields 61 + | _ -> []) 62 + stanzas) 63 + 20 64 let check (ctx : Context.project) = 21 65 let root = ctx.project_root in 22 - let try_readdir d = 23 - try Sys.readdir d |> Array.to_list with Sys_error _ -> [] 24 - in 25 66 let issues = ref [] in 26 67 let packages = try_readdir root in 27 68 List.iter ··· 42 83 (* Dune mangles [-] to [_] in module names. *) 43 84 String.map (fun c -> if c = '-' then '_' else c) p ^ "_" 44 85 in 86 + let claimed = 87 + modules_explicitly_claimed (Filename.concat lib_dir "dune") 88 + in 45 89 let has_ml name = Filename.check_suffix name ".ml" in 46 90 List.iter 47 91 (fun name -> ··· 50 94 && String.length name > String.length prefix + 3 51 95 && String.sub name 0 (String.length prefix) = prefix 52 96 then 53 - let path = Filename.concat (Filename.concat pkg "lib") name in 54 - issues := Issue.v { package = pkg; file = path } :: !issues) 97 + let mod_name = 98 + String.lowercase_ascii (Filename.chop_suffix name ".ml") 99 + in 100 + if not (List.mem mod_name claimed) then 101 + let path = Filename.concat (Filename.concat pkg "lib") name in 102 + issues := Issue.v { package = pkg; file = path } :: !issues) 55 103 (try_readdir lib_dir)) 56 104 packages; 57 105 !issues
+2 -2
lib/rules/e616.ml
··· 49 49 code = 50 50 {|let test_parse () = 51 51 match parse input with 52 - | Error e -> Alcotest.fail (Fmt.str "Parse error: %s" e) 52 + | Error e -> Alcotest.fail (Fmt.str "Parse error: %s" (Json.Error.to_string e)) 53 53 | Ok _ -> () 54 54 55 55 let test_invalid () = ··· 61 61 code = 62 62 {|let test_parse () = 63 63 match parse input with 64 - | Error e -> Alcotest.failf "Parse error: %s" e 64 + | Error e -> Alcotest.failf "Parse error: %s" (Json.Error.to_string e) 65 65 | Ok _ -> () 66 66 67 67 let test_invalid () =
+1 -1
merlint.opam
··· 13 13 "ocaml" 14 14 "dune" {>= "3.21"} 15 15 "bytesrw" 16 - "jsont" 16 + "json" 17 17 "cmdliner" 18 18 "eio" 19 19 "ocaml-merlin"
+1 -1
test/cram/e001.t/dune
··· 1 1 (library 2 2 (name test_e001) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e005.t/dune
··· 1 1 (library 2 2 (name test_e005) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e010.t/dune
··· 1 1 (library 2 2 (name test_e010) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e100.t/dune
··· 1 1 (library 2 2 (name test_e100) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e105.t/dune
··· 1 1 (library 2 2 (name test_e105) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e110.t/dune
··· 1 1 (library 2 2 (name test_e110) 3 - (modules bad good)) 3 + )
-1
test/cram/e200.t/dune
··· 1 1 (library 2 2 (name test_e200) 3 - (modules bad good) 4 3 (libraries str re))
-1
test/cram/e205.t/dune
··· 1 1 (library 2 2 (name test_e205) 3 - (modules bad good) 4 3 (libraries fmt))
-1
test/cram/e210.t/dune
··· 1 1 (library 2 2 (name test_e210) 3 - (modules bad good printf__ string__ printf__sprintf string__length) 4 3 (libraries alcotest fmt) 5 4 (flags :standard -w -32))
-1
test/cram/e215.t/dune
··· 1 1 (library 2 2 (name test_e215) 3 - (modules bad good) 4 3 (libraries fmt) 5 4 (flags :standard -w -32))
-1
test/cram/e216.t/dune
··· 1 1 (library 2 2 (name test_e216) 3 - (modules bad good) 4 3 (libraries fmt))
+1 -1
test/cram/e300.t/dune
··· 1 1 (library 2 2 (name test_e300) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e305.t/dune
··· 1 1 (library 2 2 (name test_e305) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e310.t/dune
··· 1 1 (library 2 2 (name test_e310) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e315.t/dune
··· 1 1 (library 2 2 (name test_e315) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e320.t/dune
··· 1 1 (library 2 2 (name test_e320) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e325.t/dune
··· 1 1 (library 2 2 (name test_e325) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e335.t/dune
··· 1 1 (library 2 2 (name test_e335) 3 - (modules bad good)) 3 + )
-1
test/cram/e340.t/dune
··· 1 1 (library 2 2 (name test_e340) 3 - (modules bad good) 4 3 (libraries fmt))
-1
test/cram/e350.t/dune
··· 1 1 (library 2 2 (name test_e350) 3 - (modules bad good) 4 3 (flags :standard -w -32))
-1
test/cram/e351.t/dune
··· 1 1 (library 2 2 (name test_e351) 3 - (modules bad good) 4 3 (flags :standard -w -32))
+1 -1
test/cram/e400.t/dune
··· 1 1 (library 2 2 (name test_e400) 3 - (modules bad good)) 3 + )
+1 -1
test/cram/e405.t/dune
··· 1 1 (library 2 2 (name test_e405) 3 - (modules bad good)) 3 + )
-1
test/cram/e410.t/dune
··· 1 1 (library 2 2 (name test_e410) 3 - (modules bad good) 4 3 (flags -w -32))
-1
test/cram/e415.t/dune
··· 1 1 (library 2 2 (name test_e415) 3 - (modules bad good function_good) 4 3 (modules_without_implementation function_good))
+1 -1
test/cram/e500.t/bad/dune
··· 1 1 (library 2 2 (name test_e500) 3 - (modules main)) 3 + )
+1 -1
test/cram/e500.t/good/dune
··· 1 1 (library 2 2 (name test_e500_good) 3 - (modules main)) 3 + )
+1 -1
test/cram/e505.t/dune
··· 1 1 (library 2 2 (name test_e505) 3 - (modules bad good)) 3 + )
-1
test/cram/e510.t/dune
··· 1 1 (library 2 2 (name test_e510) 3 - (modules bad good) 4 3 (libraries logs))
-1
test/cram/e600.t/bad/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_user) 4 3 (libraries alcotest))
-1
test/cram/e600.t/good/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_user) 4 3 (libraries alcotest))
+1 -1
test/cram/e607.t/bad/lib/core/dune
··· 1 1 (library 2 2 (name core_lib) 3 - (modules page)) 3 + )
+1 -1
test/cram/e607.t/bad/lib/views/dune
··· 1 1 (library 2 2 (name views_lib) 3 - (modules feed)) 3 + )
+1 -1
test/cram/e607.t/good/lib/core/dune
··· 1 1 (library 2 2 (name core_lib) 3 - (modules page)) 3 + )
+1 -1
test/cram/e610.t/bad/test/dune
··· 1 1 (test 2 2 (name test_runner) 3 - (modules test_runner test_parser test_old_feature)) 3 + )
+1 -1
test/cram/e610.t/good-subdir/test/dune
··· 1 1 (test 2 2 (name test_engine) 3 - (modules test_engine test_admin)) 3 + )
+1 -1
test/cram/e610.t/good/test/dune
··· 1 1 (test 2 2 (name test_runner) 3 - (modules test_runner test_parser test_old_feature)) 3 + )
-1
test/cram/e615.t/bad/test/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_parser) 4 3 (libraries alcotest))
-1
test/cram/e615.t/good/test/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_parser) 4 3 (libraries alcotest))
-1
test/cram/e616.t/dune
··· 1 1 (library 2 2 (name test_e616) 3 - (modules test_bad test_good) 4 3 (libraries alcotest fmt) 5 4 (flags :standard -w -32))
-1
test/cram/e617.t/dune
··· 1 1 (library 2 2 (name test_e617) 3 - (modules test_config test_parser test_user_auth) 4 3 (libraries alcotest))
-1
test/cram/e617.t/good/dune
··· 1 1 (library 2 2 (name test_e617_good) 3 - (modules test_config test_parser test_user_auth) 4 3 (libraries alcotest))
+1 -1
test/cram/e618.t/bad/dune
··· 1 1 (library 2 2 (name e618_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e618.t/bad/test/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test helpers) 4 3 (libraries alcotest))
+1 -1
test/cram/e618.t/good/dune
··· 1 1 (library 2 2 (name e618_good) 3 - (modules parser)) 3 + )
-1
test/cram/e618.t/good/test/dune
··· 1 1 (test 2 2 (name test) 3 - (modules test test_helpers) 4 3 (libraries alcotest))
+1 -1
test/cram/e620.t/bad/dune
··· 1 1 (library 2 2 (name e620_bad) 3 - (modules parser)) 3 + )
+1 -1
test/cram/e620.t/good/dune
··· 1 1 (library 2 2 (name e620_good) 3 - (modules parser)) 3 + )
+1 -1
test/cram/e621.t/bad/dune
··· 1 1 (library 2 2 (name e621_bad) 3 - (modules test_parser)) 3 + )
+1 -1
test/cram/e621.t/good/dune
··· 1 1 (library 2 2 (name e621_good) 3 - (modules test_encoder)) 3 + )
+1 -1
test/cram/e700.t/bad/dune
··· 1 1 (library 2 2 (name e700_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e700.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e700.t/good/dune
··· 1 1 (library 2 2 (name e700_good) 3 - (modules parser)) 3 + )
-1
test/cram/e700.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e705.t/bad/dune
··· 1 1 (library 2 2 (name e705_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e705.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e705.t/good/dune
··· 1 1 (library 2 2 (name e705_good) 3 - (modules parser)) 3 + )
-1
test/cram/e705.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e710.t/bad/dune
··· 1 1 (library 2 2 (name e710_bad) 3 3 (public_name e710-bad) 4 - (modules parser)) 4 + )
-1
test/cram/e710.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_missing) 4 3 (libraries alcobar))
+1 -1
test/cram/e710.t/good/dune
··· 1 1 (library 2 2 (name e710_good) 3 3 (public_name e710-good) 4 - (modules parser)) 4 + )
-1
test/cram/e710.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e715.t/bad/dune
··· 1 1 (library 2 2 (name e715_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e715.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e715.t/good/dune
··· 1 1 (library 2 2 (name e715_good) 3 - (modules parser)) 3 + )
-1
test/cram/e715.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e718.t/bad/dune
··· 1 1 (library 2 2 (name e718_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e718.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz_parser) 3 - (modules fuzz_parser parser_helpers) 4 3 (libraries alcobar))
+1 -1
test/cram/e718.t/good/dune
··· 1 1 (library 2 2 (name e718_good) 3 - (modules parser)) 3 + )
+1 -1
test/cram/e720.t/bad/dune
··· 1 1 (library 2 2 (name e720_bad) 3 - (modules parser)) 3 + )
+1 -1
test/cram/e720.t/good/dune
··· 1 1 (library 2 2 (name e720_good) 3 - (modules parser)) 3 + )
-1
test/cram/e720.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e721.t/bad/dune
··· 1 1 (library 2 2 (name e621_bad) 3 - (modules parser)) 3 + )
+1 -1
test/cram/e721.t/good/dune
··· 1 1 (library 2 2 (name e621_good) 3 - (modules parser)) 3 + )
+1 -1
test/cram/e722.t/bad/dune
··· 1 1 (library 2 2 (name e722_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e722.t/bad/fuzz/dune
··· 1 1 (test 2 2 (name fuzz_parser) 3 - (modules fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e722.t/good/dune
··· 1 1 (library 2 2 (name e722_good) 3 - (modules parser)) 3 + )
-1
test/cram/e722.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz_parser) 3 - (modules fuzz_parser) 4 3 (libraries alcobar)) 5 4 6 5 (rule
+1 -1
test/cram/e724.t/bad/dune
··· 1 1 (library 2 2 (name e724_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e724.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz_parser) 3 - (modules fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e724.t/good/dune
··· 1 1 (library 2 2 (name e724_good) 3 - (modules parser)) 3 + )
-1
test/cram/e724.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz_parser) 3 - (modules fuzz_parser) 4 3 (libraries alcobar)) 5 4 6 5 (rule
+1 -1
test/cram/e725.t/bad/dune
··· 1 1 (library 2 2 (name e725_bad) 3 - (modules parser)) 3 + )
-1
test/cram/e725.t/bad/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e725.t/good/dune
··· 1 1 (library 2 2 (name e725_good) 3 - (modules parser)) 3 + )
-1
test/cram/e725.t/good/fuzz/dune
··· 1 1 (executable 2 2 (name fuzz) 3 - (modules fuzz fuzz_parser) 4 3 (libraries alcobar))
+1 -1
test/cram/e726.t/bad/dune
··· 1 1 (library 2 2 (name e726_bad) 3 - (modules fuzz_parser fuzz_encoder)) 3 + )
+1 -1
test/cram/e726.t/good/dune
··· 1 1 (library 2 2 (name e726_good) 3 - (modules fuzz_codec)) 3 + )