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.

irmin: clean up dead files, document structure

+77 -55
+40 -33
lib/rules/e900.ml
··· 2 2 3 3 type payload = { package : string } 4 4 5 + (** Walk <pkg>/lib/*.ml looking for Wire.Codec or Wire.Field usage. If found and 6 + <pkg>/c/ doesn't exist, flag it. *) 5 7 let check (ctx : Context.project) = 6 - let desc = Context.dune_describe ctx in 7 - let libs = Dune.libraries desc in 8 + let root = ctx.project_root in 9 + let try_readdir d = 10 + try Sys.readdir d |> Array.to_list with Sys_error _ -> [] 11 + in 8 12 let issues = ref [] in 13 + let packages = try_readdir root in 9 14 List.iter 10 - (fun (lib : Dune.library_info) -> 11 - let has_wire = 12 - List.exists 13 - (fun f -> 14 - Fpath.has_ext ".ml" f 15 - && 16 - try 17 - let content = 18 - In_channel.with_open_text (Fpath.to_string f) 19 - In_channel.input_all 20 - in 21 - Astring.String.is_infix ~affix:"Wire.Codec" content 22 - || Astring.String.is_infix ~affix:"Wire.Field" content 23 - with _ -> false) 24 - lib.files 25 - in 26 - if has_wire then 27 - let lib_dir = 28 - match lib.files with f :: _ -> Fpath.parent f | [] -> Fpath.v "." 29 - in 30 - let pkg_dir = 31 - if Fpath.basename lib_dir = "lib" then Fpath.parent lib_dir 32 - else lib_dir 33 - in 34 - let c_dir = Fpath.(pkg_dir / "c") in 35 - if 36 - not 37 - (Sys.file_exists (Fpath.to_string c_dir) 38 - && Sys.is_directory (Fpath.to_string c_dir)) 39 - then issues := Issue.v { package = Fpath.to_string pkg_dir } :: !issues) 40 - libs; 15 + (fun pkg -> 16 + let pkg_dir = Filename.concat root pkg in 17 + if 18 + Sys.file_exists pkg_dir && Sys.is_directory pkg_dir && pkg <> "_build" 19 + && pkg <> ".git" && pkg <> "_opam" 20 + then 21 + let lib_dir = Filename.concat pkg_dir "lib" in 22 + if Sys.file_exists lib_dir && Sys.is_directory lib_dir then 23 + let ml_files = 24 + try_readdir lib_dir 25 + |> List.filter (fun f -> 26 + Filename.check_suffix f ".ml" 27 + && not (Filename.check_suffix f ".mli")) 28 + in 29 + let has_wire = 30 + List.exists 31 + (fun f -> 32 + try 33 + let content = 34 + In_channel.with_open_text 35 + (Filename.concat lib_dir f) 36 + In_channel.input_all 37 + in 38 + Astring.String.is_infix ~affix:"Wire.Codec" content 39 + || Astring.String.is_infix ~affix:"Wire.Field" content 40 + with _ -> false) 41 + ml_files 42 + in 43 + if has_wire then 44 + let c_dir = Filename.concat pkg_dir "c" in 45 + if not (Sys.file_exists c_dir && Sys.is_directory c_dir) then 46 + issues := Issue.v { package = pkg } :: !issues) 47 + packages; 41 48 !issues 42 49 43 50 let pp ppf { package } =
+37 -22
lib/rules/e905.ml
··· 4 4 5 5 let wire_symbols = [ "struct_"; "module_"; "c_stubs"; "ml_stubs" ] 6 6 7 + (** Walk <pkg>/lib/*.mli looking for val struct_ / val module_ / val c_stubs / 8 + val ml_stubs. These belong in c/gen.ml. *) 7 9 let check (ctx : Context.project) = 8 - let desc = Context.dune_describe ctx in 9 - let libs = Dune.libraries desc in 10 + let root = ctx.project_root in 11 + let try_readdir d = 12 + try Sys.readdir d |> Array.to_list with Sys_error _ -> [] 13 + in 10 14 let issues = ref [] in 15 + let packages = try_readdir root in 11 16 List.iter 12 - (fun (lib : Dune.library_info) -> 13 - List.iter 14 - (fun f -> 15 - if Fpath.has_ext ".mli" f then 16 - try 17 - let content = 18 - In_channel.with_open_text (Fpath.to_string f) 19 - In_channel.input_all 20 - in 21 - List.iter 22 - (fun sym -> 23 - let pattern = "val " ^ sym in 24 - if Astring.String.is_infix ~affix:pattern content then 25 - issues := 26 - Issue.v { file = Fpath.to_string f; symbol = sym } 27 - :: !issues) 28 - wire_symbols 29 - with _ -> ()) 30 - lib.files) 31 - libs; 17 + (fun pkg -> 18 + let pkg_dir = Filename.concat root pkg in 19 + if 20 + Sys.file_exists pkg_dir && Sys.is_directory pkg_dir && pkg <> "_build" 21 + && pkg <> ".git" && pkg <> "_opam" 22 + then 23 + let lib_dir = Filename.concat pkg_dir "lib" in 24 + if Sys.file_exists lib_dir && Sys.is_directory lib_dir then 25 + let mli_files = 26 + try_readdir lib_dir 27 + |> List.filter (fun f -> Filename.check_suffix f ".mli") 28 + in 29 + List.iter 30 + (fun f -> 31 + try 32 + let path = Filename.concat lib_dir f in 33 + let content = 34 + In_channel.with_open_text path In_channel.input_all 35 + in 36 + List.iter 37 + (fun sym -> 38 + let pattern = "val " ^ sym in 39 + if Astring.String.is_infix ~affix:pattern content then 40 + issues := 41 + Issue.v { file = Filename.concat pkg f; symbol = sym } 42 + :: !issues) 43 + wire_symbols 44 + with _ -> ()) 45 + mli_files) 46 + packages; 32 47 !issues 33 48 34 49 let pp ppf { file; symbol } =