【问题标题】:Prevent Gulp Spawn Child Process Error On Exit Due to Grep Not Finding Match由于 Grep 未找到匹配项,防止 Gulp Spawn 子进程在退出时出错
【发布时间】:2016-07-12 03:23:00
【问题描述】:

将 child_process 和 Gulp 4 与 git guppy 一起使用,我在一个任务中生成一个子进程,以响应运行一个小型 bash 脚本的 git 钩子。

BASH 脚本

#!/usr/bin/env bash

changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"

added_files="$(git diff-tree -r --name-only --diff-filter=AR --no-commit-id ORIG_HEAD HEAD)"

check_run() {
    echo "$changed_files" | grep --quiet "$1" && eval "$2"
}

check_add() {
    echo "$added_files" | grep --quiet "$1" && eval "$2"
}

# Run `npm install` if package.json changed, `bower install` if `bower.json`,
# or `composer install` if composer.json has changed.
check_run package.json "npm install"
check_run bower.json "bower install"
check_run composer.json "composer install"

GULP 文件

gulp.task('post-checkout', gulp.series(
    'post-checkout-install',
    ...
));

gulp.task('post-checkout-install', function () {

    return cp.spawn('sh', ['./bash/git/hooks/post-merge.sh'], {
        stdio: 'inherit',
        cwd: process.cwd()
    });
});

我已经在 /.git/hooks 中测试了合并后脚本文件,它工作正常,但是当使用 Gulp 通过生成的 shell 执行此操作时,它会抛出此错误:

$ gulp post-checkout
[19:48:27] Using gulpfile D:\projects\app\gulpfile.js
[19:48:27] Starting 'post-checkout'...
[19:48:27] Starting 'post-checkout-install'...
[19:48:28] 'post-checkout-install' errored after 200 ms
[19:48:28] Error: exited with error code: 1
    at ChildProcess.onexit (D:\projects\app\node_modules\end-of-stream\index.js:39:23)
    at emitTwo (events.js:87:13)
    at ChildProcess.emit (events.js:172:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
[19:48:28] 'post-checkout' errored after 208 ms

测试

所以我拆分了命令以查看可能导致问题的原因,从下面的 sn-ps 看来,这似乎都是由于 grep 在 diff 列表中找不到文件或文件扩展名,这不会导致直接作为 gulp hook 运行时的任何问题。

# No error just running this by itself and it returns the diff list
git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD

# Fails I believe since package.json isn't in the diff list, since the
# same command with .js, .css, and .json fails, but .html passes since
# there are only .html files in the diff list
git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD | grep "package.json"

# No error and runs npm install since .html files are in the diff list
git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD | grep ".html" && eval "npm install"

那么我该如何阻止它仅仅因为在列表中找不到文件或文件类型而退出上述错误?我尝试在 grep 中添加 -ef 标志,但这也不起作用。

更新

这似乎压制了抛出的错误。我不确定是否需要退出该过程,但无论如何都添加了它并调用了 done 回调。也就是说,它仍然无法正常运行。

gulp.task('post-checkout-install', function (done) {

    return cp.spawn('sh', ['./bash/git/hooks/post-merge.sh'], {
        stdio: 'inherit',
        cwd: process.cwd()
    }).on('exit', function (code) {

        done();

        process.exit(code);
    });
});

【问题讨论】:

    标签: git bash gulp


    【解决方案1】:

    如果您不希望 grep 的非零退出状态导致 check_runcheck_add 的非零退出状态,则将它们重写如下:

    check_run() {
        if echo "$changed_files" | grep --quiet "$1"
        then
            eval "$2"
        fi
    }
    
    check_add() {
        if echo "$added_files" | grep --quiet "$1"
        then
            eval "$2"
        fi
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 2011-02-12
      相关资源
      最近更新 更多