aboutsummaryrefslogtreecommitdiffstats
path: root/add-by
blob: 650abf19370da9d6e300a40a3fd246be4cc26550 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/perl

use warnings;
use strict;
use Getopt::Long;

sub parsing () { 1; }
sub waiting () { 2; }
my $state = parsing;

my @more;
my $append;
my $debug;

sub find_author {
	my $map = shift;
	for my $name (@_) {
		my $fh;
		print STDERR "Checking <$name>..."
		    if ($debug);
		if (!open($fh, "-|",
			  qw(git log -1 --no-merges),
			  '--format=%an <%ae>',
			  "--author=$name",
			  "--all")) {
			print STDERR "opening pipe to read from git log failed\n"
			    if ($debug);
			$map->{$name} = $name;
			next;
		}
		my $line = <$fh>;
		if ($line) {
			chomp $line;
			print STDERR "read <$line> from git log\n"
			    if ($debug);
			$map->{$name} = $line;
		} else {
			print STDERR "read false ($line) from git log\n"
			    if ($debug);
			$map->{$name} = $name;
		}
	}
}

sub accumulate {
	push @more, [@_];
}

my $mine;

sub compute_bylines {
	my %names = map { $_->[1] => 1 } @more;
	my %map = ();
	my @append;
	find_author(\%map, keys (%names));
	for (@more) {
		my ($tag, $name) = @$_;
		if ($tag eq 'mine') {
			$mine = $map{$name};
			next;
		}
		$tag = ucfirst($tag);
		push @append, "$tag: $map{$name}";
	}
	if (@append) {
		$append = join("\n", @append) . "\n";
	} else {
		$append = "";
	}
}

sub add_more_bylines {
	if (!defined $append) {
		compute_bylines();
	}
	print $append;
}

my $check_only;

exit 1 unless (GetOptions("signed-off-by=s" => \&accumulate,
			  "acked-by=s" => \&accumulate,
			  "reviewed-by=s" => \&accumulate,
			  "tested-by=s" => \&accumulate,
			  "helped-by=s" => \&accumulate,
			  "check-only!" => \$check_only,
			  "mine=s" => \&accumulate,
			  "debug!" => \$debug,
	       ));

compute_bylines();

if ($check_only) {
	add_more_bylines();
	exit 0;
}

my $seen_mine = 0;
while (<>) {
	if ($state == parsing) {
		if (/^[-A-Za-z]+-by: /i || /^Cc: /i) {
			$state = waiting;
		}
	} elsif ($state == waiting) {
		if (defined $mine && /^Signed-off-by: \Q$mine\E/) {
			$seen_mine = 1;
			next;
		} elsif (/^[-A-Za-z]+-by: /i || /^Cc: /i) {
			$state = waiting;
		} else {
			add_more_bylines();
			if ($seen_mine) {
				print "Signed-off-by: $mine\n";
			}
			$state = parsing;
			$seen_mine = 0;
		}
	}
	print;
}