From 8b912aad86227a0281bb8161b700b9bfa09469b6 Mon Sep 17 00:00:00 2001
From: Mathieu Courtois <mathieu.courtois@edf.fr>
Date: Wed, 18 Dec 2024 17:55:20 +0100
Subject: [PATCH] [#34305] add pre-push hook

---
 bin/hooks/git_hook_main        | 21 ++++++-------
 bin/install_env                |  2 +-
 lib/hgaster/hooks/codeaster.py | 55 +++++++++++++++++++++++-----------
 3 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/bin/hooks/git_hook_main b/bin/hooks/git_hook_main
index 37657af0..6258d028 100755
--- a/bin/hooks/git_hook_main
+++ b/bin/hooks/git_hook_main
@@ -15,7 +15,7 @@ import re
 from aslint.i18n import _
 from aslint.logger import SetLevelAction, logger
 from aslint.utils import remove_lines
-from hgaster.hooks.codeaster import precommit_git
+from hgaster.hooks.codeaster import precommit_git, run_ctest_minimal
 from hgaster.hooks.generic import NOOK, OK, check_commit_msg
 from repository_api import repository_switch
 
@@ -37,6 +37,9 @@ def main(repotype, repopath, hook, amend, *args):
             logger.error("commit-msg: check commit message ended with errors.")
         return OK
 
+    if hook == "pre-push":
+        return run_ctest_minimal()
+
     logger.error(_("hook '{0}' is not defined").format(hook))
     return 1
 
@@ -62,16 +65,14 @@ if __name__ == "__main__":
         help=_("call commit-msg hook"),
     )
     parser.add_argument(
-        "--amend",
-        action="store_true",
-        help=_("enabled for 'commit --amend'"),
-    )
-    parser.add_argument(
-        "-R",
-        "--repository",
-        default=".",
-        help=_("repository path"),
+        "--pre-push",
+        action="store_const",
+        dest="hook",
+        const="pre-push",
+        help=_("call pre-push hook"),
     )
+    parser.add_argument("--amend", action="store_true", help=_("enabled for 'commit --amend'"))
+    parser.add_argument("-R", "--repository", default=".", help=_("repository path"))
     parser.add_argument("paths", nargs="*", help="additional arguments passed to hook script")
 
     args = parser.parse_args()
diff --git a/bin/install_env b/bin/install_env
index 0d1599e0..e37c2b49 100755
--- a/bin/install_env
+++ b/bin/install_env
@@ -274,7 +274,7 @@ def main(repocfg, repodir, options):
                     git_config_set("remote.origin.url", asked)
 
             entrypoint = osp.join(InstallEnv.root, "bin", "hooks", "git_hook_entrypoint")
-            for hook in ("commit-msg", "pre-commit"):
+            for hook in ("commit-msg", "pre-commit", "pre-push"):
                 dest = osp.join(osp.join(rootdir, repo), ".git", "hooks", hook)
                 if options.reset and (osp.exists(dest) or osp.lexists(dest)):
                     os.remove(dest)
diff --git a/lib/hgaster/hooks/codeaster.py b/lib/hgaster/hooks/codeaster.py
index 443b900e..0b6687d6 100644
--- a/lib/hgaster/hooks/codeaster.py
+++ b/lib/hgaster/hooks/codeaster.py
@@ -4,18 +4,13 @@
 
 import os
 import os.path as osp
+from pathlib import Path
 
 from aslint.logger import logger
 from repository_api import get_branch, get_main_branch, get_repo_name, repository_type
 
 from ..ext_utils import get_changed_files, is_admin
-from .generic import (
-    NOOK,
-    OK,
-    branch_checker,
-    branch_user_commit_hook,
-    branch_user_push_hook,
-)
+from .generic import NOOK, OK, branch_checker, branch_user_commit_hook, branch_user_push_hook
 
 # authorized branches names (+ vNN)
 AUTH_BRANCH = ("^default$", "^edf/", "^asterxx/", "^v([0-9]+(\.[0-9]+)?(_smeca)?)$")
@@ -37,10 +32,7 @@ def precommit_git(repopath, amend):
     # do pretxncommit: check branch, message
     branch = get_branch(repopath)
     if git_branch_checker(branch) is NOOK:
-        logger.error(
-            "You are not allowed to commit in " "branch {0!r}.".format(branch),
-            exit=True,
-        )
+        logger.error("You are not allowed to commit in " "branch {0!r}.".format(branch), exit=True)
     return aslint(repopath, amend=amend)
 
 
@@ -77,8 +69,7 @@ def aslint(repopath, paths=(), amend=False):
             "your ~/.gitconfig file."
         )
         logger.info(
-            "pre-commit: To hide this message you can set the value "
-            "'check-precommit = yes'."
+            "pre-commit: To hide this message you can set the value " "'check-precommit = yes'."
         )
     elif choice != "yes":
         logger.warn(
@@ -115,9 +106,7 @@ def aslint(repopath, paths=(), amend=False):
         else:
             logger.info("pre-commit: no files to be checked")
         if fixed and repository_type(repopath) == "git":
-            logger.warn(
-                "pre-commit: some files were automatically fixed and added by running:"
-            )
+            logger.warn("pre-commit: some files were automatically fixed and added by running:")
             toadd = dchg.get("A", []) + dchg.get("M", [])
             cmd = ["git", "add"] + toadd
             logger.info(" ".join(cmd))
@@ -127,7 +116,7 @@ def aslint(repopath, paths=(), amend=False):
         report.report_summary()
         answ = input(
             "The commit will be not accepted because of remaining "
-            "errors.\nDo you want to continue (y/n) ?"
+            "errors.\nDo you want to continue (y/n) ? "
         )
         if answ.lower() not in ("y", "o"):
             logger.info("pre-commit: aslint ended with errors.")
@@ -135,3 +124,35 @@ def aslint(repopath, paths=(), amend=False):
         else:
             logger.cancel_error()
     return OK
+
+
+def run_ctest_minimal():
+    """Run a minimal list of testcases."""
+    from subprocess import call
+
+    from aslint.check_files import read_waf_parameters
+    from aslint.config import ASCFG
+
+    logger.warning("Run a minimal list of testcases (for about 30 seconds).")
+    logger.info("NB: It will used the already installed version.")
+    try:
+        answ = input("Do you want to continue (y/[n], 'Ctrl+C' to abort push) ? ")
+    except KeyboardInterrupt:
+        return NOOK
+    if answ.lower() not in ("y", "o"):
+        logger.info("run_ctest skipped.")
+        return OK
+
+    builddir = ASCFG.get("waf.builddir")
+    target = "release"
+    if os.environ.get("BUILD") == "debug":
+        builddir = "build/mpidebug" if osp.isdir("build/mpidebug") else "build/mpi"
+        target = "debug"
+    wafc4che = osp.join(builddir, "c4che", target + "_cache.py")
+
+    c4che = read_waf_parameters(wafc4che)
+    run_ctest = Path(c4che["BINDIR"]) / "run_ctest"
+    cmd = [run_ctest, "-R", "(asrun0|mumps02b|supv002|vocab0|zzzz509j)", "--no-resutest"]
+    if call(cmd):
+        return NOOK
+    return OK
-- 
GitLab