| Filename | C:/tmp64ng/perl/lib/CPAN/Meta/Prereqs.pm | 
| Statements | Executed 15 statements in 0s | 
| Calls | P | F | Exclusive Time  | 
        Inclusive Time  | 
        Subroutine | 
|---|---|---|---|---|---|
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Feature::BEGIN@1 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Feature::BEGIN@2 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Feature::BEGIN@3 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Prereqs::BEGIN@15 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Prereqs::BEGIN@16 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Prereqs::BEGIN@17 | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::__legal_phases | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::__legal_types | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::as_string_hash | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::clone | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::finalize | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::is_finalized | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::merged_requirements | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::new | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::requirements_for | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Prereqs::with_merged_prereqs | 
| Line | State ments  | 
      Time on line  | 
      Calls | Time in subs  | 
      Code | 
|---|---|---|---|---|---|
| 1 | 2 | 0s | 1 | 0s | # spent 0s within CPAN::Meta::Feature::BEGIN@1 which was called:
#    once (0s+0s) by CPAN::Meta::Feature::BEGIN@7 at line 1 # spent     0s making 1 call to CPAN::Meta::Feature::BEGIN@1  | 
| 2 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Feature::BEGIN@2 which was called:
#    once (0s+0s) by CPAN::Meta::Feature::BEGIN@7 at line 2 # spent     0s making 1 call to CPAN::Meta::Feature::BEGIN@2
# spent     0s making 1 call to strict::import  | 
| 3 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Feature::BEGIN@3 which was called:
#    once (0s+0s) by CPAN::Meta::Feature::BEGIN@7 at line 3 # spent     0s making 1 call to CPAN::Meta::Feature::BEGIN@3
# spent     0s making 1 call to warnings::import  | 
| 4 | package CPAN::Meta::Prereqs; | ||||
| 5 | # VERSION | ||||
| 6 | 1 | 0s | $CPAN::Meta::Prereqs::VERSION = '2.143240'; | ||
| 7 | #pod =head1 DESCRIPTION | ||||
| 8 | #pod | ||||
| 9 | #pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN | ||||
| 10 | #pod distribution or one of its optional features. Each set of prereqs is | ||||
| 11 | #pod organized by phase and type, as described in L<CPAN::Meta::Prereqs>. | ||||
| 12 | #pod | ||||
| 13 | #pod =cut | ||||
| 14 | |||||
| 15 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Prereqs::BEGIN@15 which was called:
#    once (0s+0s) by CPAN::Meta::Feature::BEGIN@7 at line 15 # spent     0s making 1 call to CPAN::Meta::Prereqs::BEGIN@15
# spent     0s making 1 call to Exporter::import  | 
| 16 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Prereqs::BEGIN@16 which was called:
#    once (0s+0s) by CPAN::Meta::Feature::BEGIN@7 at line 16 # spent     0s making 1 call to CPAN::Meta::Prereqs::BEGIN@16
# spent     0s making 1 call to Exporter::import  | 
| 17 | 3 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Prereqs::BEGIN@17 which was called:
#    once (0s+0s) by CPAN::Meta::Feature::BEGIN@7 at line 17 # spent     0s making 1 call to CPAN::Meta::Prereqs::BEGIN@17
# spent     0s making 1 call to version::vxs::_VERSION  | 
| 18 | |||||
| 19 | #pod =method new | ||||
| 20 | #pod | ||||
| 21 | #pod my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec ); | ||||
| 22 | #pod | ||||
| 23 | #pod This method returns a new set of Prereqs. The input should look like the | ||||
| 24 | #pod contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning | ||||
| 25 | #pod something more or less like this: | ||||
| 26 | #pod | ||||
| 27 | #pod my $prereq = CPAN::Meta::Prereqs->new({ | ||||
| 28 | #pod runtime => { | ||||
| 29 | #pod requires => { | ||||
| 30 | #pod 'Some::Module' => '1.234', | ||||
| 31 | #pod ..., | ||||
| 32 | #pod }, | ||||
| 33 | #pod ..., | ||||
| 34 | #pod }, | ||||
| 35 | #pod ..., | ||||
| 36 | #pod }); | ||||
| 37 | #pod | ||||
| 38 | #pod You can also construct an empty set of prereqs with: | ||||
| 39 | #pod | ||||
| 40 | #pod my $prereqs = CPAN::Meta::Prereqs->new; | ||||
| 41 | #pod | ||||
| 42 | #pod This empty set of prereqs is useful for accumulating new prereqs before finally | ||||
| 43 | #pod dumping the whole set into a structure or string. | ||||
| 44 | #pod | ||||
| 45 | #pod =cut | ||||
| 46 | |||||
| 47 | sub __legal_phases { qw(configure build test runtime develop) } | ||||
| 48 | sub __legal_types { qw(requires recommends suggests conflicts) } | ||||
| 49 | |||||
| 50 | # expect a prereq spec from META.json -- rjbs, 2010-04-11 | ||||
| 51 | sub new { | ||||
| 52 | my ($class, $prereq_spec) = @_; | ||||
| 53 | $prereq_spec ||= {}; | ||||
| 54 | |||||
| 55 | my %is_legal_phase = map {; $_ => 1 } $class->__legal_phases; | ||||
| 56 | my %is_legal_type = map {; $_ => 1 } $class->__legal_types; | ||||
| 57 | |||||
| 58 | my %guts; | ||||
| 59 | PHASE: for my $phase (keys %$prereq_spec) { | ||||
| 60 | next PHASE unless $phase =~ /\Ax_/i or $is_legal_phase{$phase}; | ||||
| 61 | |||||
| 62 | my $phase_spec = $prereq_spec->{ $phase }; | ||||
| 63 | next PHASE unless keys %$phase_spec; | ||||
| 64 | |||||
| 65 | TYPE: for my $type (keys %$phase_spec) { | ||||
| 66 | next TYPE unless $type =~ /\Ax_/i or $is_legal_type{$type}; | ||||
| 67 | |||||
| 68 | my $spec = $phase_spec->{ $type }; | ||||
| 69 | |||||
| 70 | next TYPE unless keys %$spec; | ||||
| 71 | |||||
| 72 | $guts{prereqs}{$phase}{$type} = CPAN::Meta::Requirements->from_string_hash( | ||||
| 73 | $spec | ||||
| 74 | ); | ||||
| 75 | } | ||||
| 76 | } | ||||
| 77 | |||||
| 78 | return bless \%guts => $class; | ||||
| 79 | } | ||||
| 80 | |||||
| 81 | #pod =method requirements_for | ||||
| 82 | #pod | ||||
| 83 | #pod my $requirements = $prereqs->requirements_for( $phase, $type ); | ||||
| 84 | #pod | ||||
| 85 | #pod This method returns a L<CPAN::Meta::Requirements> object for the given | ||||
| 86 | #pod phase/type combination. If no prerequisites are registered for that | ||||
| 87 | #pod combination, a new CPAN::Meta::Requirements object will be returned, and it may | ||||
| 88 | #pod be added to as needed. | ||||
| 89 | #pod | ||||
| 90 | #pod If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will | ||||
| 91 | #pod be raised. | ||||
| 92 | #pod | ||||
| 93 | #pod =cut | ||||
| 94 | |||||
| 95 | sub requirements_for { | ||||
| 96 | my ($self, $phase, $type) = @_; | ||||
| 97 | |||||
| 98 | confess "requirements_for called without phase" unless defined $phase; | ||||
| 99 | confess "requirements_for called without type" unless defined $type; | ||||
| 100 | |||||
| 101 | unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) { | ||||
| 102 | confess "requested requirements for unknown phase: $phase"; | ||||
| 103 | } | ||||
| 104 | |||||
| 105 | unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) { | ||||
| 106 | confess "requested requirements for unknown type: $type"; | ||||
| 107 | } | ||||
| 108 | |||||
| 109 | my $req = ($self->{prereqs}{$phase}{$type} ||= CPAN::Meta::Requirements->new); | ||||
| 110 | |||||
| 111 | $req->finalize if $self->is_finalized; | ||||
| 112 | |||||
| 113 | return $req; | ||||
| 114 | } | ||||
| 115 | |||||
| 116 | #pod =method with_merged_prereqs | ||||
| 117 | #pod | ||||
| 118 | #pod my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs ); | ||||
| 119 | #pod | ||||
| 120 | #pod my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs ); | ||||
| 121 | #pod | ||||
| 122 | #pod This method returns a new CPAN::Meta::Prereqs objects in which all the | ||||
| 123 | #pod other prerequisites given are merged into the current set. This is primarily | ||||
| 124 | #pod provided for combining a distribution's core prereqs with the prereqs of one of | ||||
| 125 | #pod its optional features. | ||||
| 126 | #pod | ||||
| 127 | #pod The new prereqs object has no ties to the originals, and altering it further | ||||
| 128 | #pod will not alter them. | ||||
| 129 | #pod | ||||
| 130 | #pod =cut | ||||
| 131 | |||||
| 132 | sub with_merged_prereqs { | ||||
| 133 | my ($self, $other) = @_; | ||||
| 134 | |||||
| 135 | my @other = blessed($other) ? $other : @$other; | ||||
| 136 | |||||
| 137 | my @prereq_objs = ($self, @other); | ||||
| 138 | |||||
| 139 | my %new_arg; | ||||
| 140 | |||||
| 141 | for my $phase ($self->__legal_phases) { | ||||
| 142 | for my $type ($self->__legal_types) { | ||||
| 143 | my $req = CPAN::Meta::Requirements->new; | ||||
| 144 | |||||
| 145 | for my $prereq (@prereq_objs) { | ||||
| 146 | my $this_req = $prereq->requirements_for($phase, $type); | ||||
| 147 | next unless $this_req->required_modules; | ||||
| 148 | |||||
| 149 | $req->add_requirements($this_req); | ||||
| 150 | } | ||||
| 151 | |||||
| 152 | next unless $req->required_modules; | ||||
| 153 | |||||
| 154 | $new_arg{ $phase }{ $type } = $req->as_string_hash; | ||||
| 155 | } | ||||
| 156 | } | ||||
| 157 | |||||
| 158 | return (ref $self)->new(\%new_arg); | ||||
| 159 | } | ||||
| 160 | |||||
| 161 | #pod =method merged_requirements | ||||
| 162 | #pod | ||||
| 163 | #pod my $new_reqs = $prereqs->merged_requirements( \@phases, \@types ); | ||||
| 164 | #pod my $new_reqs = $prereqs->merged_requirements( \@phases ); | ||||
| 165 | #pod my $new_reqs = $preerqs->merged_requirements(); | ||||
| 166 | #pod | ||||
| 167 | #pod This method joins together all requirements across a number of phases | ||||
| 168 | #pod and types into a new L<CPAN::Meta::Requirements> object. If arguments | ||||
| 169 | #pod are omitted, it defaults to "runtime", "build" and "test" for phases | ||||
| 170 | #pod and "requires" and "recommends" for types. | ||||
| 171 | #pod | ||||
| 172 | #pod =cut | ||||
| 173 | |||||
| 174 | sub merged_requirements { | ||||
| 175 | my ($self, $phases, $types) = @_; | ||||
| 176 | $phases = [qw/runtime build test/] unless defined $phases; | ||||
| 177 | $types = [qw/requires recommends/] unless defined $types; | ||||
| 178 | |||||
| 179 | confess "merged_requirements phases argument must be an arrayref" | ||||
| 180 | unless ref $phases eq 'ARRAY'; | ||||
| 181 | confess "merged_requirements types argument must be an arrayref" | ||||
| 182 | unless ref $types eq 'ARRAY'; | ||||
| 183 | |||||
| 184 | my $req = CPAN::Meta::Requirements->new; | ||||
| 185 | |||||
| 186 | for my $phase ( @$phases ) { | ||||
| 187 | unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) { | ||||
| 188 | confess "requested requirements for unknown phase: $phase"; | ||||
| 189 | } | ||||
| 190 | for my $type ( @$types ) { | ||||
| 191 | unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) { | ||||
| 192 | confess "requested requirements for unknown type: $type"; | ||||
| 193 | } | ||||
| 194 | $req->add_requirements( $self->requirements_for($phase, $type) ); | ||||
| 195 | } | ||||
| 196 | } | ||||
| 197 | |||||
| 198 | $req->finalize if $self->is_finalized; | ||||
| 199 | |||||
| 200 | return $req; | ||||
| 201 | } | ||||
| 202 | |||||
| 203 | |||||
| 204 | #pod =method as_string_hash | ||||
| 205 | #pod | ||||
| 206 | #pod This method returns a hashref containing structures suitable for dumping into a | ||||
| 207 | #pod distmeta data structure. It is made up of hashes and strings, only; there will | ||||
| 208 | #pod be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it. | ||||
| 209 | #pod | ||||
| 210 | #pod =cut | ||||
| 211 | |||||
| 212 | sub as_string_hash { | ||||
| 213 | my ($self) = @_; | ||||
| 214 | |||||
| 215 | my %hash; | ||||
| 216 | |||||
| 217 | for my $phase ($self->__legal_phases) { | ||||
| 218 | for my $type ($self->__legal_types) { | ||||
| 219 | my $req = $self->requirements_for($phase, $type); | ||||
| 220 | next unless $req->required_modules; | ||||
| 221 | |||||
| 222 | $hash{ $phase }{ $type } = $req->as_string_hash; | ||||
| 223 | } | ||||
| 224 | } | ||||
| 225 | |||||
| 226 | return \%hash; | ||||
| 227 | } | ||||
| 228 | |||||
| 229 | #pod =method is_finalized | ||||
| 230 | #pod | ||||
| 231 | #pod This method returns true if the set of prereqs has been marked "finalized," and | ||||
| 232 | #pod cannot be altered. | ||||
| 233 | #pod | ||||
| 234 | #pod =cut | ||||
| 235 | |||||
| 236 | sub is_finalized { $_[0]{finalized} } | ||||
| 237 | |||||
| 238 | #pod =method finalize | ||||
| 239 | #pod | ||||
| 240 | #pod Calling C<finalize> on a Prereqs object will close it for further modification. | ||||
| 241 | #pod Attempting to make any changes that would actually alter the prereqs will | ||||
| 242 | #pod result in an exception being thrown. | ||||
| 243 | #pod | ||||
| 244 | #pod =cut | ||||
| 245 | |||||
| 246 | sub finalize { | ||||
| 247 | my ($self) = @_; | ||||
| 248 | |||||
| 249 | $self->{finalized} = 1; | ||||
| 250 | |||||
| 251 | for my $phase (keys %{ $self->{prereqs} }) { | ||||
| 252 | $_->finalize for values %{ $self->{prereqs}{$phase} }; | ||||
| 253 | } | ||||
| 254 | } | ||||
| 255 | |||||
| 256 | #pod =method clone | ||||
| 257 | #pod | ||||
| 258 | #pod my $cloned_prereqs = $prereqs->clone; | ||||
| 259 | #pod | ||||
| 260 | #pod This method returns a Prereqs object that is identical to the original object, | ||||
| 261 | #pod but can be altered without affecting the original object. Finalization does | ||||
| 262 | #pod not survive cloning, meaning that you may clone a finalized set of prereqs and | ||||
| 263 | #pod then modify the clone. | ||||
| 264 | #pod | ||||
| 265 | #pod =cut | ||||
| 266 | |||||
| 267 | sub clone { | ||||
| 268 | my ($self) = @_; | ||||
| 269 | |||||
| 270 | my $clone = (ref $self)->new( $self->as_string_hash ); | ||||
| 271 | } | ||||
| 272 | |||||
| 273 | 1 | 0s | 1; | ||
| 274 | |||||
| 275 | # ABSTRACT: a set of distribution prerequisites by phase and type | ||||
| 276 | |||||
| 277 | __END__ |