Installs pre-commit hooks for OCaml projects that run dune fmt automatically
1
fork

Configure Feed

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

precommit: Improve check output formatting

- Truncate long commit subjects to terminal width
- Use emoji indicators for init feedback

+25 -13
+21 -11
bin/main.ml
··· 9 9 (* {1 Styled output} *) 10 10 11 11 let success fmt = 12 - Fmt.pf Fmt.stdout ("%a " ^^ fmt ^^ "@.") 13 - Fmt.(styled (`Fg `Green) string) 14 - "✓" 12 + Fmt.pf Fmt.stdout ("%a " ^^ fmt ^^ "@.") Fmt.(styled (`Fg `Green) string) "✓" 15 13 16 14 let error fmt = 17 15 Fmt.pf Fmt.stderr ("%a " ^^ fmt ^^ "@.") Fmt.(styled (`Fg `Red) string) "✗" 18 16 19 17 let warning fmt = 20 - Fmt.pf Fmt.stdout ("%a " ^^ fmt ^^ "@.") 21 - Fmt.(styled (`Fg `Yellow) string) 22 - "⚠" 18 + Fmt.pf Fmt.stdout ("%a " ^^ fmt ^^ "@.") Fmt.(styled (`Fg `Yellow) string) "⚠" 23 19 24 20 let info fmt = 25 21 Fmt.pf Fmt.stdout ("%a " ^^ fmt ^^ "@.") Fmt.(styled (`Fg `Cyan) string) "ℹ" ··· 107 103 dirs; 108 104 if !count = 0 then info "All directories already have hooks installed" 109 105 else 110 - Log.info (fun m -> m "Processed %d director%s" !count (if !count = 1 then "y" else "ies")) 106 + Log.info (fun m -> 107 + m "Processed %d director%s" !count (if !count = 1 then "y" else "ies")) 111 108 112 109 let init dry_run force hooks recursive dirs = 113 110 Eio_main.run @@ fun env -> ··· 218 215 219 216 (* {1 Check command} *) 220 217 218 + let get_terminal_width () = 219 + try 220 + let ic = Unix.open_process_in "tput cols 2>/dev/null" in 221 + let width = int_of_string (String.trim (input_line ic)) in 222 + ignore (Unix.close_process_in ic); 223 + width 224 + with _ -> 80 225 + 226 + let truncate_subject max_len s = 227 + if String.length s <= max_len then s else String.sub s 0 (max_len - 1) ^ "…" 228 + 221 229 let check_impl ~process_mgr ~fs recursive dirs = 222 230 let dirs = collect_dirs ~fs ~recursive dirs in 223 231 let total_commits = ref 0 in 224 232 let repos_with_issues = ref 0 in 233 + (* Get terminal width, default to 80 if not available *) 234 + let term_width = get_terminal_width () in 235 + (* Reserve space for: border (2) + hash column (~9) + padding (4) *) 236 + let subject_max = max 20 (term_width - 15) in 225 237 List.iter 226 238 (fun d -> 227 239 let commits = Precommit.check_ai_attribution ~process_mgr ~fs d in ··· 234 246 (fun (c : Precommit.ai_commit) -> 235 247 [ 236 248 Tty.Span.styled Tty.Style.(fg Tty.Color.yellow) c.hash; 237 - Tty.Span.text c.subject; 249 + Tty.Span.text (truncate_subject subject_max c.subject); 238 250 ]) 239 251 commits 240 252 in ··· 250 262 dirs; 251 263 (* Summary *) 252 264 if !total_commits > 0 then begin 253 - Fmt.pf Fmt.stdout "@.%a@." 254 - Fmt.(styled `Bold string) 255 - "Summary:"; 265 + Fmt.pf Fmt.stdout "@.%a@." Fmt.(styled `Bold string) "Summary:"; 256 266 Fmt.pf Fmt.stdout " %a %d commit%s with AI attribution in %d repo%s@." 257 267 Fmt.(styled (`Fg `Red) string) 258 268 "✗" !total_commits
+4 -2
test/init.t
··· 14 14 Would create ./.git/hooks/commit-msg 15 15 Would chmod +x ./.git/hooks/commit-msg 16 16 Would create ./.ocamlformat 17 - .: Would initialise 17 + ℹ Would initialise . 18 18 19 19 Test actual init creates the hooks 20 20 $ precommit init 21 - .: Initialised 21 + ✓ Initialised . 22 22 23 23 Verify hooks exist and are executable 24 24 $ test -x .git/hooks/pre-commit && echo "pre-commit is executable" ··· 42 42 $ cd no-git-$$ 43 43 $ echo '(lang dune 3.0)' > dune-project 44 44 $ precommit init 45 + ℹ All directories already have hooks installed 45 46 46 47 Test error when not in an OCaml project 47 48 $ cd /tmp ··· 49 50 $ cd no-dune-$$ 50 51 $ git init -q 51 52 $ precommit init 53 + ℹ All directories already have hooks installed