From 84a3559be87ef623d9a2cbca51018be7218835ce Mon Sep 17 00:00:00 2001 From: Zhou SiLe Date: Fri, 14 Jun 2024 16:58:02 +0800 Subject: [PATCH] feat: git hook pre-push (#2359) Signed-off-by: tison Co-authored-by: tison Co-authored-by: hulk --- dev/hooks/pre-push | 41 +++++++++++++++++++++++++++++++++++++++++ x.py | 30 ++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100755 dev/hooks/pre-push diff --git a/dev/hooks/pre-push b/dev/hooks/pre-push new file mode 100755 index 00000000000..f7a0f5239a5 --- /dev/null +++ b/dev/hooks/pre-push @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Check 'format' and 'golangci-lint' before 'git push', +# Copy this script to .git/hooks to activate, +# and remove it from .git/hooks to deactivate. + +set -Euo pipefail + +unset GIT_DIR +ROOT_DIR="$(git rev-parse --show-toplevel)" +cd "$ROOT_DIR" + +run_check() { + local check_name=$1 + echo "Running pre-push script $ROOT_DIR/x.py $check_name" + ./x.py check "$check_name" + + if [ $? -ne 0 ]; then + echo 'You may use `git push --no-verify` to skip this check.' + exit 1 + fi +} + +run_check format +run_check golangci-lint diff --git a/x.py b/x.py index 464d3987e42..710534a2632 100755 --- a/x.py +++ b/x.py @@ -19,9 +19,10 @@ from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, REMAINDER from glob import glob -from os import makedirs +import os from pathlib import Path import re +import filecmp from subprocess import Popen, PIPE import sys from typing import List, Any, Optional, TextIO, Tuple @@ -92,6 +93,24 @@ def check_version(current: str, required: Tuple[int, int, int], prog_name: Optio return semver +def prepare() -> None: + basedir = Path(__file__).parent.absolute() + + # Install Git hooks + hooks = basedir / "dev" / "hooks" + git_hooks = basedir / ".git" / "hooks" + + git_hooks.mkdir(exist_ok=True) + for hook in hooks.iterdir(): + dst = git_hooks / hook.name + if dst.exists(): + if filecmp.cmp(hook, dst, shallow=False): + print(f"{hook.name} already installed.") + continue + raise RuntimeError(f"{dst} already exists; please remove it first") + else: + dst.symlink_to(hook) + print(f"{hook.name} installed at {dst}.") def build(dir: str, jobs: Optional[int], ghproxy: bool, ninja: bool, unittest: bool, compiler: str, cmake_path: str, D: List[str], skip_build: bool) -> None: @@ -106,7 +125,7 @@ def build(dir: str, jobs: Optional[int], ghproxy: bool, ninja: bool, unittest: b cmake_version = output.read().strip() check_version(cmake_version, CMAKE_REQUIRE_VERSION, "CMake") - makedirs(dir, exist_ok=True) + os.makedirs(dir, exist_ok=True) cmake_options = ["-DCMAKE_BUILD_TYPE=RelWithDebInfo"] if ghproxy: @@ -415,6 +434,13 @@ def test_go(dir: str, cli_path: str, rest: List[str]) -> None: parser_test_go.add_argument('rest', nargs=REMAINDER, help="the rest of arguments to forward to go test") parser_test_go.set_defaults(func=test_go) + parser_prepare = subparsers.add_parser( + 'prepare', + description="Prepare scripts such as git hooks", + help="Prepare scripts such as git hooks" + ) + parser_prepare.set_defaults(func=prepare) + args = parser.parse_args() arg_dict = dict(vars(args))