blob: 8feed741e80ead240b0aa1fcf3ec51db86286824 [file] [log] [blame]
Renato Golin94cc1042016-04-26 11:02:23 +01001#!/usr/bin/env perl
2
3use strict;
4use warnings;
5use Cwd;
6
7my (@data, @authors, @repos, @changed) = ((), (), (), ());
8# Syntax: git-hist [author (default: whoami)] [number of weeks (default 10 / all 0)]";
9my $author = `whoami`;
10my $weeks = 10;
11my $rootdir = getcwd;
12my $totalcommits = 0;
13if (scalar @ARGV) {
14 foreach my $arg (@ARGV) {
15 if ($arg =~ /^\d+$/) {
16 $weeks = $arg;
17 } else {
18 $author = $arg;
19 }
20 }
21}
22chomp($author);
23
24# Make sure there are repositories to use
25if (-d ".git") {
26 push @repos, ".";
27} else {
28 opendir(my $dh, ".") || die "can't open local dir: $!";
29 @repos = grep { /^[^\.]/ && -d "$_/.git" } readdir($dh);
30 closedir $dh;
31}
32die "Directory (or subs) not git repo\n" unless (scalar @repos);
33&main();
34exit;
35
36#####################################################
37sub main() {
38 # Each week
39 my $week = 0;
40 while ($week <= $weeks) {
41 # Adjust for non-zero week list
42 $week++ if ($weeks != 0 and $week == 0);
43 print "\rParsing week: $week" if $week;
44 my $commits = 0;
45 # For each repo
46 for my $repo (@repos) {
47 #print "REPO: $repo\n";
48 my $log = &get_weeklog($repo, $author, $week);
49 #print "LOG: [$log]\n";
50 my $this = &get_commits($log);
51 #print "COMMITS: $this\n";
52 if ($this and ! &find($repo, \@changed)) {
53 #print "ADDING REPO\n";
54 push @changed, $repo;
55 }
56 &get_authors($log);
57 $commits += $this;
58 }
59 push @data, $commits;
60 last if ($weeks == 0);
61 $week++;
62 }
63 print "\n\n";
64
65 # Log
66 &print_report();
67}
68
69######################
70sub print_report() {
71 return if ($weeks > 0 && scalar @data != $weeks);
72
73 # Weekly histogram
74 for my $week (0..$weeks-1) {
75 printf("%02d week [%02d]: ", $week, $data[$week]);
76 for (1..$data[$week]) {
77 print "*";
78 }
79 print "\n";
80 }
81
82 # Summary
83 print "\nTotal commits: ";
84 printf("%3d", $totalcommits);
85 print "\n Repositories: ";
86 printf("%3d ", scalar @changed);
87 &dump(\@changed);
88 print "\n Authors: ";
89 printf("%3d ", scalar @authors);
90 &dump(\@authors);
91 print "\n";
92}
93
94######################
95sub get_weeklog() {
96 my ($repo, $author, $week) = @_;
97 # Author
98 my $cmd = "git shortlog -s -n ".
99 "--author='$author' ";
100 # And week (if available)
101 if ($week) {
102 my $prev = $week-1;
103 $cmd .= "--since='$week.week' ".
104 "--until='$prev.week'";
105 }
106 # Run command
107 chdir($repo);
108 my $log = `$cmd`;
109 chdir($rootdir);
110 return $log;
111}
112
113######################
114sub get_commits() {
115 my ($log) = @_;
116 my $commits = 0;
117 foreach my $line (split(/\n/, $log)) {
118 my ($this) = ($line =~ /(\d+)/);
119 $commits += $this;
120 }
121 $totalcommits += $commits;
122 return $commits;
123}
124
125######################
126sub get_authors() {
127 my ($log) = @_;
128 foreach my $line (split(/\n/, $log)) {
129 my ($author) = ($line =~ /\d+\s+(\w.*)/);
130 if (!&find($author, \@authors)) {
131 push @authors, $author;
132 }
133 }
134}
135
136######################
137sub find() {
138 my ($elm, $array) = @_;
139 foreach my $e (@$array) {
140 return 1 if ($e eq $elm);
141 }
142 return 0;
143}
144
145######################
146sub dump() {
147 my ($array) = @_;
148 return if (!scalar @{$array});
149 my $out = "";
150 foreach my $i (@$array) {
151 $out .= "$i, ";
152 }
153 $out =~ s/, $//;
154 print $out;
155}