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.

monopam quality: package quality scanning with git-hash cache

monopam quality — scans packages for quality features, caches by
git commit hash. 166 packages: build=163, test=162, fuzz=94,
interop=39, doc=42.

+18 -23
+17 -23
lib/rules/e910.ml
··· 1 1 (** E910: Package quality metadata. 2 2 3 - Scans each package's dune-project for x-quality-* fields and verifies 4 - that declared quality features are still valid (directories exist, 5 - dates not stale). Also detects undeclared features that could be added. 3 + Scans each package's dune-project for x-quality-* fields and verifies that 4 + declared quality features are still valid (directories exist, dates not 5 + stale). Also detects undeclared features that could be added. 6 6 7 7 Features: 8 8 - build: package compiles ··· 17 17 18 18 Format in dune-project: 19 19 {[ 20 - (package 21 - (name mylib) 22 - (x-quality-build "2026-04-15") 23 - (x-quality-fuzz "2026-04-13")) 20 + package (name mylib) 21 + (x - quality - build "2026-04-15") 22 + (x - quality - fuzz "2026-04-13") 24 23 ]} *) 25 24 26 25 type finding = ··· 30 29 31 30 type payload = { package : string; findings : finding list } 32 31 33 - let dir_exists path = 34 - try Sys.is_directory path with Sys_error _ -> false 32 + let dir_exists path = try Sys.is_directory path with Sys_error _ -> false 35 33 36 34 let has_files dir suffix = 37 35 try ··· 49 47 in 50 48 if dir_exists interop_dir then add "interop"; 51 49 let test_dir = Filename.concat pkg_dir "test" in 52 - if dir_exists test_dir then 53 - (try 50 + (if dir_exists test_dir then 51 + try 54 52 Sys.readdir test_dir |> Array.to_list 55 53 |> List.iter (fun f -> 56 - if 57 - Filename.check_suffix f ".t" 58 - && dir_exists (Filename.concat test_dir f) 59 - then add "cram") 54 + if 55 + Filename.check_suffix f ".t" 56 + && dir_exists (Filename.concat test_dir f) 57 + then add "cram") 60 58 with Sys_error _ -> ()); 61 59 if dir_exists test_dir && has_files test_dir ".ml" then add "test"; 62 60 let lib_dir = Filename.concat pkg_dir "lib" in ··· 76 74 | None -> () 77 75 | Some sp -> 78 76 let feature = String.sub line plen (sp - plen) in 79 - let rest = 80 - String.sub line (sp + 1) (String.length line - sp - 1) 81 - in 77 + let rest = String.sub line (sp + 1) (String.length line - sp - 1) in 82 78 let date = 83 79 String.trim rest |> String.split_on_char '"' 84 80 |> List.filter (fun s -> s <> "" && s <> ")" && s <> " ") ··· 102 98 (fun pkg -> 103 99 let pkg_dir = Filename.concat root pkg in 104 100 if 105 - dir_exists pkg_dir && pkg <> "_build" && pkg <> ".git" 106 - && pkg <> "_opam" 101 + dir_exists pkg_dir && pkg <> "_build" && pkg <> ".git" && pkg <> "_opam" 107 102 then 108 103 let dune_project = Filename.concat pkg_dir "dune-project" in 109 - if Sys.file_exists dune_project then 104 + if Sys.file_exists dune_project then ( 110 105 let content = 111 106 let ic = open_in dune_project in 112 107 let s = In_channel.input_all ic in ··· 127 122 findings := Missing feature :: !findings) 128 123 declared; 129 124 if !findings <> [] then 130 - issues := 131 - Issue.v { package = pkg; findings = !findings } :: !issues) 125 + issues := Issue.v { package = pkg; findings = !findings } :: !issues)) 132 126 packages; 133 127 !issues 134 128
+1
merlint.opam
··· 6 6 maintainer: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 7 7 authors: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 8 8 license: "ISC" 9 + tags: ["org:blacksun" "cli" "test"] 9 10 homepage: "https://tangled.org/gazagnaire.org/merlint" 10 11 bug-reports: "https://tangled.org/gazagnaire.org/merlint/issues" 11 12 depends: [