Gerrit NACR仅对主人执行 - 如何执行?

时间:2017-02-01 11:10:26

标签: prolog gerrit

第一篇文章......

我想实现一个仅由Gerrit在master分支上强制执行的NACR。

我已经在我的项目中为所有分支实施了NACR rules.pl。但我的Prolog是......好吧......不存在!所以,当我试图理解它的时候......

我认为最简单的方法是将NACR与谓词结合使用,以便在分支不是主分支或发布分支时将其删除?可能不那么有效,但可能很简单?

[Aplogies - 只在Prolog Gerrit的背景下思考 - 在这个有限的领域之外还有更多的Prolog人!]

NACR - 来自https://gerrit-review.googlesource.com/Documentation/prolog-cookbook.html#NonAuthorCodeReview的非作者代码审核

这是有效的序言,并将此NACR标签添加到gerrit更改

submit_rule(S) :-
    gerrit:default_submit(X),
    X =.. [submit | Ls],
    add_non_author_approval(Ls, R),
    S =.. [submit | R].

add_non_author_approval(S1, S2) :-
    gerrit:commit_author(A),
    gerrit:commit_label(label('Code-Review', 2), R),
    R \= A, !,
    S2 = [label('Non-Author-Code-Review', ok(R)) | S1].
add_non_author_approval(S1, [label('Non-Author-Code-Review', need(_)) | S1]).

我想的是添加类似nacr_on_master()的内容,以便在分支B不是主git分支的情况下删除NACR标签,例如

submit_rule(S) :-
    gerrit:default_submit(X),
    X =.. [submit | Ls],
    add_non_author_approval(Ls, Ri),
    nacr_on_master(Ri, R)
    S =.. [submit | R].

nacr_on_master(S1, S2) :-
  %need NACR on master
  gerrit:change_branch(B),
  B \= 'refs/heads/master',
  removehead(S1, S2). %remove last item added, which is the NACR label on head

removehead([_|Tail], Tail).

add_non_author_approval(S1, S2) :-
    gerrit:commit_author(A),
    gerrit:commit_label(label('Code-Review', 2), R),
    R \= A, !,
    S2 = [label('Non-Author-Code-Review', ok(R)) | S1].

add_non_author_approval(S1, [label('Non-Author-Code-Review', need(_)) | S1]).

这适用于分支B是refs / heads / master,但如果不是我从Gerrit的Prolog引擎中得到错误

[
  {
    "status": "RULE_ERROR",
    "error_message": "Submit rule \u0027:(user,submit_rule)\u0027 for change 1 of proj-1-1 has no solution.",
    "prolog_reduction_count": 2766
  }
]

我理解问题可能是什么,但我不知道如何处理不同分支以确保有解决方案的情况。我希望在没有添加NACR标签的情况下,我的逻辑会出现其他问题吗?

提前致谢。

1 个答案:

答案 0 :(得分:2)

我对格里特一无所知,但我想我理解你想要做的Prolog部分。

我将使用以下模块来模拟Gerrit:

:- module(gerrit, [
        default_submit/1,
        commit_author/1,
        commit_label/2,
        change_branch/1
    ]).

default_submit(submit([])).

commit_author(banman).

commit_label(label('Code-Review', 2), banman).

change_branch('refs/heads/master').
%change_branch('refs/heads/changes').

在SWI-Prolog中,可以在包含代码的其他模块中使用此方法,方法是在文件顶部添加:- use_module(gerrit).

然后您的问题可归结为以下内容:致电submit_rule(S)应始终成功。但是,使用您的代码时,它只会成功change_branch('refs/heads/changes'),但会因change_branch('refs/heads/master')而失败。

我认为最简单的解决方案是使用原始submit_rule/1并在add_non_author_approval/2添加一个额外条款来表达您的附加政策:

% No change to label list if we are not on master.
add_non_author_approval(S, S) :-
    gerrit:change_branch(B),
    B \= 'refs/heads/master',
    !.

由于整个事物的控制流程不纯,所以必须在其他两个条款之前添加。有了这个,你就不需要你的nacr_on_master/2谓词。

让我们测试一下:

% on master
?- submit_rule(S).
S = submit(label('Non-Author-Code-Review', need(_G2531)), []).

% on another branch
?- submit_rule(S).
S = submit([]).

我认为这可以做你想要的。

编辑:通过避免否定以及使用if-then-else代替剪切,整个代码变得更加清晰:

add_non_author_approval(S1, S2) :-
    gerrit:commit_author(A),
    gerrit:commit_label(label('Code-Review', 2), R),
    (   A = R
    ->  % Author and reviewer are the same person. If we are on master,
        % require another non-author code review.
        (   gerrit:change_branch('refs/heads/master')
        ->  S2 = [label('Non-Author-Code-Review', need(_)) | S1]
        ;   % On branches other than master, nothing is needed.
            S2 = S1 )
    ;   % Author and reviewer are different persons, all is well.
        S2 = [label('Non-Author-Code-Review', ok(R)) | S1] ).

(未经测试。)