File Coverage

blib/lib/CPAN/Changes/Release.pm
Criterion Covered Total %
statement 70 92 76.0
branch 16 22 72.7
condition 10 18 55.5
subroutine 12 16 75.0
pod 11 11 100.0
total 119 159 74.8


line stmt bran cond sub pod time code
1             package CPAN::Changes::Release;
2 31     31   71277 use strict;
  31         80  
  31         1013  
3 31     31   179 use warnings;
  31         104  
  31         1810  
4              
5             our $VERSION = '0.500_001';
6             $VERSION =~ tr/_//d;
7              
8 31     31   14463 use Moo;
  31         293851  
  31         188  
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 27636 my ($self, $group) = @_;
70 35 100       131 if (defined $group) {
71 15         93 return $self->get_group($group)->changes;
72             }
73             else {
74 20         85 return { map { $_ => $self->get_group($_)->changes } $self->groups };
  19         88  
75             }
76             }
77              
78             sub add_changes {
79 2     2 1 106 my $self = shift;
80 2         4 my %opts;
81 2 100 66     13 if (@_ > 1 && ref $_[0] eq 'HASH') {
82 1         3 %opts = %{ +shift };
  1         5  
83             }
84 2   100     45 $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 24 $_[0]->entries([]);
98             }
99              
100             sub groups {
101 42     42 1 918 my ($self, %args) = @_;
102 42   100 41   337 my $sort = $args{sort} || sub { sort @_ };
  41         351  
103 42         96 my %groups;
104 42         75 for my $entry ( @{ $self->entries } ) {
  42         1010  
105 44 100       581 if ($entry->has_entries) {
106 12         160 $groups{$entry->text}++;
107             }
108             else {
109 32         329 $groups{''}++;
110             }
111             }
112 42         172 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 9 my ($self) = @_;
133 4         7 my @entries = grep { $_->has_entries } @{ $self->entries };
  7         56  
  4         66  
134             return
135 4 100       39 if !@entries;
136 3         47 $self->entries(\@entries);
137             }
138              
139             sub get_group {
140 36     36 1 103 my ($self, $name) = @_;
141 36         7920 require CPAN::Changes::Group;
142 36 100 66     245 if (defined $name && length $name) {
143 5         11 my ($entry) = grep { $_->text eq $name } @{ $self->entries };
  4         46  
  5         123  
144 5   66     46 $entry ||= $self->add_entry($name);
145 5         50 return CPAN::Changes::Group->new(_entry => $entry);
146             }
147             else {
148 31         534 return CPAN::Changes::Group->new(_entry => $self);
149             }
150             }
151              
152             sub attach_group {
153 2     2 1 78 my ($self, $group) = @_;
154 2         9 my $entry = $group->_maybe_entry;
155 2         30 my $text = $entry->text;
156 2         34 my $entries = $self->entries;
157 2 50       23 if ($text eq '') {
    100          
158 0         0 $self->add_entry( @{ $entry->entries } );
  0         0  
159             }
160 1         11 elsif (my ($found) = grep { $_->text eq $text } @$entries) {
161 1         4 $found->add_entry( @{ $entry->entries } );
  1         17  
162             }
163             else {
164 1         4 $self->add_entry( $entry );
165             }
166             }
167              
168             sub group_values {
169 0     0 1 0 my ($self, @groups) = @_;
170 0         0 return map { $self->get_group($_) } $self->groups(@groups);
  0         0  
171             }
172              
173             sub _sorted_groups {
174 3     3   7 my ($self, $sort_function) = @_;
175 3         5 my @groups = grep { $_->has_entries } @{ $self->entries };
  6         50  
  3         50  
176 3         33 my @bare = grep { !$_->has_entries } @{ $self->entries };
  6         50  
  3         50  
177             return \@bare
178 3 50       38 if !@groups;
179              
180 3         8 my %entries = map { $_->text => [$_] } @groups;
  6         23  
181 3 50       13 $entries{''} = \@bare
182             if @bare;
183 3         11 my @sorted = $sort_function->(keys %entries);
184 3 50       28 return [ map { @{ $entries{$_} || [] } } @sorted ];
  6         11  
  6         22  
185             }
186              
187             1;
188             __END__