rules.pl: add Trust+2 check and disallow self-code-review For golang/go#40699. Change-Id: I681f08cb84aa9bf4b227188594ea02c2727b3697 Reviewed-on: https://go-review.googlesource.com/c/All-Projects/+/254799 Reviewed-by: Andrew Bonventre <andybons@google.com>
diff --git a/rules.pl b/rules.pl index 88efe81..4247e63 100644 --- a/rules.pl +++ b/rules.pl
@@ -1,22 +1,93 @@ -% 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. +% 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) :- - In =.. [submit | I], + 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 =.. [submit, Error | I]. + 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. -submit_filter(In, Out) :- - In =.. [submit | I], +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 =.. [submit, Error | I]. + Out = [Error | In]. -% Otherwise, pass submit rule through. -submit_filter(In, Out) :- In = Out. +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).