blob: 4247e638eded6675a09f7e809e504bf032babca5 [file] [log] [blame]
% submit_rule in the actual project (go, scratch, etc.)
% generates a list of labels and whether they are ok, needed, or can be ignored.
% Most repos don't define a specific submit_rule; the server uses gerrit:default_submit.
%
% submit_filter, defined below, is applied to the output of submit_rule to adjust it.
% The adjustments are:
%
% * do_not_review_filter: add a “rejected by Do-Not-Review label”
% if the commit message says DO NOT REVIEW.
%
% * do_not_submit_filter: add a “rejected by Do-Not-Submit label”
% if the commit message says DO NOT SUBMIT.
%
% * trust_filter: make sure that two different people have set
% either Code-Review+2 or Trust+1 on the commit.
%
% * self_review_filter: make sure that Code-Review+2
% is from someone other than the author of the commit.
%
% Note that if you make any mistake in this file that causes
% a Prolog execution exception or makes submit_filter not succeed,
% the usual signal you get in Gerrit is that labels disappear from the UI for all CLs.
% Sometimes you get an internal error popup instead (syntax errors do this, for example).
submit_filter(In, Out) :-
Gobot = user(5976),
In =.. [submit | A],
do_not_review_filter(Gobot, A, B),
do_not_submit_filter(Gobot, B, C),
trust_filter(Gobot, C, D),
self_review_filter(Gobot, D, E),
Out =.. [submit | E].
% We don't send email if the commit message says DO NOT REVIEW,
% so don't allow submit either.
% Case insensitive because the mail filter rules are.
do_not_review_filter(Gobot, In, Out) :-
gerrit:commit_message_matches('[Dd][Oo][ \t\r\n]+[Nn][Oo][Tt][ \t\r\n]+[Rr][Ee][Vv][Ii][Ee][Ww]'),
!,
gerrit:commit_author(Id),
Error = label('Do-Not-Review', reject(Id)),
Out = [Error | In].
do_not_review_filter(Gobot, In, Out) :-
Out = In.
% Don't allow submit of DO NOT SUBMIT commit message either.
% Case insensitive because DO NOT REVIEW is.
do_not_submit_filter(Gobot, In, Out) :-
gerrit:commit_message_matches('[Dd][Oo][ \t\r\n]+[Nn][Oo][Tt][ \t\r\n]+[Ss][Uu][Bb][Mm][Ii][Tt]'),
!,
gerrit:commit_author(Id),
Error = label('Do-Not-Submit', reject(Id)),
Out = [Error | In].
do_not_submit_filter(Gobot, In, Out) :-
Out = In.
% Check for two trusted author/reviewers, unless Self-Review-OK label set by project.
trust_filter(Gobot, In, Out) :- has_label('Self-Review-OK', In), !, Out = In.
trust_filter(Gobot, In, Out) :- trust2, !, Out = [label('Trust-2', ok(Gobot)) | In].
trust_filter(Gobot, In, Out) :- Out = [label('Trust-2', reject(Gobot)) | In].
trust2 :- trust(U1), trust(U2), U1 \= U2.
trust(U) :- gerrit:commit_label(label('Code-Review', 2), U).
trust(U) :- gerrit:commit_label(label('Trust', 1), U).
% Reject self-code-review, unless Self-Review-OK label set by project.
%
% NOTE: Projects (= repos) that allow self-code-review and that do not require Trust+2
% (for example, the blog and proposal projects), can use this in rules.pl to set Self-Review-OK:
%
% submit_rule(S) :-
% Gobot = user(5976),
% gerrit:default_submit(R),
% R =.. [submit | A],
% self_review_ok(Gobot, A, B),
% S =.. [submit | B].
%
% self_review_ok(Gobot, In, Out) :- Out = [label('Self-Review-OK', ok(Gobot)) | In].
%
self_review_filter(Gobot, In, Out) :- has_label('Self-Review-OK', In), !, Out = In.
self_review_filter(Gobot, In, Out) :- self_review, !, Out = [label('Self-Review', reject(Gobot)) | In].
self_review_filter(Gobot, In, Out) :- Out = In.
self_review :-
gerrit:change_owner(Owner),
gerrit:commit_label(label('Code-Review', 2), Owner).
% has_label checks whether the list contains the label L.
has_label(L, [label(L, _) | T]).
has_label(L, [_ | T]) :- has_label(L, T).