9 use OpenSSL::Query::REST;
10 use Module::Load::Conditional qw(can_load);
12 can_load(modules => { 'OpenSSL::Query::DB' => undef });
26 my $query = OpenSSL::Query->new();
30 my @unknown_reviewers;
33 sub try_add_reviewer {
36 my $id2 = $id =~ /^\@(.*)$/ ? { github => $1 } : $id;
37 my $rev = $query->find_person_tag($id2, 'rev');
39 my $cla = $query->has_cla($rev);
41 unless (grep {$_ eq $rev} @reviewers) {
42 $omccount++ if $query->is_member_of($id2, 'omc');
43 push @reviewers, $rev;
47 push @nocla_reviewers, $id
48 unless grep {$_ eq $id} @nocla_reviewers;
51 push @unknown_reviewers, $id
52 unless grep {$_ eq $id} @unknown_reviewers;
53 unless ($id =~ m|^.+\@.*$| && $query->has_cla($id)) {
54 push @nocla_reviewers, $id
55 unless grep {$_ eq $id} @nocla_reviewers;
64 foreach ($query->list_people()) {
65 my $email_id = (grep { ref($_) eq "" && $_ =~ m|\@| } @$_)[0];
66 my $rev = $query->find_person_tag($email_id, 'rev');
67 my $omc = $query->is_member_of($email_id, 'omc');
68 next unless $query->has_cla($rev);
69 next unless $query->is_member_of($email_id, 'commit') || $omc;
71 sort grep { $_ =~ /^[a-z]+$/ || $_ =~ /^\@(?:\w|\w-\w)+$/ }
73 if (ref($_) eq "HASH") {
75 map { $_ eq "github" ? '@'.$h{$_} : $h{$_} } keys %h;
81 $list{$_} = { tag => $rev, omc => $omc };
84 foreach (sort { my $res = $list{$a}->{tag} cmp $list{$b}->{tag};
85 $res != 0 ? $res : ($a cmp $b) } keys %list) {
86 printf "%-15s %-6s (%s)\n",
87 $_, $list{$_}->{omc} ? "[OMC]" : "", $list{$_}->{tag};
90 } elsif (/^--reviewer=(.+)$/) {
92 } elsif (/^--prnum=(.+)$/) {
94 } elsif (/^--commit=(.+)$/) {
97 } elsif (/^--rmreviewers$/) {
99 } elsif (/^--myemail=(.+\@.+)$/) {
100 try_add_reviewer($1);
101 } elsif (/^--verbose$/) {
103 } elsif (/^--web$/) {
105 } elsif (/--tools$/) {
110 my @commit_message = map { (my $x = $_) =~ s|\R$||; $x } <STDIN>;
111 my $trivial = !! grep(/^CLA:\s*Trivial\s*$/i, @commit_message);
113 # If the author is a registered committer, that identity passes as a reviewer
114 # too. There is a twist, though... see next comment
115 if (my $rev = try_add_reviewer($ENV{GIT_AUTHOR_EMAIL})) {
117 # So here's the deal: We added the commit author because we need to keep
118 # count of the total amount of reviewers, which includes the commit author
119 # if it's a registered committer. However, the author can "reviewed
120 # themselves", so no Reviewed-by: should be added for that identity.
121 # However, we still need to check the @reviewers count below, so the
122 # solution is to record this rev tag separately and remove it from
123 # @reviewers after the count check.
124 $skip_reviewer = $rev;
128 # In case the author is unknown to our databases or is lacking a CLA,
129 # we need to be extra careful to check if this is supposed to be a
131 my $author = lc($ENV{GIT_AUTHOR_EMAIL});
133 # Note: it really should be enough to check if $author is unknown, since
134 # the databases are supposed to be consistent with each other. However,
135 # let's be cautious and check both, in case someone has been registered
136 # as a known identity without having a CLA in place.
137 die "Commit author ",$author," has no CLA, and this is a non-trivial commit\n"
138 if !$trivial && grep { $_ eq $author } (@nocla_reviewers);
140 # Now that that's cleared, remove the author from anything that could cause
141 # more unnecessary errors (false positives).
142 @nocla_reviewers = grep { $_ ne $author } @nocla_reviewers;
143 @unknown_reviewers = grep { $_ ne $author } @unknown_reviewers;
146 if (@unknown_reviewers) {
147 die "Unknown reviewers: ", join(", ", @unknown_reviewers), "\n";
149 if (@nocla_reviewers) {
150 die "Reviewers without CLA: ", join(", ", @nocla_reviewers), "\n";
153 print STDERR "Detected trivial marker\n" if $verbose && $trivial;
155 print STDERR "Going with these reviewers:\n ", join("\n ", @reviewers), "\n"
158 if (scalar @reviewers < 2) {
159 die "Too few reviewers (total must be at least 2)\n";
162 die "At least one of the reviewers must be an OMC member\n";
164 if ($skip_reviewer) {
165 @reviewers = grep { $_ ne $skip_reviewer } @reviewers;
166 @nocla_reviewers = grep { $_ ne $skip_reviewer } @nocla_reviewers;
167 @unknown_reviewers = grep { $_ ne $skip_reviewer } @unknown_reviewers;
171 my $commit_id = $ENV{GIT_COMMIT};
173 if ($commit_id =~ /^$_/) {
186 if (scalar @reviewers == 0 && $rmrev == 0) {
187 die "No reviewer set!\n";
190 # Remove blank lines from the end of commit message
191 pop @commit_message while $commit_message[$#commit_message] =~ m|^\s*$|;
194 foreach (@commit_message) {
195 # Start each line with assuming it's not a reviewed-by line
197 if (/^\(Merged from https:\/\/github\.com\/openssl\/$WHAT\/pull\//) {
200 next; # Because we're rewriting it below
201 # (unless --nopr was given in addrev)
202 } elsif (/^Reviewed-by:\s*(\S.*\S)\s*$/) {
206 # Remove reviewers that are already in the message from our reviewer list
207 @reviewers = grep { $_ ne $id } @reviewers;
212 #Add a blank line unless the last one is a review line
213 print "\n" unless $last_is_rev;
214 foreach(@reviewers) {
215 print "Reviewed-by: $_\n";
219 print "(Merged from https://github.com/openssl/$WHAT/pull/$prnum)\n"