File Coverage

blib/lib/CPAN/Changes/Release.pm
Criterion Covered Total %
statement 73 92 79.3
branch 16 22 72.7
condition 10 19 52.6
subroutine 13 16 81.2
pod 11 11 100.0
total 123 160 76.8


line stmt bran cond sub pod time code
1             package CPAN::Changes::Release;
2 32     32   92254 use strict;
  32         71  
  32         1386  
3 32     32   180 use warnings;
  32         68  
  32         3850  
4              
5             our $VERSION = '0.500005';
6             $VERSION =~ tr/_//d;
7              
8 32     32   16041 use Moo;
  32         227666  
  32         254  
9              
10             with 'CPAN::Changes::HasEntries';
11              
12             has version => (is => 'rw');
13             has date => (is => 'rw');
14             has note => (is => 'rw');
15             has line => (is => 'ro');
16              
17             around BUILDARGS => sub {
18             my ($orig, $class, @args) = @_;
19             my $args = $class->$orig(@args);
20             if (my $changes = delete $args->{changes}) {
21             if ($args->{entries}) {
22             die "Mixing back-compat interface with new interface not allowed";
23             }
24             $args->{entries} = [];
25             for my $group (sort keys %$changes) {
26             my @entries = @{$changes->{$group}};
27              
28             if ($group eq '') {
29             push @{$args->{entries}}, @entries;
30             }
31             else {
32             my $entry = CPAN::Changes::Entry->new(
33             text => $group,
34             entries => \@entries,
35             );
36             push @{$args->{entries}}, $entry;
37             }
38             }
39             }
40             $args;
41             };
42              
43             sub serialize {
44             my ($self, %args) = @_;
45             my $indents = $args{indents} || ['', ' ', ''];
46             my $styles = $args{styles} || ['', '[]'];
47             my $width = $args{width} || 75;
48              
49             my $out = $indents->[0] . $styles->[0] . $self->version;
50             if ($self->date || $self->note) {
51             $out .= ' ' . join ' ', (grep { defined } $self->date, $self->note);
52             }
53             $out . "\n";
54             }
55              
56             around serialize => sub {
57             my ($orig, $self, %args) = @_;
58             $args{indents} ||= ['', ' ', ''];
59             $args{styles} ||= ['', '[]'];
60             $args{width} ||= 75;
61             if (my $sort = $args{group_sort}) {
62             my $entries = $self->_sorted_groups($sort);
63             $self = $self->clone(entries => $entries);
64             }
65             $self->$orig(%args);
66             };
67              
68             sub changes {
69 35     35 1 44276 my ($self, $group) = @_;
70 35 100       135 if (defined $group) {
71 15         87 return $self->get_group($group)->changes;
72             }
73             else {
74 20         90 return { map { $_ => $self->get_group($_)->changes } $self->groups };
  19         104  
75             }
76             }
77              
78             sub add_changes {
79 2     2 1 102 my $self = shift;
80 2         4 my %opts;
81 2 100 66     17 if (@_ > 1 && ref $_[0] eq 'HASH') {
82 1         2 %opts = %{ +shift };
  1         5  
83             }
84 2   100     17 $self->get_group($opts{group} || '')->add_changes(@_);
85             }
86              
87             sub set_changes {
88 0     0 1 0 my $self = shift;
89 0         0 my %opts;
90 0 0 0     0 if (@_ > 1 && ref $_[0] eq 'HASH') {
91 0         0 %opts = %{ +shift };
  0         0  
92             }
93 0   0     0 $self->get_group($opts{group} || '')->set_changes(@_);
94             }
95              
96             sub clear_changes {
97 1     1 1 51 $_[0]->entries([]);
98             }
99              
100             sub groups {
101 44     44 1 1009 my ($self, %args) = @_;
102 44   66 43   404 my $sort = $args{sort} || sub { sort @_ };
  43         411  
103 44         121 my %groups;
104 44         85 for my $entry ( @{ $self->entries } ) {
  44         1405  
105 46 100       526 if ($entry->has_entries) {
106 13         251 $groups{$entry->text}++;
107             }
108             else {
109 33         369 $groups{''}++;
110             }
111             }
112 44         184 return $sort->(keys %groups);
113             }
114              
115             sub add_group {
116 0     0 1 0 my ($self, @groups) = @_;
117 0         0 push @{ $self->entries }, map { CPAN::Changes::Entry->new(text => $_) } @groups;
  0         0  
  0         0  
118             }
119              
120             sub delete_group {
121 0     0 1 0 my ($self, @groups) = @_;
122 0         0 my @entries = @{ $self->entries };
  0         0  
123 0         0 for my $name (@groups) {
124 0         0 @entries = grep { $_->text ne $name } @entries;
  0         0  
125             }
126 0         0 $self->entries(\@entries);
127             }
128              
129             # this is nonsense, but try to emulate. if nothing has entries, then there
130             # are no "groups", so leave everything.
131             sub delete_empty_groups {
132 4     4 1 7 my ($self) = @_;
133 4         6 my @entries = grep { $_->has_entries } @{ $self->entries };
  7         41  
  4         45  
134             return
135 4 100       49 if !@entries;
136 3         35 $self->entries(\@entries);
137             }
138              
139             sub get_group {
140 38     38 1 92 my ($self, $name) = @_;
141 38         9790 require CPAN::Changes::Group;
142 38 100 66     303 if (defined $name && length $name) {
143 6         16 my ($entry) = grep { $_->text eq $name } @{ $self->entries };
  5         65  
  6         237  
144 6   66     39 $entry ||= $self->add_entry($name);
145 6         98 return CPAN::Changes::Group->new(_entry => $entry);
146             }
147             else {
148 32         690 return CPAN::Changes::Group->new(_entry => $self);
149             }
150             }
151              
152             sub attach_group {
153 2     2 1 81 my ($self, $group) = @_;
154 2         9 my $entry = $group->_maybe_entry;
155 2         23 my $text = $entry->text;
156 2         53 my $entries = $self->entries;
157 2 50       22 if ($text eq '') {
    100          
158 0         0 $self->add_entry( @{ $entry->entries } );
  0         0  
159             }
160 1         7 elsif (my ($found) = grep { $_->text eq $text } @$entries) {
161 1         4 $found->add_entry( @{ $entry->entries } );
  1         23  
162             }
163             else {
164 1         5 $self->add_entry( $entry );
165             }
166             }
167              
168             sub group_values {
169 2     2 1 13 my ($self, @groups) = @_;
170 2         9 return map { $self->get_group($_) } $self->groups(@groups);
  2         9  
171             }
172              
173             sub _sorted_groups {
174 3     3   9 my ($self, $sort_function) = @_;
175 3         6 my @groups = grep { $_->has_entries } @{ $self->entries };
  6         45  
  3         63  
176 3         26 my @bare = grep { !$_->has_entries } @{ $self->entries };
  6         50  
  3         59  
177             return \@bare
178 3 50       49 if !@groups;
179              
180 3         6 my %entries = map { $_->text => [$_] } @groups;
  6         33  
181 3 50       10 $entries{''} = \@bare
182             if @bare;
183 3         16 my @sorted = $sort_function->(keys %entries);
184 3 50       74 return [ map { @{ $entries{$_} || [] } } @sorted ];
  6         11  
  6         30  
185             }
186              
187             1;
188             __END__