Line # Revision Author
1 49 dpavlin #!/usr/bin/perl -w
2
3 # Produce nice statistics from SubVersion repository
4
5 use strict;
6 use Regex::PreSuf;
7 use XML::Simple;
8
9 # directories to track statistic for
10 my @track = qw(
11 trunk
12 branches/hidra
13 branches/fsb
14 branches/tehnika
15 branches/humanistika
16 branches/ffzg
17 branches/unesco
18 branches/lezbib
19 branches/cpi
20 branches/drustvene
21 branches/biomed
22 trunk2
23 );
24
25 my @ignore = qw(
26 branches/biomed/openisis
27 branches/cpi/openisis
28 branches/drustvene/openisis
29 branches/ffzg/openisis
30 branches/fsb/openisis
31 branches/hidra/openisis
32 branches/humanistika/openisis
33 branches/lezbib/openisis
34 branches/tehnika/openisis
35 branches/unesco/openisis
36 openisis/
37 trunk2/openisis
38 trunk/openisis
39 );
40
41 my $from_rev = 1;
42 my $to_rev = 'HEAD';
43
44 my $track_re = presuf(@track);
45 my $ignore_re = presuf(@ignore);
46
47 my %add;
48 my %del;
49 my %lin;
50
51 # print headline
52
53 print STDERR "reading log\n";
54
55 open(LOG, "svn log -v --xml -r $from_rev:$to_rev |") || die "svn log: $!";
56 my $log;
57 while(<LOG>) {
58 $log .= $_;
59 }
60 close(LOG);
61
62 my $fmt = "\n" . "-" x 79 . "\nr%5s| %8s | %s\n\n%s\n";
63
64
65
66
67 my $xml = XMLin($log, ForceArray => [ 'logentry', 'path' ]);
68 foreach my $e (@{$xml->{'logentry'}}) {
69 my $rev = $e->{'revision'};
70 my $date = $e->{'date'};
71 $date =~ s/T/ /;
72 $date =~ s/\..*$//;
73 $date =~ s/(\d\d\d\d)-(\d\d)-(\d\d)/$2\/$3\/$1/ || die "can't parse date: $date";
74
75 print "$rev,$date,";
76
77 printf STDERR ($fmt, $e->{'revision'}, $e->{'author'}, $e->{'date'}, $e->{'msg'});
78 foreach my $p (@{$e->{'paths'}->{'path'}}) {
79 my ($action,$path) = ($p->{'action'},$p->{'content'});
80
81 print STDERR "$action: $path\n";
82 }
83
84 # cound added/deleted lines for this revision
85
86 open(DIFF, "svn diff -r".($rev-1).":$rev |") || die "svn diff: $!";
87
88 my ($add,$del) = (0,0);
89
90 my $skip = 1;
91 my $path;
92
93 while(<DIFF>) {
94 chomp;
95 if (/^Index:\s+(($track_re).*)$/) {
96 next if (/^Index:\s+$ignore_re/);
97 $path = $2;
98 }
99 next if (! $path);
100 next if ($path && $skip && !/^@@/);
101 $skip = 0;
102 if (/^(\+|-|\s)/) {
103 if ("$1" eq "+") {
104 $add++;
105 } elsif ("$1" eq "-") {
106 $del--;
107 }
108 } elsif (/^$/) {
109 $add{$path} += $add;
110 $del{$path} += $del;
111 $lin{$path} += $add + $del;
112
113 undef $path;
114 ($add,$del,$skip) = (0,0,1);
115 }
116 }
117 close(DIFF);
118
119 foreach my $path (@track) {
120 print
121 '"',$path,'"',
122 ",",
123 $lin{$path} || 0,
124 ",",
125 $add{$path} || 0,
126 ",",
127 $del{$path} || 0,
128 ",";
129 $add{$path} = 0;
130 $del{$path} = 0;
131 }
132 my $msg = $e->{'msg'};
133 $msg =~ s/\s+/ /gs;
134 $msg =~ s/"/\\"/g;
135 print "\"$msg\"\n";
136 }