File Coverage

blib/lib/Module/cpmfile.pm
Criterion Covered Total %
statement 86 87 98.8
branch 13 20 65.0
condition 4 9 44.4
subroutine 16 16 100.0
pod 0 7 0.0
total 119 139 85.6


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