第一篇文章......
我想实现一个仅由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标签的情况下,我的逻辑会出现其他问题吗?
提前致谢。
答案 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] ).
(未经测试。)