summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGianni Ceccarelli <gianni.ceccarelli@net-a-porter.com>2013-03-19 17:02:31 +0000
committerGianni Ceccarelli <gianni.ceccarelli@net-a-porter.com>2013-03-19 17:02:31 +0000
commit4ee128f76553f3efec44f55a2c5d7a0c4cb965c5 (patch)
tree191a36039bcb10f2861c2135356390a1692a29db
parenthandle missing changelogs in prev release (diff)
downloadmetacpan-diff-feed-4ee128f76553f3efec44f55a2c5d7a0c4cb965c5.tar.gz
metacpan-diff-feed-4ee128f76553f3efec44f55a2c5d7a0c4cb965c5.tar.bz2
metacpan-diff-feed-4ee128f76553f3efec44f55a2c5d7a0c4cb965c5.zip
factored code, better reporting when no diff
-rw-r--r--meta.pl210
1 files changed, 127 insertions, 83 deletions
diff --git a/meta.pl b/meta.pl
index b039c3f..26eefc1 100644
--- a/meta.pl
+++ b/meta.pl
@@ -1,6 +1,7 @@
#!/usr/bin/env perl
use strict;
use warnings;
+use 5.014;
use MetaCPAN::API;
use Text::Diff;
use XML::Feed;
@@ -10,35 +11,68 @@ use HTML::Escape 'escape_html';
my $api = MetaCPAN::API->new();
-sub get_recent_releases {
- my $now = DateTime->now;
- my $yesterday = $now->clone->subtract(hours=>3);
- my $recent = $api->post(
+package Release {
+use Moose;
+has [qw(distribution name author date abstract)] => (
+ is => 'ro',
+);
+
+around BUILDARGS => sub {
+ my ($orig,$class,$args) = @_;
+ if ($args->{fields}) {
+ $args = $args->{fields};
+ }
+ return $class->$orig($args);
+};
+
+sub get_file {
+ my ($self,$path) = @_;
+
+ my $file_response = $api->ua->get(
+ join '/',$api->base_url,'source',
+ $self->author,$self->name,$path
+ );
+ return unless $file_response->{success};
+ return $file_response->{content};
+}
+
+sub get_previous {
+ my ($self) = @_;
+
+ my $prev_release = $api->post(
'release/_search',
{
- size => 500,
- from => 0,
+ size => 1,
+ from => 0,
query => {
- range => { date => {
- from => $yesterday->iso8601,
- include_lower => 1,
- } },
+ filtered => {
+ query => {
+ range => { date => {
+ to => $self->date,
+ include_upper => 0,
+ } },
+ },
+ filter => {
+ and => [ {
+ term => {
+ 'release.distribution' => $self->distribution,
+ },
+ } ]
+ }
+ }
},
- sort => [ { 'date' => { order => "desc" } } ],
- fields => [qw(distribution name date author abstract)],
+ sort => [ { date => 'desc' } ],
+ fields => [qw(name author)],
},
);
- $recent=$recent->{hits}{hits};
- return $recent;
+ ($prev_release)=@{$prev_release->{hits}{hits}};
+ return unless $prev_release;
+ return ref($self)->new($prev_release);
}
-sub get_changelog_diff {
- my ($release) = @_;
+sub search_files {
+ my ($self,@criteria) = @_;
- my $dist_name = $release->{distribution};
- my $release_name = $release->{name};
- my $release_author = $release->{author};
- my $release_date = $release->{date};
my $files = $api->post(
'file/_search',
{
@@ -48,15 +82,8 @@ sub get_changelog_diff {
query => { match_all => {} },
filter => {
and => [
- { term => { level => 0 } },
- { term => { release => $release_name } },
- {
- or => [
- { prefix => { name => 'Change' } },
- { prefix => { name => 'change' } },
- { prefix => { name => 'CHANGE' } },
- ],
- },
+ { term => { release => $self->name } },
+ @criteria,
],
},
},
@@ -64,62 +91,73 @@ sub get_changelog_diff {
fields => [qw(name)],
}
);
+ return map { $_->{fields}{name} } @{$files->{hits}{hits}//[]};
+}
+
+sub get_changelog_name {
+ my ($self) = @_;
+ my @potential_changelogs = $self->search_files(
+ { term => { level => 0 } },
+ {
+ or => [
+ { prefix => { name => 'Change' } },
+ { prefix => { name => 'change' } },
+ { prefix => { name => 'CHANGE' } },
+ ],
+ },
+ );
my ($changelog_name) = grep {
/^change(s|log)$/i
- } map { $_->{fields}{name} } @{$files->{hits}{hits}};
-
- return 'no changelog file' unless $changelog_name;
+ } @potential_changelogs;
+ return $changelog_name;
+}
+};
- my $this_changelog = $api->ua->get(
- join '/',$api->base_url,'source',
- $release_author,$release_name,$changelog_name
- )->{content};
- my $prev_release = $api->post(
+sub get_recent_releases {
+ my $now = DateTime->now;
+ my $yesterday = $now->clone->subtract(hours=>3);
+ my $recent = $api->post(
'release/_search',
{
- size => 1,
- from => 0,
+ size => 500,
+ from => 0,
query => {
- filtered => {
- query => {
- range => { date => {
- to => $release_date,
- include_upper => 0,
- } },
- },
- filter => {
- and => [ {
- term => {
- 'release.distribution' => $dist_name,
- },
- } ]
- }
- }
+ range => { date => {
+ from => $yesterday->iso8601,
+ include_lower => 1,
+ } },
},
- sort => [ { date => 'desc' } ],
- fields => [qw(name author)],
+ sort => [ { 'date' => { order => "desc" } } ],
+ fields => [qw(distribution name date author abstract)],
},
);
- ($prev_release)=@{$prev_release->{hits}{hits}};
+ return map { Release->new($_) } @{$recent->{hits}{hits}//[]};
+}
+
+sub get_changelog_diff {
+ my ($release) = @_;
- return $this_changelog if !$prev_release;
+ my $changelog_name = $release->get_changelog_name;
- my $prev_release_name = $prev_release->{fields}{name};
- my $prev_release_author = $prev_release->{fields}{author};
+ return {error=>'no changelog file'} unless $changelog_name;
- my $prev_changelog = $api->ua->get(
- join '/',$api->base_url,'source',
- $prev_release_author,$prev_release_name,$changelog_name
- );
+ my $this_changelog = $release->get_file($changelog_name);
- return $this_changelog unless $prev_changelog->{success};
- $prev_changelog=$prev_changelog->{content};
+ my $prev_release = $release->get_previous;
+
+ return {diff=>$this_changelog} if !$prev_release;
+
+ my $prev_changelog = $prev_release->get_file($changelog_name);
+
+ return {diff=>$this_changelog} unless $prev_changelog;
my $diff = diff \$prev_changelog,\$this_changelog;
- return $diff;
+ return {diff=>$diff} if $diff;
+
+ return {error=>'changelog not modified'};
}
sub build_feed {
@@ -129,32 +167,38 @@ sub build_feed {
return $feed;
}
sub build_entry {
- my ($release,$diff) = @_;
+ my ($release) = @_;
my $e = XML::Feed::Entry->new('RSS');
- $e->title( $release->{name} );
+ $e->title( $release->name );
$e->link(
join( '/',
'http://metacpan.org', 'release',
- $release->{author}, $release->{name} )
+ $release->author, $release->name )
);
- $e->author( $release->{author} );
- $e->issued( DateTime::Format::ISO8601->parse_datetime( $release->{date} ) );
- $e->content( sprintf '<p>%s</p><pre>%s</pre>',
- escape_html($release->{abstract}),
- escape_html($diff//'') );
+ $e->author( $release->author );
+ $e->issued( DateTime::Format::ISO8601->parse_datetime( $release->date ) );
+ my $diff = get_changelog_diff($release);
+
+ my $content = sprintf '<p>%s</p>',
+ escape_html($release->abstract);
+ if ($diff->{diff}) {
+ $content .= sprintf '<pre>%s</pre>',
+ escape_html($diff->{diff});
+ }
+ else {
+ $content .= sprintf '<p>%s</p>',
+ escape_html($diff->{error});
+ }
+ $e->content($content);
+
return $e;
}
-my $recent = get_recent_releases();
my $feed = build_feed();
-
-for my $rel (@{$recent}) {
- my $release = $rel->{fields};
-
- my $diff = get_changelog_diff($release);
-
- $feed->add_entry(build_entry($release,$diff));
+my @recent = get_recent_releases();
+for my $release (@recent) {
+ $feed->add_entry(build_entry($release));
}
print $feed->as_xml;