35

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

4

4 回答 4

42

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

从 NPM安装jshint :

npm install jshint

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

现在安装预提交模块(并将其保存为开发依赖项):

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

于 2014-10-24T22:31:25.703 回答
41

但这可能吗……

是的!这个有可能。我最近写过它。请注意,它不是特定于 GitHub,只是一般的 Git - 因为它是一个预提交挂钩,它任何数据发送到 GitHub 之前运行。

存储库的/.git/hooks目录中任何适当命名的可执行文件都将作为挂钩运行。默认情况下,那里可能已经有一堆示例钩子。这是一个简单的 shell 脚本,我将它用作 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的可执行文件中,它会在每次提交之前运行。

于 2013-04-02T06:56:27.253 回答
16

对@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
于 2014-01-20T16:17:27.260 回答
2

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

  • 颜色指示器
  • 没有 --diff-filter, grep 使用 insead
  • 帮助消息(git 样式)以避免预提交调用

#!/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 "${REDBOLD}COMMIT 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
于 2016-09-02T08:59:55.567 回答