Extra prolog predicates to extract files and owners
To simplify the configuration of projects rules, move all the
common rules into the owners plugin and leaves externally accessible:
- add_match_owner_approval (block submit if owners review is needed)
- findall_match_file_user (shows full list of files / owners needed)
Change-Id: I64dcee7495fc76e6abe81ca98b1c419fbc1a819f
diff --git a/owners/src/main/prolog/gerrit_owners.pl b/owners/src/main/prolog/gerrit_owners.pl
index 5d54dc4..89c0aec 100644
--- a/owners/src/main/prolog/gerrit_owners.pl
+++ b/owners/src/main/prolog/gerrit_owners.pl
@@ -3,6 +3,7 @@
:- public add_owner_approval/2.
:- public add_owner_approval/3.
+:- public findall_match_file_user/1.
add_owner_approval(In, Out) :-
owner_path(Path),
@@ -32,3 +33,73 @@
member(X, [X|_]).
member(X, [_|L]) :- member(X, L).
+
+% add extra label for every file F
+findall_match_file_user(FileAndUser) :-
+ matcher_path(F),
+ findall(US,code_review_user(US),Approvers),
+ gerrit_owners:matcher_needed(Approvers,F,FileAndUser).
+
+code_review_user(U) :-
+ gerrit:commit_label(label('Code-Review', 2), user(U)).
+
+% this loops over all the paths and if for any
+% we have some labels generated then add a single
+% Owner-Approval need to block submit button
+add_match_owner_approval(In,Out) :-
+ matcher_path(P),
+ findall(US,code_review_user(US),Approvers),
+ matcher_needed(Approvers,P,W),
+ \+ W == [],
+ Out = [label('Owner-Approval', need(_)) | In], !.
+
+add_match_owner_approval(In,Out) :- Out = In.
+
+matcher_needed(Users,Path,W) :-
+ findall(US,needed_review_user(Path,US),NSL),
+ subtract(Users,NSL,Diff),
+ % if Users - Needed is unchanged this means we are missing at
+ % least one (!)
+ Diff == Users,
+ file_owners(Path,FormattedLabel),
+ W = label(FormattedLabel, need(_)).
+
+needed_review_user(Path,User) :-
+ matcher_owner(Path,user(User)).
+
+%%%%%%%%%%%%%%%
+% utility functions
+%%%%%%%%%%%%%%%
+
+%
+% convert a Var back to a sequence of solutions to be feed
+% in prolog (test purpose).
+%
+enumerate([H|T],F) :- F = H ; enumerate(T,F).
+
+%
+% check if first arg is a member of second list arg
+%
+memberchk(X,[X|_]) :- !.
+memberchk(X,[_|T]):- memberchk(X,T).
+
+%
+% subtract second list from first list giving result
+% used to understand if ApprovedList-NeededList is changed
+% in this case we understand that at least one owner of the matching
+% gave the ok
+%
+subtract([], _, []) :- !.
+subtract([A|C], B, D) :-
+ memberchk(A, B), !,
+ subtract(C, B, D).
+subtract([A|B], C, [A|D]) :-
+ subtract(B, C, D).
+
+append([],L,L).
+append([H|T],L2,[H|L3]) :- append(T,L2,L3).
+
+prepend([],L,L).
+prepend([X|T],L,[X|Result]):- prepend(T,L,Result).
+prepend(X,L,[X|L]).
+