File Coverage

blib/lib/Module/cpmfile.pm
Criterion Covered Total %
statement 86 97 88.6
branch 13 20 65.0
condition 4 9 44.4
subroutine 16 17 94.1
pod 0 8 0.0
total 119 151 78.8


line stmt bran cond sub pod time code
1             package Module::cpmfile;
2 3     3   546971 use 5.008001;
  3         19  
3 3     3   13 use strict;
  3         4  
  3         48  
4 3     3   12 use warnings;
  3         4  
  3         96  
5              
6             our $VERSION = '0.006';
7              
8 3     3   1033 use Module::cpmfile::Prereqs;
  3         7  
  3         88  
9 3     3   15 use Module::cpmfile::Util qw(merge_version _yaml_hash);
  3         5  
  3         101  
10 3     3   1325 use YAML::PP ();
  3         138237  
  3         2451  
11              
12             sub load {
13 2     2 0 2904 my ($class, $file) = @_;
14 2         10 my ($hash) = YAML::PP->new->load_file($file);
15 2         46802 $class->new($hash);
16             }
17              
18             sub new {
19 2     2 0 11 my ($class, $hash) = @_;
20 2         14 my $prereqs = Module::cpmfile::Prereqs->new($hash->{prereqs});
21 2         4 my %feature;
22 2 50       3 for my $id (sort keys %{ $hash->{features} || +{} }) {
  2         9  
23 4         7 my $description = $hash->{features}{$id}{description};
24 4         12 my $prereqs = Module::cpmfile::Prereqs->new($hash->{features}{$id}{prereqs});
25 4         14 $feature{$id} = { description => $description, prereqs => $prereqs };
26             }
27 2         19 bless { prereqs => $prereqs, features => \%feature, _mirrors => [] }, $class;
28             }
29              
30             sub from_cpanfile {
31 1     1 0 996 my ($class, $cpanfile) = @_;
32 1         2 my %feature;
33 1         5 for my $feature ($cpanfile->features) {
34 1         556 my $id = $feature->{identifier};
35 1         2 my $description = $feature->{description};
36 1         8 my $prereqs = Module::cpmfile::Prereqs->from_cpanmeta($feature->{prereqs});
37 1         5 $feature{$id} = { description => $description, prereqs => $prereqs };
38             }
39 1         11 my $prereqs = Module::cpmfile::Prereqs->from_cpanmeta($cpanfile->prereqs);
40 1         3 for my $p ($prereqs, map { $_->{prereqs} } values %feature) {
  1         4  
41             $p->walk(undef, undef, sub {
42 6     6   9 my (undef, undef, $package, $original_options) = @_;
43 6   50     15 my $additional_options = $cpanfile->options_for_module($package) || +{};
44 6 100       183 if (%$additional_options) {
45 1         8 %$original_options = (%$original_options, %$additional_options);
46             }
47 2         11 });
48             }
49 1         4 my $mirrors = $cpanfile->mirrors;
50 1         8 bless { prereqs => $prereqs, features => \%feature, _mirrors => $mirrors }, $class;
51             }
52              
53             sub from_cpanmeta {
54 0     0 0 0 my ($class, $cpanmeta) = @_;
55 0         0 my %feature;
56 0         0 for my $id (keys %{$cpanmeta->optional_features}) {
  0         0  
57 0         0 my $f = $cpanmeta->optional_features->{$id};
58 0         0 my $description = $f->{description};
59 0         0 my $prereqs = Module::cpmfile::Prereqs->from_cpanmeta($f->{prereqs});
60 0         0 $feature{$id} = { description => $description, prereqs => $prereqs };
61             }
62 0         0 my $prereqs = Module::cpmfile::Prereqs->from_cpanmeta($cpanmeta->prereqs);
63 0         0 bless { prereqs => $prereqs, features => \%feature, _mirrors => [] }, $class;
64             }
65              
66             sub prereqs {
67 1     1 0 1 my $self = shift;
68 1         6 $self->{prereqs};
69             }
70              
71             sub features {
72 2     2 0 5512 my $self = shift;
73 2 50       3 if (%{$self->{features}}) {
  2         11  
74 2         6 return $self->{features};
75             }
76 0         0 return;
77             }
78              
79             sub _feature_prereqs {
80 3     3   4 my ($self, $ids) = @_;
81 3         4 my @prereqs;
82 3 100       3 for my $id (@{ $ids || [] }) {
  3         11  
83 1         3 my $feature = $self->{features}{$id};
84 1 50 33     5 next if !$feature || !$feature->{prereqs};
85             push @prereqs, $feature->{prereqs}
86 1         2 }
87 3         6 @prereqs;
88             }
89              
90             sub effective_requirements {
91 3     3 0 7507 my ($self, $feature_ids, $phases, $types) = @_;
92 3         4 my %req;
93 3         9 for my $prereqs ($self->{prereqs}, $self->_feature_prereqs($feature_ids)) {
94             $prereqs->walk($phases, $types, sub {
95 13     13   18 my (undef, undef, $package, $options) = @_;
96 13 100       20 if (exists $req{$package}) {
97 1   50     3 my $v1 = $req{$package}{version} || 0;
98 1   50     2 my $v2 = $options->{version} || 0;
99 1         17 my $version = merge_version $v1, $v2;
100             $req{$package} = +{
101 1 50       46 %{$req{$package}},
  1         8  
102             %$options,
103             $version ? (version => $version) : (),
104             };
105             } else {
106 12         21 $req{$package} = $options;
107             }
108 4         31 });
109             }
110 3         8 \%req;
111             }
112              
113             sub to_string {
114 1     1 0 4 my $self = shift;
115 1         3 my @out;
116 1         3 push @out, $self->prereqs->to_string;
117 1 50       4 if (my $features = $self->features) {
118 1         3 push @out, "features:";
119 1         4 for my $id (sort keys %$features) {
120 2         4 my $feature = $features->{$id};
121 2         5 push @out, " $id:";
122 2 50       23 if (my $desc = $feature->{description}) {
123 2         7 push @out, _yaml_hash({ description => $desc }, " ");
124             }
125 2 50       8 if (my $prereqs = $feature->{prereqs}) {
126 2         5 push @out, $prereqs->to_string(" ");
127             }
128             }
129             }
130 1         6 ( join "\n", @out ) . "\n";
131             }
132              
133             1;
134             __END__