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.

Update merlint E718/E724 to require --gen-corpus pattern (no standalone gen_corpus.ml)

Per alcobar's README, corpus generation uses fuzz.exe --gen-corpus,
not a separate gen_corpus.ml. Updated E718 and E724 rules to check
for --gen-corpus in the dune fuzz rule instead of gen_corpus.ml/.exe.
Removed gen_corpus from the valid fuzz filename list.

Also: add .merlint to ocaml-sqlite excluding E331 for create_table,
and doc comments on test suite mli files (E405).

+26 -19
+2 -2
docs/index.html
··· 1528 1528 <span class="error-code">E718</span> 1529 1529 <span class="error-title">Non-Fuzz File in Fuzz Directory</span> 1530 1530 </div> 1531 - <div class="error-hint"><p>All .ml files in a fuzz/ directory should follow the fuzz_ naming convention (e.g., fuzz_parser.ml), be the fuzz runner (fuzz.ml), or the corpus generator (gen_corpus.ml). Each fuzz directory must have a gen_corpus.ml.</p></div> 1531 + <div class="error-hint"><p>All .ml files in a fuzz/ directory should follow the fuzz_ naming convention (e.g., fuzz_parser.ml) or be the fuzz runner (fuzz.ml). Each fuzz directory must use fuzz.exe --gen-corpus in its dune rule.</p></div> 1532 1532 </div> 1533 1533 <div class="error-card" id="E720"> 1534 1534 <div> ··· 1556 1556 <span class="error-code">E724</span> 1557 1557 <span class="error-title">Missing Fuzz Build Rules</span> 1558 1558 </div> 1559 - <div class="error-hint"><p>Each fuzz directory should have (rule (alias runtest) ...) for property-based testing during dune test, and (rule (alias fuzz) (deps (source_tree corpus) fuzz.exe gen_corpus.exe) ...) for AFL fuzzing campaigns with corpus generation.</p></div> 1559 + <div class="error-hint"><p>Each fuzz directory should have (rule (alias runtest) ...) for property-based testing during dune test, and (rule (alias fuzz) ...) using fuzz.exe --gen-corpus for AFL fuzzing campaigns.</p></div> 1560 1560 </div> 1561 1561 <div class="error-card" id="E725"> 1562 1562 <div>
+18 -11
lib/rules/e718.ml
··· 9 9 let is_fuzz_dir = File.is_in_fuzz_dir 10 10 11 11 let is_valid basename = 12 - String.starts_with ~prefix:"fuzz_" basename 13 - || String.equal basename "fuzz" 14 - || String.equal basename "gen_corpus" 12 + String.starts_with ~prefix:"fuzz_" basename || String.equal basename "fuzz" 15 13 16 14 (** Collect all stanzas with files in fuzz/ directories from both test and 17 15 executable stanzas. *) ··· 88 86 dir_files 89 87 in 90 88 let issues = ref [] in 91 - if not (has "gen_corpus") then 89 + (* Corpus generation should use fuzz.exe --gen-corpus (alcobar). *) 90 + let dune_file = Filename.concat dir "dune" in 91 + let has_gen_corpus = 92 + try 93 + let content = 94 + In_channel.with_open_text dune_file In_channel.input_all 95 + in 96 + Re.execp (Re.compile (Re.str "--gen-corpus")) content 97 + with _ -> false 98 + in 99 + if not has_gen_corpus then 92 100 issues := 93 101 Issue.v 94 102 ~loc: 95 - (Location.v 96 - ~file:(Filename.concat dir "dune") 97 - ~start_line:1 ~start_col:0 ~end_line:1 ~end_col:0) 103 + (Location.v ~file:dune_file ~start_line:1 ~start_col:0 104 + ~end_line:1 ~end_col:0) 98 105 { directory = dir; kind = `missing_gen_corpus } 99 106 :: !issues; 100 107 if has_fuzz_modules && not (has "fuzz") then ··· 121 128 convention - rename to fuzz_%s.ml" 122 129 basename stanza_name modname 123 130 | `missing_gen_corpus -> 124 - Fmt.pf ppf "Fuzz directory '%s' is missing gen_corpus.ml" directory 131 + Fmt.pf ppf "Fuzz directory '%s' is missing --gen-corpus in fuzz dune rule" 132 + directory 125 133 | `missing_fuzz_runner -> 126 134 Fmt.pf ppf 127 135 "Fuzz directory '%s' has fuzz_* modules but is missing fuzz.ml runner" ··· 131 139 Rule.v ~code:"E718" ~title:"Non-Fuzz File in Fuzz Directory" ~category:Testing 132 140 ~hint: 133 141 "All .ml files in a fuzz/ directory should follow the fuzz_ naming \ 134 - convention (e.g., fuzz_parser.ml), be the fuzz runner (fuzz.ml), or the \ 135 - corpus generator (gen_corpus.ml). Each fuzz directory must have a \ 136 - gen_corpus.ml." 142 + convention (e.g., fuzz_parser.ml) or be the fuzz runner (fuzz.ml). Each \ 143 + fuzz directory must use fuzz.exe --gen-corpus in its dune rule." 137 144 ~examples:[] ~pp (Project check)
+6 -6
lib/rules/e724.ml
··· 67 67 let has_corpus = 68 68 Re.execp (Re.compile (Re.str "source_tree corpus")) content 69 69 || Re.execp (Re.compile (Re.str "source_tree input")) content 70 + || Re.execp (Re.compile (Re.str "--gen-corpus corpus")) content 70 71 in 71 72 let has_gen_corpus = 72 - Re.execp (Re.compile (Re.str "gen_corpus")) content 73 + Re.execp (Re.compile (Re.str "--gen-corpus")) content 73 74 in 74 75 let has_afl_profile = 75 76 Re.execp (Re.compile (Re.str "profile")) content ··· 121 122 directory 122 123 | `fuzz_missing_gen_corpus -> 123 124 Fmt.pf ppf 124 - "Fuzz directory '%s' (alias fuzz) rule should depend on gen_corpus.exe \ 125 - to generate seed corpus" 125 + "Fuzz directory '%s' (alias fuzz) rule should use fuzz.exe \ 126 + --gen-corpus to generate seed corpus" 126 127 directory 127 128 | `fuzz_missing_afl_profile -> 128 129 Fmt.pf ppf ··· 134 135 Rule.v ~code:"E724" ~title:"Missing Fuzz Build Rules" ~category:Testing 135 136 ~hint: 136 137 "Each fuzz directory should have (rule (alias runtest) ...) for \ 137 - property-based testing during dune test, and (rule (alias fuzz) (deps \ 138 - (source_tree corpus) fuzz.exe gen_corpus.exe) ...) for AFL fuzzing \ 139 - campaigns with corpus generation." 138 + property-based testing during dune test, and (rule (alias fuzz) ...) \ 139 + using fuzz.exe --gen-corpus for AFL fuzzing campaigns." 140 140 ~examples:[] ~pp (Project check)