From 0f569b07038e00af8a5aca813601eecb2a53c7df Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 27 Oct 2022 16:18:30 +0200 Subject: [PATCH] [lint/headers] new commit hook --- dev/git-hooks/pre-commit.sh | 41 ++++++++++++++++++++++------------- share/Makefile.headers | 2 +- share/Makefile.linting | 2 +- tools/hdrck/hdrck.ml | 43 +++++++++++++++++++++++++------------ 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/dev/git-hooks/pre-commit.sh b/dev/git-hooks/pre-commit.sh index 3f376ce71e3..5d59f0b0f99 100755 --- a/dev/git-hooks/pre-commit.sh +++ b/dev/git-hooks/pre-commit.sh @@ -25,22 +25,33 @@ # - cp ./dev/git-hooks/pre-commit.sh .git/hooks/pre-commit # - (cd .git/hooks/ && ln -s ../../dev/git-hooks/pre-commit.sh pre-commit) -# Note: -# - that checks the unstaged version of the files and these files are -# only commited with a `git commit -a` command. -# - so, a `git commit` command may checks the wrong version of a file. - echo "Pre-commit Hook..." -# Extract the files that have both an unstaged version and a staged one. -UNSTAGED="git diff --name-status" -STAGED="git diff --name-status --cached" -(($UNSTAGED ; $STAGED) | sed "s:^.::" | sort -u) | diff - <(($UNSTAGED ; $STAGED) | sed "s:^.::" | sort) -if [ "$?" != "0" ]; then - echo "WARNING: These previous files are both unstaged and in the index." - echo " They will be verified only for a 'git commit -a' command." +STAGED=$(git diff --diff-filter ACMR --name-only --cached | sort) +UNSTAGED=$(git diff --diff-filter DMR --name-only | sort) + +INTER=$(comm -12 <(ls $STAGED) <(ls $UNSTAGED)) + +if [ "$INTER" != "" ]; +then + echo "Cannot validate commit." + echo "The following staged files have been modified, renamed or deleted." + for file in $INTER ; do + echo "- $file" + done + exit 1 fi -# Verifies the current version of the files -make lint.before-commit-a || exit 1 -make check-headers.before-commit-a || exit 1 +STAGED=$(echo $STAGED | tr '\n' ' ') + +TMP=$(mktemp) + +cleanup () { + rm "$TMP" +} +trap cleanup exit + +git check-attr -za $STAGED > "$TMP" +make lint LINTCK_FILES_INPUT="$TMP" || exit 1 +git check-attr -z header_spec $STAGED > "$TMP" +make check-headers HDRCK_FILES_INPUT="$TMP" HDRCK_EXTRA="-quiet" || exit 1 diff --git a/share/Makefile.headers b/share/Makefile.headers index 47d53f56919..ea3826c56bf 100644 --- a/share/Makefile.headers +++ b/share/Makefile.headers @@ -74,7 +74,7 @@ DUNE ?= dune ifneq ($(IN_FRAMAC),yes) HDRCK.CMD:= $(HDRCK) else -HDRCK.CMD:= $(DUNE) exec --root $(FRAMAC_HDRCK_SRC) -- $(HDRCK) +HDRCK.CMD:= $(DUNE) exec --no-print-directory --root $(FRAMAC_HDRCK_SRC) -- $(HDRCK) endif HDRCK.OPTS:= --stdin -z -spec-format 3-zeros diff --git a/share/Makefile.linting b/share/Makefile.linting index 4edf434164e..7b9ea957390 100644 --- a/share/Makefile.linting +++ b/share/Makefile.linting @@ -49,7 +49,7 @@ DUNE ?= dune ifneq ($(IN_FRAMAC),yes) LINTCK.CMD:= $(LINTCK) else -LINTCK.CMD:= $(DUNE) exec --root $(FRAMAC_LINTCK_SRC) -- $(LINTCK) +LINTCK.CMD:= $(DUNE) exec --no-print-directory --root $(FRAMAC_LINTCK_SRC) -- $(LINTCK) endif ########################################################################## diff --git a/tools/hdrck/hdrck.ml b/tools/hdrck/hdrck.ml index e8fd61024ec..c65802c97ed 100644 --- a/tools/hdrck/hdrck.ml +++ b/tools/hdrck/hdrck.ml @@ -60,7 +60,7 @@ and headache_config_file = ref [] (* empty -> headache_config_file_default *) and headache_config_file_default = "headers/headache_config.txt" and exit_on_warning = ref false and exit_on_error = ref true (* only settable to false for debugging purposes *) - +and quiet = ref false type mode = | Check @@ -84,7 +84,8 @@ let job_head fmt = Format.printf fmt let job_done () = - Format.printf "done@." + if not !quiet then + Format.printf "done@." let pp_job_first_line () = if !is_first_job_line then @@ -258,7 +259,8 @@ let add_spec_entry (ignored_files: StringSet.t ref) (spec_tab: (string, string) let read_specs spec_format (ignored_files: StringSet.t ref) (spec_tab: (string, string) Hashtbl.t) (spec_file : string option) = let spec_fname = match spec_file with None -> "--stdin" | Some filename -> filename in debug "Specification file: %s@." spec_fname ; - job_head "Checking format of specification file %s... @?" spec_fname; + if not !quiet then + job_head "Checking format of specification file %s... @?" spec_fname; let sub_dir = extract_sub_dir spec_fname in let add_spec, get_line = let add_spec_item i ~file_name ~license_name = @@ -337,7 +339,8 @@ let get_header_files ?directories:(dirs=(get_header_dirs ())) () : let license_path_tbl = Hashtbl.create 23 in List.iter (fun dir -> - job_head "Reading license header definition files from directory %s... @?" dir; + if not !quiet then + job_head "Reading license header definition files from directory %s... @?" dir; if Sys.file_exists dir && Sys.is_directory dir then begin Array.iter (fun filename -> @@ -373,7 +376,8 @@ let get_header_files ?directories:(dirs=(get_header_dirs ())) () : @requires ignored files have been filtered out the specifications *) let check_declared_headers specification headers = - job_head "Checking license specifications are defined... @?" ; + if not !quiet then + job_head "Checking license specifications are defined... @?" ; Hashtbl.iter (fun file header_type -> if not (Hashtbl.mem headers header_type) then begin @@ -429,7 +433,8 @@ let check_spec_discrepancies if ret <> 0 && !debug_flag then extract_header orig_file template_hdr ; ret = 0 in - job_head "Checking specification discrepancies... @?"; + if not !quiet then + job_head "Checking specification discrepancies... @?"; let n = ref 0 in let discrepancies = ref [] in Hashtbl.iter @@ -459,7 +464,8 @@ let check_spec_discrepancies let check_forbidden_headers (forbidden_headers:StringSet.t) header_specifications (distributed_files:StringSet.t) = if not (StringSet.is_empty forbidden_headers) then begin - job_head "Checking that all distributed files have no forbidden header specification... @?"; + if not !quiet then + job_head "Checking that all distributed files have no forbidden header specification... @?"; let forbidden = ref [] in let n = ref 0 in StringSet.iter @@ -492,7 +498,8 @@ let check_forbidden_headers (forbidden_headers:StringSet.t) header_specification * @param exceptions a set of files distributed but that should not be checked *) let check files_ignored header_specifications distributed_files exceptions = - job_head "Checking that all distributed files do exist... @?"; + if not !quiet then + job_head "Checking that all distributed files do exist... @?"; let nonexistent_files = StringSet.filter (fun f -> not (Sys.file_exists f)) distributed_files in @@ -501,7 +508,8 @@ let check files_ignored header_specifications distributed_files exceptions = "@[<v 2># Non-existing files listed as distributed:@ %a@]@." StringSet.pp nonexistent_files; job_done (); - job_head "Checking that distributed exception files have no license header specification... @?"; + if not !quiet then + job_head "Checking that distributed exception files have no license header specification... @?"; let files_licencied = Hashtbl.fold (fun file _ set -> StringSet.add file set) @@ -518,7 +526,8 @@ let check files_ignored header_specifications distributed_files exceptions = "@[<v 2># Files distributed with an header exception (even having to be ignored):@ %a@]@." StringSet.pp ignored_exceptions; job_done (); - job_head "Checking that other distributed files have a license header specification... @?"; + if not !quiet then + job_head "Checking that other distributed files have a license header specification... @?"; let files_to_check = StringSet.diff distributed_files exceptions in let files_specified = StringSet.union files_licencied files_ignored in let distributed_unspecified = StringSet.diff files_to_check files_specified in @@ -527,7 +536,8 @@ let check files_ignored header_specifications distributed_files exceptions = "@[<v 2># Files distributed without specified header:@ %a@]@." StringSet.pp distributed_unspecified; job_done (); - job_head "Checking presence of source files having an header specification... @?" ; + if not !quiet then + job_head "Checking presence of source files having an header specification... @?" ; StringSet.iter (fun filename -> if not (Sys.file_exists filename) then @@ -565,7 +575,8 @@ let update_headers ~config_file_opts header_specifications = else debug "%s : error updating header" filename in - job_head "Updating header files ... @?"; + if not !quiet then + job_head "Updating header files ... @?"; Hashtbl.iter (fun filename header_name -> if Sys.file_exists filename then begin @@ -620,6 +631,8 @@ let rec argspec = [ " print this option list and exits"; "-debug", Arg.Set debug_flag, " enable debug messages"; + "-quiet", Arg.Set quiet, + "disable most messages"; "-forbidden-headers", Arg.String (fun set -> set_cumulative ~name:"-forbidden-headers" forbidden_headers ~set) , "<license name>,... \t none of the checked files may have one of the <license name> []"; @@ -679,7 +692,8 @@ let _ = let ignored_files = ref StringSet.empty in if !from_stdin then read_specs (if !zero_stdin then Zero3 else !spec_format) ignored_files specified_files None; List.iter (fun f -> read_specs !spec_format ignored_files specified_files (Some f)) spec_files; - Format.printf "- ignored=%d@.- specified=%d@." (StringSet.cardinal !ignored_files) (Hashtbl.length specified_files); + if not !quiet then + Format.printf "- ignored=%d@.- specified=%d@." (StringSet.cardinal !ignored_files) (Hashtbl.length specified_files); match !mode with | Check -> let stringset_from_opt_file = function @@ -692,7 +706,8 @@ let _ = in let distributed_files = stringset_from_opt_file distrib_file_opt in let header_exception_files = stringset_from_opt_file header_except_opt in - Format.printf "- excepted=%d@.- distributed=%d@." (StringSet.cardinal header_exception_files) (StringSet.cardinal distributed_files); + if not !quiet then + Format.printf "- excepted=%d@.- distributed=%d@." (StringSet.cardinal header_exception_files) (StringSet.cardinal distributed_files); check ~config_file_opts !ignored_files specified_files distributed_files header_exception_files | Update -> update_headers ~config_file_opts specified_files; -- GitLab