What's cooking (2024/04 #09)
[git.git] / add-by
blob650abf19370da9d6e300a40a3fd246be4cc26550
1 #!/usr/bin/perl
3 use warnings;
4 use strict;
5 use Getopt::Long;
7 sub parsing () { 1; }
8 sub waiting () { 2; }
9 my $state = parsing;
11 my @more;
12 my $append;
13 my $debug;
15 sub find_author {
16 my $map = shift;
17 for my $name (@_) {
18 my $fh;
19 print STDERR "Checking <$name>..."
20 if ($debug);
21 if (!open($fh, "-|",
22 qw(git log -1 --no-merges),
23 '--format=%an <%ae>',
24 "--author=$name",
25 "--all")) {
26 print STDERR "opening pipe to read from git log failed\n"
27 if ($debug);
28 $map->{$name} = $name;
29 next;
31 my $line = <$fh>;
32 if ($line) {
33 chomp $line;
34 print STDERR "read <$line> from git log\n"
35 if ($debug);
36 $map->{$name} = $line;
37 } else {
38 print STDERR "read false ($line) from git log\n"
39 if ($debug);
40 $map->{$name} = $name;
45 sub accumulate {
46 push @more, [@_];
49 my $mine;
51 sub compute_bylines {
52 my %names = map { $_->[1] => 1 } @more;
53 my %map = ();
54 my @append;
55 find_author(\%map, keys (%names));
56 for (@more) {
57 my ($tag, $name) = @$_;
58 if ($tag eq 'mine') {
59 $mine = $map{$name};
60 next;
62 $tag = ucfirst($tag);
63 push @append, "$tag: $map{$name}";
65 if (@append) {
66 $append = join("\n", @append) . "\n";
67 } else {
68 $append = "";
72 sub add_more_bylines {
73 if (!defined $append) {
74 compute_bylines();
76 print $append;
79 my $check_only;
81 exit 1 unless (GetOptions("signed-off-by=s" => \&accumulate,
82 "acked-by=s" => \&accumulate,
83 "reviewed-by=s" => \&accumulate,
84 "tested-by=s" => \&accumulate,
85 "helped-by=s" => \&accumulate,
86 "check-only!" => \$check_only,
87 "mine=s" => \&accumulate,
88 "debug!" => \$debug,
89 ));
91 compute_bylines();
93 if ($check_only) {
94 add_more_bylines();
95 exit 0;
98 my $seen_mine = 0;
99 while (<>) {
100 if ($state == parsing) {
101 if (/^[-A-Za-z]+-by: /i || /^Cc: /i) {
102 $state = waiting;
104 } elsif ($state == waiting) {
105 if (defined $mine && /^Signed-off-by: \Q$mine\E/) {
106 $seen_mine = 1;
107 next;
108 } elsif (/^[-A-Za-z]+-by: /i || /^Cc: /i) {
109 $state = waiting;
110 } else {
111 add_more_bylines();
112 if ($seen_mine) {
113 print "Signed-off-by: $mine\n";
115 $state = parsing;
116 $seen_mine = 0;
119 print;