summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2010-02-15 02:10:59 -0600
committerJesse Luehrs <doy@tozt.net>2010-02-15 02:10:59 -0600
commitf919b440a12f5c31fe55d3b683e90702eb0ac5b0 (patch)
tree3859c0bb26d32ba13485dc8be6c7f16b565ab9b1
parent09623a38634e62849673e38fe9e7750d9da9b493 (diff)
downloadcrawlbot-f919b440a12f5c31fe55d3b683e90702eb0ac5b0.tar.gz
crawlbot-f919b440a12f5c31fe55d3b683e90702eb0ac5b0.zip
add a plugin for commit reporting
-rw-r--r--lib/Crawl/Bot/Plugin/Commit.pm101
1 files changed, 101 insertions, 0 deletions
diff --git a/lib/Crawl/Bot/Plugin/Commit.pm b/lib/Crawl/Bot/Plugin/Commit.pm
new file mode 100644
index 0000000..7993271
--- /dev/null
+++ b/lib/Crawl/Bot/Plugin/Commit.pm
@@ -0,0 +1,101 @@
+package Crawl::Bot::Plugin::Commit;
+use Moose;
+use autodie;
+use File::pushd;
+extends 'Crawl::Bot::Plugin';
+
+has repo_uri => (
+ is => 'ro',
+ isa => 'Str',
+ default => 'git://crawl-ref.git.sourceforge.net/gitroot/crawl-ref/crawl-ref ',
+);
+
+has checkout => (
+ is => 'ro',
+ isa => 'Str',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ my $checkout = File::Spec->catdir($self->data_dir, 'crawl-ref');
+ mkdir $checkout unless -d $checkout;
+ my $dir = pushd($checkout);
+ if (-f 'HEAD') {
+ system('git fetch ' . $self->repo_uri);
+ }
+ else {
+ system('git clone --bare ' . $self->repo_uri . " $checkout");
+ }
+ $checkout;
+ },
+);
+
+has heads => (
+ traits => [qw(Hash)],
+ isa => 'HashRef[Str]',
+ lazy => 1,
+ handles => {
+ has_branch => 'exists',
+ head => 'accessor',
+ },
+ default => sub {
+ my $self = shift;
+ my $dir = pushd($self->checkout);
+ return { map { $_ => `git rev-parse $_` } $self->branches };
+ },
+);
+
+sub tick {
+ my $self = shift;
+ my $dir = pushd($self->checkout);
+ system('git fetch ' . $self->repo_uri);
+ for my $branch ($self->branches) {
+ my $old_head = $self->head($branch) || '';
+ my $head = `git rev-parse $branch`;
+ next if $old_head eq $head;
+
+ if (!$self->has_branch($branch)) {
+ $self->say_all("New branch created: $branch");
+ }
+
+ my @revs = split /\n/, `git rev-list $old_head..$head`;
+ my %commits = map { $_, $self->parse_commit($_) } @revs;
+
+ my $cherry_picks = @revs;
+ @revs = grep { $commits{$_}->{body} !~ /\(cherry picked from / } @revs;
+ $cherry_picks -= @revs;
+ $self->say_all("Cherry-picked $cherry_picks commits into $branch");
+
+ for my $rev (@revs) {
+ my $commit = $commits{$rev};
+ $self->say_all("$commit->{author} * r$rev ($commit->{nfiles} changed): $commit->{subject}");
+ }
+
+ $self->head($branch => $head);
+ }
+}
+
+sub branches {
+ my $self = shift;
+ my $dir = pushd($self->checkout);
+ return map { s/^[ \*]*//; $_ } split /\n/, `git branch`;
+}
+
+sub parse_commit {
+ my $self = shift;
+ my ($rev) = @_;
+ my $info = `git log -1 --pretty=format:%aN%x00%s%x00%b%x00 $rev`;
+ $info =~ /(.*?)\0(.*?)\0(.*?)\0(.*?)/;
+ my ($author, $subject, $body, $stat) = ($1, $2, $3, $4);
+ $stat =~ s/(\d+) files changed//;
+ return {
+ author => $author,
+ subject => $subject,
+ body => $body,
+ nfiles => $stat,
+ };
+}
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;