设置预提交挂钩 jshint

Posted

技术标签:

【中文标题】设置预提交挂钩 jshint【英文标题】:setup pre-commit hook jshint 【发布时间】:2013-03-20 03:27:19 【问题描述】:

我最近开了一个project on github。 我已经设法在每次提交后使用 Travis 设置自动测试。但现在我也想用 jshint 设置一个预提交钩子。因此,如果 jshint 报告错误,则提交应该失败。但这可能吗?如果可以,该怎么做?

【问题讨论】:

【参考方案1】:

有一种更简单的方法可以在您的 Node.js 工作流程中进行预提交检查(例如 JSHint):

从 NPM 安装 jshint:

npm install jshint

接下来在您的项目中创建一个 .jshintrc 文件(如果您还没有)。 例如:https://github.com/nelsonic/learn-jshint/blob/master/.jshintrc

现在安装pre-commit 模块(并将其保存为开发依赖项):

npm install pre-commit --save-dev

接下来,您需要在 package.json

中定义将为 JSHint 运行的任务(脚本)

例如:

"scripts": "jshint": "jshint -c .jshintrc --exclude-path .gitignore ."

然后您注册要在提交前运行的脚本(也在 package.json 中),例如:

"pre-commit": [ "jshint", "coverage", "etc" ]

这使您可以在预提交工作流程中进行不止一项检查。 (我们有检查确保团队成员的代码符合 JSHint,代码风格和测试覆盖率是 100%)

如需更详细的教程,您可以与您的团队分享:https://github.com/nelsonic/learn-pre-commit

【讨论】:

嗨。你知道如何设置我要扫描的文件夹吗? @AlexeiBerkov 您是在询问您希望jshint 扫描哪个文件夹?见:jshint.com/docs/cli @nelsonic 预提交挂钩是否仅适用于 jshint 的一组规则?我可以使用另一个 linter 吗? @RicardoGonzales 您可以在pre-commit 中使用 any 命令,所以是的,任何其他 linter 都可以使用。 :-) @nelsonic 很奇怪,因为我的 lint 没有工作,只是暂停了,***.com/questions/47761550/pre-commit-hook-with-lint【参考方案2】:

但这可能吗……

是的!这个有可能。我recently wrote about it。请注意,它不是特定于 GitHub 的,只是一般的 Git - 因为它是一个预提交钩子,它在任何数据发送到 GitHub 之前运行

您的存储库的 /.git/hooks 目录中任何适当命名的可执行文件都将作为挂钩运行。默认情况下,那里可能已经有一堆示例钩子。 Here's a simple shell script 我用作 JSLint 预提交钩子(您可以很容易地修改它以使用 JSHint):

#!/bin/sh

files=$(git diff --cached --name-only --diff-filter=ACM | grep "\.js$")
if [ "$files" = "" ]; then 
    exit 0 
fi

pass=true

echo "\nValidating javascript:\n"

for file in $files; do
    result=$(jslint $file | grep "$file is OK")
    if [ "$result" != "" ]; then
        echo "\t\033[32mJSLint Passed: $file\033[0m"
    else
        echo "\t\033[31mJSLint Failed: $file\033[0m"
        pass=false
    fi
done

echo "\nJavaScript validation complete\n"

if ! $pass; then
    echo "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass JSLint but do not. Please fix the JSLint errors and try again.\n"
    exit 1
else
    echo "\033[42mCOMMIT SUCCEEDED\033[0m\n"
fi

你可以简单地将它放在你的 Git hooks 目录中一个名为 pre-commit 的可执行文件中,它会在每次提交之前运行。

【讨论】:

非常感谢!!但是,我一定做错了什么,因为我无法让它工作。我已经在 .git/hooks 中创建了该文件并使其可执行。现在,当我提交一个带有“太多错误”的文件时,它只会提交它。另外,当我手动运行钩子时,我被困在 /bin/sh.h 中。现在,当我键入“exit”时,我收到“COMMIT FAILED”消息。有什么建议吗? 我刚刚注意到,即使是“git init”项目中的预提交挂钩也不起作用。所以我发现一个预提交钩子应该被命名为'pre-commit' :) 所以它现在工作得很好。我将 jsLint 修改为 jsHint 并将 grep 修改为:“egrep”errors?$”。但是如果我想要多个预提交挂钩怎么办,这可能吗? 很高兴你让它工作:) 据我所知,不幸的是你不能有多个钩子。最简单的解决方法是将它们简单地合并到一个文件中。 对于那些想知道 JSHint 最终版本是什么样子的人:pastie.org/pastes/8392390/text 注意grep有错误。应该是"\.js$"【参考方案3】:

对@James Allardice 脚本进行了一些更改以适应JSHint。感谢原始代码。

#!/bin/sh
#
# Run JSHint validation before commit.

files=$(git diff --cached --name-only --diff-filter=ACMR -- *.js **/*.js)
pass=true


if [ "$files" != "" ]; then
    for file in $files; do
        result=$(jshint $file)

        if [ "$result" != "" ]; then
            echo "$result"
            echo "\n"
            pass=false
        fi
    done
fi


if $pass; then
    exit 0
else
    echo ""
    echo "COMMIT FAILED:"
    echo "Some JavaScript files are invalid. Please fix errors and try committing again."
    exit 1
fi

【讨论】:

【参考方案4】:

类似于@igor 的脚本,但有一些改进:

颜色指示器 没有 --diff-filter, grep 使用 insead 帮助消息(git 风格)避免 pre-commit 调用
#!/bin/sh
#
# Run JSHint validation before commit.

RED='\033[0;31m'
REDBOLD='\033[1;31m'
ORANGE='\033[0;33m'
NC='\033[0m' # No Color

files=$(git diff --cached --name-only | grep .js)
pass=true
totalErrors=0

if [ "$files" != "" ]; then
    for file in $files; do
        result=$(jshint $file)
        if [ "$result" != "" ]; then
            echo "$RED$result$NC"
            pass=false
            totalErrors=$((totalErrors+1))
        fi
        echo ""
    done
fi

if $pass; then
    exit 0
else
    echo "$ORANGE===== $totalErrors JSHint Error$NC"
    echo ""
    echo "$REDBOLDCOMMIT FAILED: Some JavaScript files are invalid. Please fix errors and try committing again.$NC"
    echo ""
    echo "  (use -n option \"git commit -n -m <message>\" to avoid call pre-commit hook and JSHint check)"
    echo ""
    exit 1
fi

【讨论】:

看起来不错! :) 这只是 *nix。

以上是关于设置预提交挂钩 jshint的主要内容,如果未能解决你的问题,请参考以下文章

Git 预提交挂钩未在 Windows 上运行

有没有办法让 git commit --verbose 在使用预提交挂钩时显示更新的差异?

GitHub:预接收挂钩

预提交挂钩失败

Git 预提交挂钩:更改/添加的文件

预提交/挂钩:没有这样的文件或目录