【问题标题】:Git Pre-push hooks not aborting push in case of more than one checksGit Pre-push 钩子不会在多次检查的情况下中止推送
【发布时间】:2018-11-02 18:04:04
【问题描述】:

在 git 钩子中 - 我想在推送之前检查 jshint 错误和纱线完整性检查,所以我在 pre-push 中添加了下面。 所以它是这样的 -

    # Pre-push hooks
    # Lint stuff before committing
    grunt jshint eslint tslint
    # Verifies that versions and hashed value of the package contents 
      in the project’s package.json matches that of yarn’s lock file.
    yarn check --integrity
  • 这里如果 jshint 给出错误但如果纱线完整性检查通过,仍然 它允许推动。如果纱线失败,它将中止。
  • 如果我颠倒顺序然后如果纱线检查失败并且如果 jshint 通过, 然后它也会推动。如果 jshint 失败,它将中止。

因此只有在最后一次检查失败时才会推送失败,而在其他情况下它会声明错误但仍会推送它

【问题讨论】:

  • 无耻插件,但您可以查看我的助手git-riff,它允许您为钩子中的每个任务编写单独的脚本并为您处理这种情况。

标签: git shell githooks yarnpkg


【解决方案1】:

在这里自我宣传:如果你想很花哨,你可以使用我前段时间写的辅助函数(用于提交挂钩)。

你这样运行它:

set -e

run_check 'flake8' . flake8
run_check 'ESLint' . ./node_modules/eslint/bin/eslint.js frontend/js
exit_test

得到这样的输出:

flake8 OK
ESLint OK

或者如果你不太幸运:

./frontend/tests.py:8:83: E999 SyntaxError: invalid syntax
flake8 FAILED

/home/frax/Programowanie/organizer/organizer2/frontend/js/utils.js
  11:18  error  Parsing error: Unexpected token ;

✖ 1 problem (1 error, 0 warnings)

ESLint FAILED
Some check(s) failed.

exit_test 的退出码是上次检查失败的退出码。当使用set -e 时,它成为整个脚本的退出代码。

代码:

# Use run_check to run groups of independent tests, that should all be run even
# if some of them fail (but you still want to know about failure).

# testing_exit_code variable stores last non-zero exit code of the check, or 0,
# if no check failed so far.

# Important note: using trap prevents set -e from intercepting check failures,
# so it's safe (and recommended) to use -e in testing script.

# Example:

#
#    run_check 'Foo check' . echo Foo
#    run_check 'Bar check' . echo Bar
#    exit_test  # fail if any test failed
#

testing_exit_code=0

function run_check () {
    # Usage: run_check <check name> <working directory> <command> [args...]
    local cmd="$1"
    trap 'testing_exit_code=$?; echo "$cmd FAILED"; return 0' ERR
    local cmd_wd="$2"
    shift 2
    ( cd "$cmd_wd" && "$@" )  # run the command
    echo "$cmd OK"
}

function exit_test () {
    if (( testing_exit_code != 0 )); then
        echo "Some check(s) failed."
    fi
    exit $testing_exit_code
}

如果添加一些颜色,输出​​看起来会更好。实际上,我的原始脚本中有它们,但为了简洁和可移植性而省略了它们。如果您有兴趣,我可以单独分享带有颜色的版本。

【讨论】:

    【解决方案2】:

    这真是一个关于编写脚本的问题。

    在 sh/bash 脚本中,一系列命令只是运行这一系列命令:

    cmd1
    cmd2
    cmd3
    

    任何一个命令“失败”都没有关系(返回非零退出状态);脚本继续运行下一个。

    脚本的最终退出状态是最后运行的命令的退出状态,除非您提供特定状态:

    exit 0
    

    (零表示成功)。

    如果您希望在任何命令失败后立即退出,您可以设置-e 选项:

    set -e
    cmd1
    cmd2
    cmd3
    

    这是相当粗略的,并不总是正确的做法。请注意,如果 cmd2 失败(退出非零),cmd3 甚至不会启动,但 shell 会以 cmd2 的失败退出状态退出。

    为了特别花哨,可以保存每个命令的退出状态:

    cmd1; cmd1_status=$?
    cmd2; cmd2_status=$?
    cmd3; cmd3_status=$?
    

    $? 变量扩展为刚刚运行的命令的退出状态。

    当然,现在你必须弄清楚如何处理这三个状态,因为你只能退出其中的一个,但你现在可以退出哪个先失败,如果有的话:

    test $cmd1_status != 0 && exit $cmd1_status
    test $cmd2_status != 0 && exit $cmd2_status
    exit $cmd3_status
    

    现在您的脚本无条件运行所有三个命令,但返回第一个非零失败的状态。如果 cmd1 和 cmd2 都返回零状态,则脚本以 cmd3 的状态退出。

    【讨论】:

    • 对于 2 cmnds,test cmd1_status != 0 && exit $cmd1_status test cmd2_status != 0 && exit $cmd2_status 即使最后一个命令失败,它仍然会推送
    • 我上面有两个错别字,我会改正的。同时,如果不是这样,请显示确切的代码(可能剪切并粘贴到原始问题中;记得使用“格式即代码”stackoverflow 标记)。
    猜你喜欢
    • 2013-12-01
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 2017-07-16
    • 2017-09-19
    • 1970-01-01
    • 2016-07-13
    相关资源
    最近更新 更多