1*b8851fccSafresh1use 5.006; # keep at v5.6 for CPAN.pm
291f110e0Safresh1use strict;
391f110e0Safresh1use warnings;
491f110e0Safresh1package CPAN::Meta::Requirements;
591f110e0Safresh1# ABSTRACT: a set of version requirements for a CPAN dist
691f110e0Safresh1
7*b8851fccSafresh1our $VERSION = '2.140';
8*b8851fccSafresh1
9*b8851fccSafresh1#pod =head1 SYNOPSIS
10*b8851fccSafresh1#pod
11*b8851fccSafresh1#pod   use CPAN::Meta::Requirements;
12*b8851fccSafresh1#pod
13*b8851fccSafresh1#pod   my $build_requires = CPAN::Meta::Requirements->new;
14*b8851fccSafresh1#pod
15*b8851fccSafresh1#pod   $build_requires->add_minimum('Library::Foo' => 1.208);
16*b8851fccSafresh1#pod
17*b8851fccSafresh1#pod   $build_requires->add_minimum('Library::Foo' => 2.602);
18*b8851fccSafresh1#pod
19*b8851fccSafresh1#pod   $build_requires->add_minimum('Module::Bar'  => 'v1.2.3');
20*b8851fccSafresh1#pod
21*b8851fccSafresh1#pod   $METAyml->{build_requires} = $build_requires->as_string_hash;
22*b8851fccSafresh1#pod
23*b8851fccSafresh1#pod =head1 DESCRIPTION
24*b8851fccSafresh1#pod
25*b8851fccSafresh1#pod A CPAN::Meta::Requirements object models a set of version constraints like
26*b8851fccSafresh1#pod those specified in the F<META.yml> or F<META.json> files in CPAN distributions,
27*b8851fccSafresh1#pod and as defined by L<CPAN::Meta::Spec>;
28*b8851fccSafresh1#pod It can be built up by adding more and more constraints, and it will reduce them
29*b8851fccSafresh1#pod to the simplest representation.
30*b8851fccSafresh1#pod
31*b8851fccSafresh1#pod Logically impossible constraints will be identified immediately by thrown
32*b8851fccSafresh1#pod exceptions.
33*b8851fccSafresh1#pod
34*b8851fccSafresh1#pod =cut
3591f110e0Safresh1
3691f110e0Safresh1use Carp ();
3791f110e0Safresh1
38*b8851fccSafresh1# To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls
39*b8851fccSafresh1# before 5.10, we fall back to the EUMM bundled compatibility version module if
40*b8851fccSafresh1# that's the only thing available.  This shouldn't ever happen in a normal CPAN
41*b8851fccSafresh1# install of CPAN::Meta::Requirements, as version.pm will be picked up from
42*b8851fccSafresh1# prereqs and be available at runtime.
43*b8851fccSafresh1
44*b8851fccSafresh1BEGIN {
45*b8851fccSafresh1  eval "use version ()"; ## no critic
46*b8851fccSafresh1  if ( my $err = $@ ) {
47*b8851fccSafresh1    eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic
48*b8851fccSafresh1  }
49*b8851fccSafresh1}
50*b8851fccSafresh1
51*b8851fccSafresh1# Perl 5.10.0 didn't have "is_qv" in version.pm
52*b8851fccSafresh1*_is_qv = version->can('is_qv') ? sub { $_[0]->is_qv } : sub { exists $_[0]->{qv} };
53*b8851fccSafresh1
54*b8851fccSafresh1# construct once, reuse many times
55*b8851fccSafresh1my $V0 = version->new(0);
56*b8851fccSafresh1
57*b8851fccSafresh1#pod =method new
58*b8851fccSafresh1#pod
59*b8851fccSafresh1#pod   my $req = CPAN::Meta::Requirements->new;
60*b8851fccSafresh1#pod
61*b8851fccSafresh1#pod This returns a new CPAN::Meta::Requirements object.  It takes an optional
62*b8851fccSafresh1#pod hash reference argument.  Currently, only one key is supported:
63*b8851fccSafresh1#pod
64*b8851fccSafresh1#pod =for :list
65*b8851fccSafresh1#pod * C<bad_version_hook> -- if provided, when a version cannot be parsed into
66*b8851fccSafresh1#pod   a version object, this code reference will be called with the invalid
67*b8851fccSafresh1#pod   version string as first argument, and the module name as second
68*b8851fccSafresh1#pod   argument.  It must return a valid version object.
69*b8851fccSafresh1#pod
70*b8851fccSafresh1#pod All other keys are ignored.
71*b8851fccSafresh1#pod
72*b8851fccSafresh1#pod =cut
7391f110e0Safresh1
7491f110e0Safresh1my @valid_options = qw( bad_version_hook );
7591f110e0Safresh1
7691f110e0Safresh1sub new {
7791f110e0Safresh1  my ($class, $options) = @_;
7891f110e0Safresh1  $options ||= {};
7991f110e0Safresh1  Carp::croak "Argument to $class\->new() must be a hash reference"
8091f110e0Safresh1    unless ref $options eq 'HASH';
8191f110e0Safresh1  my %self = map {; $_ => $options->{$_}} @valid_options;
8291f110e0Safresh1
8391f110e0Safresh1  return bless \%self => $class;
8491f110e0Safresh1}
8591f110e0Safresh1
86*b8851fccSafresh1# from version::vpp
87*b8851fccSafresh1sub _find_magic_vstring {
88*b8851fccSafresh1  my $value = shift;
89*b8851fccSafresh1  my $tvalue = '';
90*b8851fccSafresh1  require B;
91*b8851fccSafresh1  my $sv = B::svref_2object(\$value);
92*b8851fccSafresh1  my $magic = ref($sv) eq 'B::PVMG' ? $sv->MAGIC : undef;
93*b8851fccSafresh1  while ( $magic ) {
94*b8851fccSafresh1    if ( $magic->TYPE eq 'V' ) {
95*b8851fccSafresh1      $tvalue = $magic->PTR;
96*b8851fccSafresh1      $tvalue =~ s/^v?(.+)$/v$1/;
97*b8851fccSafresh1      last;
98*b8851fccSafresh1    }
99*b8851fccSafresh1    else {
100*b8851fccSafresh1      $magic = $magic->MOREMAGIC;
101*b8851fccSafresh1    }
102*b8851fccSafresh1  }
103*b8851fccSafresh1  return $tvalue;
104*b8851fccSafresh1}
105*b8851fccSafresh1
106*b8851fccSafresh1# safe if given an unblessed reference
107*b8851fccSafresh1sub _isa_version {
108*b8851fccSafresh1  UNIVERSAL::isa( $_[0], 'UNIVERSAL' ) && $_[0]->isa('version')
109*b8851fccSafresh1}
110*b8851fccSafresh1
11191f110e0Safresh1sub _version_object {
112*b8851fccSafresh1  my ($self, $module, $version) = @_;
11391f110e0Safresh1
114*b8851fccSafresh1  my ($vobj, $err);
11591f110e0Safresh1
116*b8851fccSafresh1  if (not defined $version or (!ref($version) && $version eq '0')) {
117*b8851fccSafresh1    return $V0;
118*b8851fccSafresh1  }
119*b8851fccSafresh1  elsif ( ref($version) eq 'version' || ( ref($version) && _isa_version($version) ) ) {
120*b8851fccSafresh1    $vobj = $version;
121*b8851fccSafresh1  }
122*b8851fccSafresh1  else {
123*b8851fccSafresh1    # hack around version::vpp not handling <3 character vstring literals
124*b8851fccSafresh1    if ( $INC{'version/vpp.pm'} || $INC{'ExtUtils/MakeMaker/version/vpp.pm'} ) {
125*b8851fccSafresh1      my $magic = _find_magic_vstring( $version );
126*b8851fccSafresh1      $version = $magic if length $magic;
127*b8851fccSafresh1    }
128*b8851fccSafresh1    # pad to 3 characters if before 5.8.1 and appears to be a v-string
129*b8851fccSafresh1    if ( $] < 5.008001 && $version !~ /\A[0-9]/ && substr($version,0,1) ne 'v' && length($version) < 3 ) {
130*b8851fccSafresh1      $version .= "\0" x (3 - length($version));
131*b8851fccSafresh1    }
13291f110e0Safresh1    eval {
133*b8851fccSafresh1      local $SIG{__WARN__} = sub { die "Invalid version: $_[0]" };
134*b8851fccSafresh1      # avoid specific segfault on some older version.pm versions
135*b8851fccSafresh1      die "Invalid version: $version" if $version eq 'version';
136*b8851fccSafresh1      $vobj = version->new($version);
13791f110e0Safresh1    };
13891f110e0Safresh1    if ( my $err = $@ ) {
13991f110e0Safresh1      my $hook = $self->{bad_version_hook};
140*b8851fccSafresh1      $vobj = eval { $hook->($version, $module) }
14191f110e0Safresh1        if ref $hook eq 'CODE';
142*b8851fccSafresh1      unless (eval { $vobj->isa("version") }) {
14391f110e0Safresh1        $err =~ s{ at .* line \d+.*$}{};
14491f110e0Safresh1        die "Can't convert '$version': $err";
14591f110e0Safresh1      }
14691f110e0Safresh1    }
147*b8851fccSafresh1  }
14891f110e0Safresh1
14991f110e0Safresh1  # ensure no leading '.'
15091f110e0Safresh1  if ( $vobj =~ m{\A\.} ) {
151*b8851fccSafresh1    $vobj = version->new("0$vobj");
15291f110e0Safresh1  }
15391f110e0Safresh1
15491f110e0Safresh1  # ensure normal v-string form
155*b8851fccSafresh1  if ( _is_qv($vobj) ) {
156*b8851fccSafresh1    $vobj = version->new($vobj->normal);
15791f110e0Safresh1  }
15891f110e0Safresh1
15991f110e0Safresh1  return $vobj;
16091f110e0Safresh1}
16191f110e0Safresh1
162*b8851fccSafresh1#pod =method add_minimum
163*b8851fccSafresh1#pod
164*b8851fccSafresh1#pod   $req->add_minimum( $module => $version );
165*b8851fccSafresh1#pod
166*b8851fccSafresh1#pod This adds a new minimum version requirement.  If the new requirement is
167*b8851fccSafresh1#pod redundant to the existing specification, this has no effect.
168*b8851fccSafresh1#pod
169*b8851fccSafresh1#pod Minimum requirements are inclusive.  C<$version> is required, along with any
170*b8851fccSafresh1#pod greater version number.
171*b8851fccSafresh1#pod
172*b8851fccSafresh1#pod This method returns the requirements object.
173*b8851fccSafresh1#pod
174*b8851fccSafresh1#pod =method add_maximum
175*b8851fccSafresh1#pod
176*b8851fccSafresh1#pod   $req->add_maximum( $module => $version );
177*b8851fccSafresh1#pod
178*b8851fccSafresh1#pod This adds a new maximum version requirement.  If the new requirement is
179*b8851fccSafresh1#pod redundant to the existing specification, this has no effect.
180*b8851fccSafresh1#pod
181*b8851fccSafresh1#pod Maximum requirements are inclusive.  No version strictly greater than the given
182*b8851fccSafresh1#pod version is allowed.
183*b8851fccSafresh1#pod
184*b8851fccSafresh1#pod This method returns the requirements object.
185*b8851fccSafresh1#pod
186*b8851fccSafresh1#pod =method add_exclusion
187*b8851fccSafresh1#pod
188*b8851fccSafresh1#pod   $req->add_exclusion( $module => $version );
189*b8851fccSafresh1#pod
190*b8851fccSafresh1#pod This adds a new excluded version.  For example, you might use these three
191*b8851fccSafresh1#pod method calls:
192*b8851fccSafresh1#pod
193*b8851fccSafresh1#pod   $req->add_minimum( $module => '1.00' );
194*b8851fccSafresh1#pod   $req->add_maximum( $module => '1.82' );
195*b8851fccSafresh1#pod
196*b8851fccSafresh1#pod   $req->add_exclusion( $module => '1.75' );
197*b8851fccSafresh1#pod
198*b8851fccSafresh1#pod Any version between 1.00 and 1.82 inclusive would be acceptable, except for
199*b8851fccSafresh1#pod 1.75.
200*b8851fccSafresh1#pod
201*b8851fccSafresh1#pod This method returns the requirements object.
202*b8851fccSafresh1#pod
203*b8851fccSafresh1#pod =method exact_version
204*b8851fccSafresh1#pod
205*b8851fccSafresh1#pod   $req->exact_version( $module => $version );
206*b8851fccSafresh1#pod
207*b8851fccSafresh1#pod This sets the version required for the given module to I<exactly> the given
208*b8851fccSafresh1#pod version.  No other version would be considered acceptable.
209*b8851fccSafresh1#pod
210*b8851fccSafresh1#pod This method returns the requirements object.
211*b8851fccSafresh1#pod
212*b8851fccSafresh1#pod =cut
21391f110e0Safresh1
21491f110e0Safresh1BEGIN {
215*b8851fccSafresh1  for my $type (qw(maximum exclusion exact_version)) {
21691f110e0Safresh1    my $method = "with_$type";
21791f110e0Safresh1    my $to_add = $type eq 'exact_version' ? $type : "add_$type";
21891f110e0Safresh1
21991f110e0Safresh1    my $code = sub {
22091f110e0Safresh1      my ($self, $name, $version) = @_;
22191f110e0Safresh1
222*b8851fccSafresh1      $version = $self->_version_object( $name, $version );
22391f110e0Safresh1
22491f110e0Safresh1      $self->__modify_entry_for($name, $method, $version);
22591f110e0Safresh1
22691f110e0Safresh1      return $self;
22791f110e0Safresh1    };
22891f110e0Safresh1
22991f110e0Safresh1    no strict 'refs';
23091f110e0Safresh1    *$to_add = $code;
23191f110e0Safresh1  }
23291f110e0Safresh1}
23391f110e0Safresh1
234*b8851fccSafresh1# add_minimum is optimized compared to generated subs above because
235*b8851fccSafresh1# it is called frequently and with "0" or equivalent input
236*b8851fccSafresh1sub add_minimum {
237*b8851fccSafresh1  my ($self, $name, $version) = @_;
238*b8851fccSafresh1
239*b8851fccSafresh1  # stringify $version so that version->new("0.00")->stringify ne "0"
240*b8851fccSafresh1  # which preserves the user's choice of "0.00" as the requirement
241*b8851fccSafresh1  if (not defined $version or "$version" eq '0') {
242*b8851fccSafresh1    return $self if $self->__entry_for($name);
243*b8851fccSafresh1    Carp::confess("can't add new requirements to finalized requirements")
244*b8851fccSafresh1      if $self->is_finalized;
245*b8851fccSafresh1
246*b8851fccSafresh1    $self->{requirements}{ $name } =
247*b8851fccSafresh1      CPAN::Meta::Requirements::_Range::Range->with_minimum($V0, $name);
248*b8851fccSafresh1  }
249*b8851fccSafresh1  else {
250*b8851fccSafresh1    $version = $self->_version_object( $name, $version );
251*b8851fccSafresh1
252*b8851fccSafresh1    $self->__modify_entry_for($name, 'with_minimum', $version);
253*b8851fccSafresh1  }
254*b8851fccSafresh1  return $self;
255*b8851fccSafresh1}
256*b8851fccSafresh1
257*b8851fccSafresh1#pod =method add_requirements
258*b8851fccSafresh1#pod
259*b8851fccSafresh1#pod   $req->add_requirements( $another_req_object );
260*b8851fccSafresh1#pod
261*b8851fccSafresh1#pod This method adds all the requirements in the given CPAN::Meta::Requirements
262*b8851fccSafresh1#pod object to the requirements object on which it was called.  If there are any
263*b8851fccSafresh1#pod conflicts, an exception is thrown.
264*b8851fccSafresh1#pod
265*b8851fccSafresh1#pod This method returns the requirements object.
266*b8851fccSafresh1#pod
267*b8851fccSafresh1#pod =cut
26891f110e0Safresh1
26991f110e0Safresh1sub add_requirements {
27091f110e0Safresh1  my ($self, $req) = @_;
27191f110e0Safresh1
27291f110e0Safresh1  for my $module ($req->required_modules) {
27391f110e0Safresh1    my $modifiers = $req->__entry_for($module)->as_modifiers;
27491f110e0Safresh1    for my $modifier (@$modifiers) {
27591f110e0Safresh1      my ($method, @args) = @$modifier;
27691f110e0Safresh1      $self->$method($module => @args);
27791f110e0Safresh1    };
27891f110e0Safresh1  }
27991f110e0Safresh1
28091f110e0Safresh1  return $self;
28191f110e0Safresh1}
28291f110e0Safresh1
283*b8851fccSafresh1#pod =method accepts_module
284*b8851fccSafresh1#pod
285*b8851fccSafresh1#pod   my $bool = $req->accepts_module($module => $version);
286*b8851fccSafresh1#pod
287*b8851fccSafresh1#pod Given an module and version, this method returns true if the version
288*b8851fccSafresh1#pod specification for the module accepts the provided version.  In other words,
289*b8851fccSafresh1#pod given:
290*b8851fccSafresh1#pod
291*b8851fccSafresh1#pod   Module => '>= 1.00, < 2.00'
292*b8851fccSafresh1#pod
293*b8851fccSafresh1#pod We will accept 1.00 and 1.75 but not 0.50 or 2.00.
294*b8851fccSafresh1#pod
295*b8851fccSafresh1#pod For modules that do not appear in the requirements, this method will return
296*b8851fccSafresh1#pod true.
297*b8851fccSafresh1#pod
298*b8851fccSafresh1#pod =cut
29991f110e0Safresh1
30091f110e0Safresh1sub accepts_module {
30191f110e0Safresh1  my ($self, $module, $version) = @_;
30291f110e0Safresh1
303*b8851fccSafresh1  $version = $self->_version_object( $module, $version );
30491f110e0Safresh1
30591f110e0Safresh1  return 1 unless my $range = $self->__entry_for($module);
30691f110e0Safresh1  return $range->_accepts($version);
30791f110e0Safresh1}
30891f110e0Safresh1
309*b8851fccSafresh1#pod =method clear_requirement
310*b8851fccSafresh1#pod
311*b8851fccSafresh1#pod   $req->clear_requirement( $module );
312*b8851fccSafresh1#pod
313*b8851fccSafresh1#pod This removes the requirement for a given module from the object.
314*b8851fccSafresh1#pod
315*b8851fccSafresh1#pod This method returns the requirements object.
316*b8851fccSafresh1#pod
317*b8851fccSafresh1#pod =cut
31891f110e0Safresh1
31991f110e0Safresh1sub clear_requirement {
32091f110e0Safresh1  my ($self, $module) = @_;
32191f110e0Safresh1
32291f110e0Safresh1  return $self unless $self->__entry_for($module);
32391f110e0Safresh1
32491f110e0Safresh1  Carp::confess("can't clear requirements on finalized requirements")
32591f110e0Safresh1    if $self->is_finalized;
32691f110e0Safresh1
32791f110e0Safresh1  delete $self->{requirements}{ $module };
32891f110e0Safresh1
32991f110e0Safresh1  return $self;
33091f110e0Safresh1}
33191f110e0Safresh1
332*b8851fccSafresh1#pod =method requirements_for_module
333*b8851fccSafresh1#pod
334*b8851fccSafresh1#pod   $req->requirements_for_module( $module );
335*b8851fccSafresh1#pod
336*b8851fccSafresh1#pod This returns a string containing the version requirements for a given module in
337*b8851fccSafresh1#pod the format described in L<CPAN::Meta::Spec> or undef if the given module has no
338*b8851fccSafresh1#pod requirements. This should only be used for informational purposes such as error
339*b8851fccSafresh1#pod messages and should not be interpreted or used for comparison (see
340*b8851fccSafresh1#pod L</accepts_module> instead).
341*b8851fccSafresh1#pod
342*b8851fccSafresh1#pod =cut
34391f110e0Safresh1
34491f110e0Safresh1sub requirements_for_module {
34591f110e0Safresh1  my ($self, $module) = @_;
34691f110e0Safresh1  my $entry = $self->__entry_for($module);
34791f110e0Safresh1  return unless $entry;
34891f110e0Safresh1  return $entry->as_string;
34991f110e0Safresh1}
35091f110e0Safresh1
351*b8851fccSafresh1#pod =method structured_requirements_for_module
352*b8851fccSafresh1#pod
353*b8851fccSafresh1#pod   $req->structured_requirements_for_module( $module );
354*b8851fccSafresh1#pod
355*b8851fccSafresh1#pod This returns a data structure containing the version requirements for a given
356*b8851fccSafresh1#pod module or undef if the given module has no requirements.  This should
357*b8851fccSafresh1#pod not be used for version checks (see L</accepts_module> instead).
358*b8851fccSafresh1#pod
359*b8851fccSafresh1#pod Added in version 2.134.
360*b8851fccSafresh1#pod
361*b8851fccSafresh1#pod =cut
362*b8851fccSafresh1
363*b8851fccSafresh1sub structured_requirements_for_module {
364*b8851fccSafresh1  my ($self, $module) = @_;
365*b8851fccSafresh1  my $entry = $self->__entry_for($module);
366*b8851fccSafresh1  return unless $entry;
367*b8851fccSafresh1  return $entry->as_struct;
368*b8851fccSafresh1}
369*b8851fccSafresh1
370*b8851fccSafresh1#pod =method required_modules
371*b8851fccSafresh1#pod
372*b8851fccSafresh1#pod This method returns a list of all the modules for which requirements have been
373*b8851fccSafresh1#pod specified.
374*b8851fccSafresh1#pod
375*b8851fccSafresh1#pod =cut
37691f110e0Safresh1
37791f110e0Safresh1sub required_modules { keys %{ $_[0]{requirements} } }
37891f110e0Safresh1
379*b8851fccSafresh1#pod =method clone
380*b8851fccSafresh1#pod
381*b8851fccSafresh1#pod   $req->clone;
382*b8851fccSafresh1#pod
383*b8851fccSafresh1#pod This method returns a clone of the invocant.  The clone and the original object
384*b8851fccSafresh1#pod can then be changed independent of one another.
385*b8851fccSafresh1#pod
386*b8851fccSafresh1#pod =cut
38791f110e0Safresh1
38891f110e0Safresh1sub clone {
38991f110e0Safresh1  my ($self) = @_;
39091f110e0Safresh1  my $new = (ref $self)->new;
39191f110e0Safresh1
39291f110e0Safresh1  return $new->add_requirements($self);
39391f110e0Safresh1}
39491f110e0Safresh1
39591f110e0Safresh1sub __entry_for     { $_[0]{requirements}{ $_[1] } }
39691f110e0Safresh1
39791f110e0Safresh1sub __modify_entry_for {
39891f110e0Safresh1  my ($self, $name, $method, $version) = @_;
39991f110e0Safresh1
40091f110e0Safresh1  my $fin = $self->is_finalized;
40191f110e0Safresh1  my $old = $self->__entry_for($name);
40291f110e0Safresh1
40391f110e0Safresh1  Carp::confess("can't add new requirements to finalized requirements")
40491f110e0Safresh1    if $fin and not $old;
40591f110e0Safresh1
40691f110e0Safresh1  my $new = ($old || 'CPAN::Meta::Requirements::_Range::Range')
407*b8851fccSafresh1          ->$method($version, $name);
40891f110e0Safresh1
40991f110e0Safresh1  Carp::confess("can't modify finalized requirements")
41091f110e0Safresh1    if $fin and $old->as_string ne $new->as_string;
41191f110e0Safresh1
41291f110e0Safresh1  $self->{requirements}{ $name } = $new;
41391f110e0Safresh1}
41491f110e0Safresh1
415*b8851fccSafresh1#pod =method is_simple
416*b8851fccSafresh1#pod
417*b8851fccSafresh1#pod This method returns true if and only if all requirements are inclusive minimums
418*b8851fccSafresh1#pod -- that is, if their string expression is just the version number.
419*b8851fccSafresh1#pod
420*b8851fccSafresh1#pod =cut
42191f110e0Safresh1
42291f110e0Safresh1sub is_simple {
42391f110e0Safresh1  my ($self) = @_;
42491f110e0Safresh1  for my $module ($self->required_modules) {
42591f110e0Safresh1    # XXX: This is a complete hack, but also entirely correct.
42691f110e0Safresh1    return if $self->__entry_for($module)->as_string =~ /\s/;
42791f110e0Safresh1  }
42891f110e0Safresh1
42991f110e0Safresh1  return 1;
43091f110e0Safresh1}
43191f110e0Safresh1
432*b8851fccSafresh1#pod =method is_finalized
433*b8851fccSafresh1#pod
434*b8851fccSafresh1#pod This method returns true if the requirements have been finalized by having the
435*b8851fccSafresh1#pod C<finalize> method called on them.
436*b8851fccSafresh1#pod
437*b8851fccSafresh1#pod =cut
43891f110e0Safresh1
43991f110e0Safresh1sub is_finalized { $_[0]{finalized} }
44091f110e0Safresh1
441*b8851fccSafresh1#pod =method finalize
442*b8851fccSafresh1#pod
443*b8851fccSafresh1#pod This method marks the requirements finalized.  Subsequent attempts to change
444*b8851fccSafresh1#pod the requirements will be fatal, I<if> they would result in a change.  If they
445*b8851fccSafresh1#pod would not alter the requirements, they have no effect.
446*b8851fccSafresh1#pod
447*b8851fccSafresh1#pod If a finalized set of requirements is cloned, the cloned requirements are not
448*b8851fccSafresh1#pod also finalized.
449*b8851fccSafresh1#pod
450*b8851fccSafresh1#pod =cut
45191f110e0Safresh1
45291f110e0Safresh1sub finalize { $_[0]{finalized} = 1 }
45391f110e0Safresh1
454*b8851fccSafresh1#pod =method as_string_hash
455*b8851fccSafresh1#pod
456*b8851fccSafresh1#pod This returns a reference to a hash describing the requirements using the
457*b8851fccSafresh1#pod strings in the L<CPAN::Meta::Spec> specification.
458*b8851fccSafresh1#pod
459*b8851fccSafresh1#pod For example after the following program:
460*b8851fccSafresh1#pod
461*b8851fccSafresh1#pod   my $req = CPAN::Meta::Requirements->new;
462*b8851fccSafresh1#pod
463*b8851fccSafresh1#pod   $req->add_minimum('CPAN::Meta::Requirements' => 0.102);
464*b8851fccSafresh1#pod
465*b8851fccSafresh1#pod   $req->add_minimum('Library::Foo' => 1.208);
466*b8851fccSafresh1#pod
467*b8851fccSafresh1#pod   $req->add_maximum('Library::Foo' => 2.602);
468*b8851fccSafresh1#pod
469*b8851fccSafresh1#pod   $req->add_minimum('Module::Bar'  => 'v1.2.3');
470*b8851fccSafresh1#pod
471*b8851fccSafresh1#pod   $req->add_exclusion('Module::Bar'  => 'v1.2.8');
472*b8851fccSafresh1#pod
473*b8851fccSafresh1#pod   $req->exact_version('Xyzzy'  => '6.01');
474*b8851fccSafresh1#pod
475*b8851fccSafresh1#pod   my $hashref = $req->as_string_hash;
476*b8851fccSafresh1#pod
477*b8851fccSafresh1#pod C<$hashref> would contain:
478*b8851fccSafresh1#pod
479*b8851fccSafresh1#pod   {
480*b8851fccSafresh1#pod     'CPAN::Meta::Requirements' => '0.102',
481*b8851fccSafresh1#pod     'Library::Foo' => '>= 1.208, <= 2.206',
482*b8851fccSafresh1#pod     'Module::Bar'  => '>= v1.2.3, != v1.2.8',
483*b8851fccSafresh1#pod     'Xyzzy'        => '== 6.01',
484*b8851fccSafresh1#pod   }
485*b8851fccSafresh1#pod
486*b8851fccSafresh1#pod =cut
48791f110e0Safresh1
48891f110e0Safresh1sub as_string_hash {
48991f110e0Safresh1  my ($self) = @_;
49091f110e0Safresh1
49191f110e0Safresh1  my %hash = map {; $_ => $self->{requirements}{$_}->as_string }
49291f110e0Safresh1             $self->required_modules;
49391f110e0Safresh1
49491f110e0Safresh1  return \%hash;
49591f110e0Safresh1}
49691f110e0Safresh1
497*b8851fccSafresh1#pod =method add_string_requirement
498*b8851fccSafresh1#pod
499*b8851fccSafresh1#pod   $req->add_string_requirement('Library::Foo' => '>= 1.208, <= 2.206');
500*b8851fccSafresh1#pod   $req->add_string_requirement('Library::Foo' => v1.208);
501*b8851fccSafresh1#pod
502*b8851fccSafresh1#pod This method parses the passed in string and adds the appropriate requirement
503*b8851fccSafresh1#pod for the given module.  A version can be a Perl "v-string".  It understands
504*b8851fccSafresh1#pod version ranges as described in the L<CPAN::Meta::Spec/Version Ranges>. For
505*b8851fccSafresh1#pod example:
506*b8851fccSafresh1#pod
507*b8851fccSafresh1#pod =over 4
508*b8851fccSafresh1#pod
509*b8851fccSafresh1#pod =item 1.3
510*b8851fccSafresh1#pod
511*b8851fccSafresh1#pod =item >= 1.3
512*b8851fccSafresh1#pod
513*b8851fccSafresh1#pod =item <= 1.3
514*b8851fccSafresh1#pod
515*b8851fccSafresh1#pod =item == 1.3
516*b8851fccSafresh1#pod
517*b8851fccSafresh1#pod =item != 1.3
518*b8851fccSafresh1#pod
519*b8851fccSafresh1#pod =item > 1.3
520*b8851fccSafresh1#pod
521*b8851fccSafresh1#pod =item < 1.3
522*b8851fccSafresh1#pod
523*b8851fccSafresh1#pod =item >= 1.3, != 1.5, <= 2.0
524*b8851fccSafresh1#pod
525*b8851fccSafresh1#pod A version number without an operator is equivalent to specifying a minimum
526*b8851fccSafresh1#pod (C<E<gt>=>).  Extra whitespace is allowed.
527*b8851fccSafresh1#pod
528*b8851fccSafresh1#pod =back
529*b8851fccSafresh1#pod
530*b8851fccSafresh1#pod =cut
53191f110e0Safresh1
53291f110e0Safresh1my %methods_for_op = (
53391f110e0Safresh1  '==' => [ qw(exact_version) ],
53491f110e0Safresh1  '!=' => [ qw(add_exclusion) ],
53591f110e0Safresh1  '>=' => [ qw(add_minimum)   ],
53691f110e0Safresh1  '<=' => [ qw(add_maximum)   ],
53791f110e0Safresh1  '>'  => [ qw(add_minimum add_exclusion) ],
53891f110e0Safresh1  '<'  => [ qw(add_maximum add_exclusion) ],
53991f110e0Safresh1);
54091f110e0Safresh1
54191f110e0Safresh1sub add_string_requirement {
54291f110e0Safresh1  my ($self, $module, $req) = @_;
54391f110e0Safresh1
544*b8851fccSafresh1  unless ( defined $req && length $req ) {
545*b8851fccSafresh1    $req = 0;
546*b8851fccSafresh1    $self->_blank_carp($module);
547*b8851fccSafresh1  }
548*b8851fccSafresh1
549*b8851fccSafresh1  my $magic = _find_magic_vstring( $req );
550*b8851fccSafresh1  if (length $magic) {
551*b8851fccSafresh1    $self->add_minimum($module => $magic);
552*b8851fccSafresh1    return;
553*b8851fccSafresh1  }
55491f110e0Safresh1
55591f110e0Safresh1  my @parts = split qr{\s*,\s*}, $req;
55691f110e0Safresh1
55791f110e0Safresh1  for my $part (@parts) {
55891f110e0Safresh1    my ($op, $ver) = $part =~ m{\A\s*(==|>=|>|<=|<|!=)\s*(.*)\z};
55991f110e0Safresh1
56091f110e0Safresh1    if (! defined $op) {
56191f110e0Safresh1      $self->add_minimum($module => $part);
56291f110e0Safresh1    } else {
56391f110e0Safresh1      Carp::confess("illegal requirement string: $req")
56491f110e0Safresh1        unless my $methods = $methods_for_op{ $op };
56591f110e0Safresh1
56691f110e0Safresh1      $self->$_($module => $ver) for @$methods;
56791f110e0Safresh1    }
56891f110e0Safresh1  }
56991f110e0Safresh1}
57091f110e0Safresh1
571*b8851fccSafresh1#pod =method from_string_hash
572*b8851fccSafresh1#pod
573*b8851fccSafresh1#pod   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash );
574*b8851fccSafresh1#pod   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash, \%opts );
575*b8851fccSafresh1#pod
576*b8851fccSafresh1#pod This is an alternate constructor for a CPAN::Meta::Requirements
577*b8851fccSafresh1#pod object. It takes a hash of module names and version requirement
578*b8851fccSafresh1#pod strings and returns a new CPAN::Meta::Requirements object. As with
579*b8851fccSafresh1#pod add_string_requirement, a version can be a Perl "v-string". Optionally,
580*b8851fccSafresh1#pod you can supply a hash-reference of options, exactly as with the L</new>
581*b8851fccSafresh1#pod method.
582*b8851fccSafresh1#pod
583*b8851fccSafresh1#pod =cut
584*b8851fccSafresh1
585*b8851fccSafresh1sub _blank_carp {
586*b8851fccSafresh1  my ($self, $module) = @_;
587*b8851fccSafresh1  Carp::carp("Undefined requirement for $module treated as '0'");
588*b8851fccSafresh1}
58991f110e0Safresh1
59091f110e0Safresh1sub from_string_hash {
591*b8851fccSafresh1  my ($class, $hash, $options) = @_;
59291f110e0Safresh1
593*b8851fccSafresh1  my $self = $class->new($options);
59491f110e0Safresh1
59591f110e0Safresh1  for my $module (keys %$hash) {
59691f110e0Safresh1    my $req = $hash->{$module};
59791f110e0Safresh1    unless ( defined $req && length $req ) {
59891f110e0Safresh1      $req = 0;
599*b8851fccSafresh1      $class->_blank_carp($module);
60091f110e0Safresh1    }
60191f110e0Safresh1    $self->add_string_requirement($module, $req);
60291f110e0Safresh1  }
60391f110e0Safresh1
60491f110e0Safresh1  return $self;
60591f110e0Safresh1}
60691f110e0Safresh1
60791f110e0Safresh1##############################################################
60891f110e0Safresh1
60991f110e0Safresh1{
61091f110e0Safresh1  package
61191f110e0Safresh1    CPAN::Meta::Requirements::_Range::Exact;
61291f110e0Safresh1  sub _new     { bless { version => $_[1] } => $_[0] }
61391f110e0Safresh1
61491f110e0Safresh1  sub _accepts { return $_[0]{version} == $_[1] }
61591f110e0Safresh1
61691f110e0Safresh1  sub as_string { return "== $_[0]{version}" }
61791f110e0Safresh1
618*b8851fccSafresh1  sub as_struct { return [ [ '==', "$_[0]{version}" ] ] }
619*b8851fccSafresh1
62091f110e0Safresh1  sub as_modifiers { return [ [ exact_version => $_[0]{version} ] ] }
62191f110e0Safresh1
622*b8851fccSafresh1  sub _reject_requirements {
623*b8851fccSafresh1    my ($self, $module, $error) = @_;
624*b8851fccSafresh1    Carp::confess("illegal requirements for $module: $error")
625*b8851fccSafresh1  }
626*b8851fccSafresh1
62791f110e0Safresh1  sub _clone {
62891f110e0Safresh1    (ref $_[0])->_new( version->new( $_[0]{version} ) )
62991f110e0Safresh1  }
63091f110e0Safresh1
63191f110e0Safresh1  sub with_exact_version {
632*b8851fccSafresh1    my ($self, $version, $module) = @_;
633*b8851fccSafresh1    $module = 'module' unless defined $module;
63491f110e0Safresh1
63591f110e0Safresh1    return $self->_clone if $self->_accepts($version);
63691f110e0Safresh1
637*b8851fccSafresh1    $self->_reject_requirements(
638*b8851fccSafresh1      $module,
639*b8851fccSafresh1      "can't be exactly $version when exact requirement is already $self->{version}",
640*b8851fccSafresh1    );
64191f110e0Safresh1  }
64291f110e0Safresh1
64391f110e0Safresh1  sub with_minimum {
644*b8851fccSafresh1    my ($self, $minimum, $module) = @_;
645*b8851fccSafresh1    $module = 'module' unless defined $module;
646*b8851fccSafresh1
64791f110e0Safresh1    return $self->_clone if $self->{version} >= $minimum;
648*b8851fccSafresh1    $self->_reject_requirements(
649*b8851fccSafresh1      $module,
650*b8851fccSafresh1      "minimum $minimum exceeds exact specification $self->{version}",
651*b8851fccSafresh1    );
65291f110e0Safresh1  }
65391f110e0Safresh1
65491f110e0Safresh1  sub with_maximum {
655*b8851fccSafresh1    my ($self, $maximum, $module) = @_;
656*b8851fccSafresh1    $module = 'module' unless defined $module;
657*b8851fccSafresh1
65891f110e0Safresh1    return $self->_clone if $self->{version} <= $maximum;
659*b8851fccSafresh1    $self->_reject_requirements(
660*b8851fccSafresh1      $module,
661*b8851fccSafresh1      "maximum $maximum below exact specification $self->{version}",
662*b8851fccSafresh1    );
66391f110e0Safresh1  }
66491f110e0Safresh1
66591f110e0Safresh1  sub with_exclusion {
666*b8851fccSafresh1    my ($self, $exclusion, $module) = @_;
667*b8851fccSafresh1    $module = 'module' unless defined $module;
668*b8851fccSafresh1
66991f110e0Safresh1    return $self->_clone unless $exclusion == $self->{version};
670*b8851fccSafresh1    $self->_reject_requirements(
671*b8851fccSafresh1      $module,
672*b8851fccSafresh1      "tried to exclude $exclusion, which is already exactly specified",
673*b8851fccSafresh1    );
67491f110e0Safresh1  }
67591f110e0Safresh1}
67691f110e0Safresh1
67791f110e0Safresh1##############################################################
67891f110e0Safresh1
67991f110e0Safresh1{
68091f110e0Safresh1  package
68191f110e0Safresh1    CPAN::Meta::Requirements::_Range::Range;
68291f110e0Safresh1
68391f110e0Safresh1  sub _self { ref($_[0]) ? $_[0] : (bless { } => $_[0]) }
68491f110e0Safresh1
68591f110e0Safresh1  sub _clone {
68691f110e0Safresh1    return (bless { } => $_[0]) unless ref $_[0];
68791f110e0Safresh1
68891f110e0Safresh1    my ($s) = @_;
68991f110e0Safresh1    my %guts = (
69091f110e0Safresh1      (exists $s->{minimum} ? (minimum => version->new($s->{minimum})) : ()),
69191f110e0Safresh1      (exists $s->{maximum} ? (maximum => version->new($s->{maximum})) : ()),
69291f110e0Safresh1
69391f110e0Safresh1      (exists $s->{exclusions}
69491f110e0Safresh1        ? (exclusions => [ map { version->new($_) } @{ $s->{exclusions} } ])
69591f110e0Safresh1        : ()),
69691f110e0Safresh1    );
69791f110e0Safresh1
69891f110e0Safresh1    bless \%guts => ref($s);
69991f110e0Safresh1  }
70091f110e0Safresh1
70191f110e0Safresh1  sub as_modifiers {
70291f110e0Safresh1    my ($self) = @_;
70391f110e0Safresh1    my @mods;
70491f110e0Safresh1    push @mods, [ add_minimum => $self->{minimum} ] if exists $self->{minimum};
70591f110e0Safresh1    push @mods, [ add_maximum => $self->{maximum} ] if exists $self->{maximum};
70691f110e0Safresh1    push @mods, map {; [ add_exclusion => $_ ] } @{$self->{exclusions} || []};
70791f110e0Safresh1    return \@mods;
70891f110e0Safresh1  }
70991f110e0Safresh1
710*b8851fccSafresh1  sub as_struct {
71191f110e0Safresh1    my ($self) = @_;
71291f110e0Safresh1
71391f110e0Safresh1    return 0 if ! keys %$self;
71491f110e0Safresh1
71591f110e0Safresh1    my @exclusions = @{ $self->{exclusions} || [] };
71691f110e0Safresh1
71791f110e0Safresh1    my @parts;
71891f110e0Safresh1
719*b8851fccSafresh1    for my $tuple (
72091f110e0Safresh1      [ qw( >= > minimum ) ],
72191f110e0Safresh1      [ qw( <= < maximum ) ],
72291f110e0Safresh1    ) {
723*b8851fccSafresh1      my ($op, $e_op, $k) = @$tuple;
72491f110e0Safresh1      if (exists $self->{$k}) {
72591f110e0Safresh1        my @new_exclusions = grep { $_ != $self->{ $k } } @exclusions;
72691f110e0Safresh1        if (@new_exclusions == @exclusions) {
727*b8851fccSafresh1          push @parts, [ $op, "$self->{ $k }" ];
72891f110e0Safresh1        } else {
729*b8851fccSafresh1          push @parts, [ $e_op, "$self->{ $k }" ];
73091f110e0Safresh1          @exclusions = @new_exclusions;
73191f110e0Safresh1        }
73291f110e0Safresh1      }
73391f110e0Safresh1    }
73491f110e0Safresh1
735*b8851fccSafresh1    push @parts, map {; [ "!=", "$_" ] } @exclusions;
73691f110e0Safresh1
737*b8851fccSafresh1    return \@parts;
738*b8851fccSafresh1  }
739*b8851fccSafresh1
740*b8851fccSafresh1  sub as_string {
741*b8851fccSafresh1    my ($self) = @_;
742*b8851fccSafresh1
743*b8851fccSafresh1    my @parts = @{ $self->as_struct };
744*b8851fccSafresh1
745*b8851fccSafresh1    return $parts[0][1] if @parts == 1 and $parts[0][0] eq '>=';
746*b8851fccSafresh1
747*b8851fccSafresh1    return join q{, }, map {; join q{ }, @$_ } @parts;
748*b8851fccSafresh1  }
749*b8851fccSafresh1
750*b8851fccSafresh1  sub _reject_requirements {
751*b8851fccSafresh1    my ($self, $module, $error) = @_;
752*b8851fccSafresh1    Carp::confess("illegal requirements for $module: $error")
75391f110e0Safresh1  }
75491f110e0Safresh1
75591f110e0Safresh1  sub with_exact_version {
756*b8851fccSafresh1    my ($self, $version, $module) = @_;
757*b8851fccSafresh1    $module = 'module' unless defined $module;
75891f110e0Safresh1    $self = $self->_clone;
75991f110e0Safresh1
760*b8851fccSafresh1    unless ($self->_accepts($version)) {
761*b8851fccSafresh1      $self->_reject_requirements(
762*b8851fccSafresh1        $module,
763*b8851fccSafresh1        "exact specification $version outside of range " . $self->as_string
764*b8851fccSafresh1      );
765*b8851fccSafresh1    }
76691f110e0Safresh1
76791f110e0Safresh1    return CPAN::Meta::Requirements::_Range::Exact->_new($version);
76891f110e0Safresh1  }
76991f110e0Safresh1
77091f110e0Safresh1  sub _simplify {
771*b8851fccSafresh1    my ($self, $module) = @_;
77291f110e0Safresh1
77391f110e0Safresh1    if (defined $self->{minimum} and defined $self->{maximum}) {
77491f110e0Safresh1      if ($self->{minimum} == $self->{maximum}) {
775*b8851fccSafresh1        if (grep { $_ == $self->{minimum} } @{ $self->{exclusions} || [] }) {
776*b8851fccSafresh1          $self->_reject_requirements(
777*b8851fccSafresh1            $module,
778*b8851fccSafresh1            "minimum and maximum are both $self->{minimum}, which is excluded",
779*b8851fccSafresh1          );
780*b8851fccSafresh1        }
78191f110e0Safresh1
78291f110e0Safresh1        return CPAN::Meta::Requirements::_Range::Exact->_new($self->{minimum})
78391f110e0Safresh1      }
78491f110e0Safresh1
785*b8851fccSafresh1      if ($self->{minimum} > $self->{maximum}) {
786*b8851fccSafresh1        $self->_reject_requirements(
787*b8851fccSafresh1          $module,
788*b8851fccSafresh1          "minimum $self->{minimum} exceeds maximum $self->{maximum}",
789*b8851fccSafresh1        );
790*b8851fccSafresh1      }
79191f110e0Safresh1    }
79291f110e0Safresh1
79391f110e0Safresh1    # eliminate irrelevant exclusions
79491f110e0Safresh1    if ($self->{exclusions}) {
79591f110e0Safresh1      my %seen;
79691f110e0Safresh1      @{ $self->{exclusions} } = grep {
79791f110e0Safresh1        (! defined $self->{minimum} or $_ >= $self->{minimum})
79891f110e0Safresh1        and
79991f110e0Safresh1        (! defined $self->{maximum} or $_ <= $self->{maximum})
80091f110e0Safresh1        and
80191f110e0Safresh1        ! $seen{$_}++
80291f110e0Safresh1      } @{ $self->{exclusions} };
80391f110e0Safresh1    }
80491f110e0Safresh1
80591f110e0Safresh1    return $self;
80691f110e0Safresh1  }
80791f110e0Safresh1
80891f110e0Safresh1  sub with_minimum {
809*b8851fccSafresh1    my ($self, $minimum, $module) = @_;
810*b8851fccSafresh1    $module = 'module' unless defined $module;
81191f110e0Safresh1    $self = $self->_clone;
81291f110e0Safresh1
81391f110e0Safresh1    if (defined (my $old_min = $self->{minimum})) {
81491f110e0Safresh1      $self->{minimum} = (sort { $b cmp $a } ($minimum, $old_min))[0];
81591f110e0Safresh1    } else {
81691f110e0Safresh1      $self->{minimum} = $minimum;
81791f110e0Safresh1    }
81891f110e0Safresh1
819*b8851fccSafresh1    return $self->_simplify($module);
82091f110e0Safresh1  }
82191f110e0Safresh1
82291f110e0Safresh1  sub with_maximum {
823*b8851fccSafresh1    my ($self, $maximum, $module) = @_;
824*b8851fccSafresh1    $module = 'module' unless defined $module;
82591f110e0Safresh1    $self = $self->_clone;
82691f110e0Safresh1
82791f110e0Safresh1    if (defined (my $old_max = $self->{maximum})) {
82891f110e0Safresh1      $self->{maximum} = (sort { $a cmp $b } ($maximum, $old_max))[0];
82991f110e0Safresh1    } else {
83091f110e0Safresh1      $self->{maximum} = $maximum;
83191f110e0Safresh1    }
83291f110e0Safresh1
833*b8851fccSafresh1    return $self->_simplify($module);
83491f110e0Safresh1  }
83591f110e0Safresh1
83691f110e0Safresh1  sub with_exclusion {
837*b8851fccSafresh1    my ($self, $exclusion, $module) = @_;
838*b8851fccSafresh1    $module = 'module' unless defined $module;
83991f110e0Safresh1    $self = $self->_clone;
84091f110e0Safresh1
84191f110e0Safresh1    push @{ $self->{exclusions} ||= [] }, $exclusion;
84291f110e0Safresh1
843*b8851fccSafresh1    return $self->_simplify($module);
84491f110e0Safresh1  }
84591f110e0Safresh1
84691f110e0Safresh1  sub _accepts {
84791f110e0Safresh1    my ($self, $version) = @_;
84891f110e0Safresh1
84991f110e0Safresh1    return if defined $self->{minimum} and $version < $self->{minimum};
85091f110e0Safresh1    return if defined $self->{maximum} and $version > $self->{maximum};
85191f110e0Safresh1    return if defined $self->{exclusions}
85291f110e0Safresh1          and grep { $version == $_ } @{ $self->{exclusions} };
85391f110e0Safresh1
85491f110e0Safresh1    return 1;
85591f110e0Safresh1  }
85691f110e0Safresh1}
85791f110e0Safresh1
85891f110e0Safresh11;
85991f110e0Safresh1# vim: ts=2 sts=2 sw=2 et:
86091f110e0Safresh1
86191f110e0Safresh1__END__
8626fb12b70Safresh1
86391f110e0Safresh1=pod
86491f110e0Safresh1
865*b8851fccSafresh1=encoding UTF-8
8666fb12b70Safresh1
86791f110e0Safresh1=head1 NAME
86891f110e0Safresh1
86991f110e0Safresh1CPAN::Meta::Requirements - a set of version requirements for a CPAN dist
87091f110e0Safresh1
87191f110e0Safresh1=head1 VERSION
87291f110e0Safresh1
873*b8851fccSafresh1version 2.140
87491f110e0Safresh1
87591f110e0Safresh1=head1 SYNOPSIS
87691f110e0Safresh1
87791f110e0Safresh1  use CPAN::Meta::Requirements;
87891f110e0Safresh1
87991f110e0Safresh1  my $build_requires = CPAN::Meta::Requirements->new;
88091f110e0Safresh1
88191f110e0Safresh1  $build_requires->add_minimum('Library::Foo' => 1.208);
88291f110e0Safresh1
88391f110e0Safresh1  $build_requires->add_minimum('Library::Foo' => 2.602);
88491f110e0Safresh1
88591f110e0Safresh1  $build_requires->add_minimum('Module::Bar'  => 'v1.2.3');
88691f110e0Safresh1
88791f110e0Safresh1  $METAyml->{build_requires} = $build_requires->as_string_hash;
88891f110e0Safresh1
88991f110e0Safresh1=head1 DESCRIPTION
89091f110e0Safresh1
89191f110e0Safresh1A CPAN::Meta::Requirements object models a set of version constraints like
892*b8851fccSafresh1those specified in the F<META.yml> or F<META.json> files in CPAN distributions,
893*b8851fccSafresh1and as defined by L<CPAN::Meta::Spec>;
89491f110e0Safresh1It can be built up by adding more and more constraints, and it will reduce them
89591f110e0Safresh1to the simplest representation.
89691f110e0Safresh1
89791f110e0Safresh1Logically impossible constraints will be identified immediately by thrown
89891f110e0Safresh1exceptions.
89991f110e0Safresh1
90091f110e0Safresh1=head1 METHODS
90191f110e0Safresh1
90291f110e0Safresh1=head2 new
90391f110e0Safresh1
90491f110e0Safresh1  my $req = CPAN::Meta::Requirements->new;
90591f110e0Safresh1
90691f110e0Safresh1This returns a new CPAN::Meta::Requirements object.  It takes an optional
907*b8851fccSafresh1hash reference argument.  Currently, only one key is supported:
90891f110e0Safresh1
90991f110e0Safresh1=over 4
91091f110e0Safresh1
91191f110e0Safresh1=item *
91291f110e0Safresh1
913*b8851fccSafresh1C<bad_version_hook> -- if provided, when a version cannot be parsed into a version object, this code reference will be called with the invalid version string as first argument, and the module name as second argument.  It must return a valid version object.
91491f110e0Safresh1
91591f110e0Safresh1=back
91691f110e0Safresh1
91791f110e0Safresh1All other keys are ignored.
91891f110e0Safresh1
91991f110e0Safresh1=head2 add_minimum
92091f110e0Safresh1
92191f110e0Safresh1  $req->add_minimum( $module => $version );
92291f110e0Safresh1
92391f110e0Safresh1This adds a new minimum version requirement.  If the new requirement is
92491f110e0Safresh1redundant to the existing specification, this has no effect.
92591f110e0Safresh1
92691f110e0Safresh1Minimum requirements are inclusive.  C<$version> is required, along with any
92791f110e0Safresh1greater version number.
92891f110e0Safresh1
92991f110e0Safresh1This method returns the requirements object.
93091f110e0Safresh1
93191f110e0Safresh1=head2 add_maximum
93291f110e0Safresh1
93391f110e0Safresh1  $req->add_maximum( $module => $version );
93491f110e0Safresh1
93591f110e0Safresh1This adds a new maximum version requirement.  If the new requirement is
93691f110e0Safresh1redundant to the existing specification, this has no effect.
93791f110e0Safresh1
93891f110e0Safresh1Maximum requirements are inclusive.  No version strictly greater than the given
93991f110e0Safresh1version is allowed.
94091f110e0Safresh1
94191f110e0Safresh1This method returns the requirements object.
94291f110e0Safresh1
94391f110e0Safresh1=head2 add_exclusion
94491f110e0Safresh1
94591f110e0Safresh1  $req->add_exclusion( $module => $version );
94691f110e0Safresh1
94791f110e0Safresh1This adds a new excluded version.  For example, you might use these three
94891f110e0Safresh1method calls:
94991f110e0Safresh1
95091f110e0Safresh1  $req->add_minimum( $module => '1.00' );
95191f110e0Safresh1  $req->add_maximum( $module => '1.82' );
95291f110e0Safresh1
95391f110e0Safresh1  $req->add_exclusion( $module => '1.75' );
95491f110e0Safresh1
95591f110e0Safresh1Any version between 1.00 and 1.82 inclusive would be acceptable, except for
95691f110e0Safresh11.75.
95791f110e0Safresh1
95891f110e0Safresh1This method returns the requirements object.
95991f110e0Safresh1
96091f110e0Safresh1=head2 exact_version
96191f110e0Safresh1
96291f110e0Safresh1  $req->exact_version( $module => $version );
96391f110e0Safresh1
96491f110e0Safresh1This sets the version required for the given module to I<exactly> the given
96591f110e0Safresh1version.  No other version would be considered acceptable.
96691f110e0Safresh1
96791f110e0Safresh1This method returns the requirements object.
96891f110e0Safresh1
96991f110e0Safresh1=head2 add_requirements
97091f110e0Safresh1
97191f110e0Safresh1  $req->add_requirements( $another_req_object );
97291f110e0Safresh1
973*b8851fccSafresh1This method adds all the requirements in the given CPAN::Meta::Requirements
974*b8851fccSafresh1object to the requirements object on which it was called.  If there are any
975*b8851fccSafresh1conflicts, an exception is thrown.
97691f110e0Safresh1
97791f110e0Safresh1This method returns the requirements object.
97891f110e0Safresh1
97991f110e0Safresh1=head2 accepts_module
98091f110e0Safresh1
981*b8851fccSafresh1  my $bool = $req->accepts_module($module => $version);
98291f110e0Safresh1
98391f110e0Safresh1Given an module and version, this method returns true if the version
98491f110e0Safresh1specification for the module accepts the provided version.  In other words,
98591f110e0Safresh1given:
98691f110e0Safresh1
98791f110e0Safresh1  Module => '>= 1.00, < 2.00'
98891f110e0Safresh1
98991f110e0Safresh1We will accept 1.00 and 1.75 but not 0.50 or 2.00.
99091f110e0Safresh1
99191f110e0Safresh1For modules that do not appear in the requirements, this method will return
99291f110e0Safresh1true.
99391f110e0Safresh1
99491f110e0Safresh1=head2 clear_requirement
99591f110e0Safresh1
99691f110e0Safresh1  $req->clear_requirement( $module );
99791f110e0Safresh1
99891f110e0Safresh1This removes the requirement for a given module from the object.
99991f110e0Safresh1
100091f110e0Safresh1This method returns the requirements object.
100191f110e0Safresh1
100291f110e0Safresh1=head2 requirements_for_module
100391f110e0Safresh1
100491f110e0Safresh1  $req->requirements_for_module( $module );
100591f110e0Safresh1
100691f110e0Safresh1This returns a string containing the version requirements for a given module in
100791f110e0Safresh1the format described in L<CPAN::Meta::Spec> or undef if the given module has no
100891f110e0Safresh1requirements. This should only be used for informational purposes such as error
100991f110e0Safresh1messages and should not be interpreted or used for comparison (see
1010*b8851fccSafresh1L</accepts_module> instead).
1011*b8851fccSafresh1
1012*b8851fccSafresh1=head2 structured_requirements_for_module
1013*b8851fccSafresh1
1014*b8851fccSafresh1  $req->structured_requirements_for_module( $module );
1015*b8851fccSafresh1
1016*b8851fccSafresh1This returns a data structure containing the version requirements for a given
1017*b8851fccSafresh1module or undef if the given module has no requirements.  This should
1018*b8851fccSafresh1not be used for version checks (see L</accepts_module> instead).
1019*b8851fccSafresh1
1020*b8851fccSafresh1Added in version 2.134.
102191f110e0Safresh1
102291f110e0Safresh1=head2 required_modules
102391f110e0Safresh1
102491f110e0Safresh1This method returns a list of all the modules for which requirements have been
102591f110e0Safresh1specified.
102691f110e0Safresh1
102791f110e0Safresh1=head2 clone
102891f110e0Safresh1
102991f110e0Safresh1  $req->clone;
103091f110e0Safresh1
103191f110e0Safresh1This method returns a clone of the invocant.  The clone and the original object
103291f110e0Safresh1can then be changed independent of one another.
103391f110e0Safresh1
103491f110e0Safresh1=head2 is_simple
103591f110e0Safresh1
103691f110e0Safresh1This method returns true if and only if all requirements are inclusive minimums
103791f110e0Safresh1-- that is, if their string expression is just the version number.
103891f110e0Safresh1
103991f110e0Safresh1=head2 is_finalized
104091f110e0Safresh1
104191f110e0Safresh1This method returns true if the requirements have been finalized by having the
104291f110e0Safresh1C<finalize> method called on them.
104391f110e0Safresh1
104491f110e0Safresh1=head2 finalize
104591f110e0Safresh1
104691f110e0Safresh1This method marks the requirements finalized.  Subsequent attempts to change
104791f110e0Safresh1the requirements will be fatal, I<if> they would result in a change.  If they
104891f110e0Safresh1would not alter the requirements, they have no effect.
104991f110e0Safresh1
105091f110e0Safresh1If a finalized set of requirements is cloned, the cloned requirements are not
105191f110e0Safresh1also finalized.
105291f110e0Safresh1
105391f110e0Safresh1=head2 as_string_hash
105491f110e0Safresh1
105591f110e0Safresh1This returns a reference to a hash describing the requirements using the
1056*b8851fccSafresh1strings in the L<CPAN::Meta::Spec> specification.
105791f110e0Safresh1
105891f110e0Safresh1For example after the following program:
105991f110e0Safresh1
106091f110e0Safresh1  my $req = CPAN::Meta::Requirements->new;
106191f110e0Safresh1
106291f110e0Safresh1  $req->add_minimum('CPAN::Meta::Requirements' => 0.102);
106391f110e0Safresh1
106491f110e0Safresh1  $req->add_minimum('Library::Foo' => 1.208);
106591f110e0Safresh1
106691f110e0Safresh1  $req->add_maximum('Library::Foo' => 2.602);
106791f110e0Safresh1
106891f110e0Safresh1  $req->add_minimum('Module::Bar'  => 'v1.2.3');
106991f110e0Safresh1
107091f110e0Safresh1  $req->add_exclusion('Module::Bar'  => 'v1.2.8');
107191f110e0Safresh1
107291f110e0Safresh1  $req->exact_version('Xyzzy'  => '6.01');
107391f110e0Safresh1
107491f110e0Safresh1  my $hashref = $req->as_string_hash;
107591f110e0Safresh1
107691f110e0Safresh1C<$hashref> would contain:
107791f110e0Safresh1
107891f110e0Safresh1  {
107991f110e0Safresh1    'CPAN::Meta::Requirements' => '0.102',
108091f110e0Safresh1    'Library::Foo' => '>= 1.208, <= 2.206',
108191f110e0Safresh1    'Module::Bar'  => '>= v1.2.3, != v1.2.8',
108291f110e0Safresh1    'Xyzzy'        => '== 6.01',
108391f110e0Safresh1  }
108491f110e0Safresh1
108591f110e0Safresh1=head2 add_string_requirement
108691f110e0Safresh1
108791f110e0Safresh1  $req->add_string_requirement('Library::Foo' => '>= 1.208, <= 2.206');
1088*b8851fccSafresh1  $req->add_string_requirement('Library::Foo' => v1.208);
108991f110e0Safresh1
109091f110e0Safresh1This method parses the passed in string and adds the appropriate requirement
1091*b8851fccSafresh1for the given module.  A version can be a Perl "v-string".  It understands
1092*b8851fccSafresh1version ranges as described in the L<CPAN::Meta::Spec/Version Ranges>. For
1093*b8851fccSafresh1example:
109491f110e0Safresh1
109591f110e0Safresh1=over 4
109691f110e0Safresh1
109791f110e0Safresh1=item 1.3
109891f110e0Safresh1
109991f110e0Safresh1=item >= 1.3
110091f110e0Safresh1
110191f110e0Safresh1=item <= 1.3
110291f110e0Safresh1
110391f110e0Safresh1=item == 1.3
110491f110e0Safresh1
110591f110e0Safresh1=item != 1.3
110691f110e0Safresh1
110791f110e0Safresh1=item > 1.3
110891f110e0Safresh1
110991f110e0Safresh1=item < 1.3
111091f110e0Safresh1
111191f110e0Safresh1=item >= 1.3, != 1.5, <= 2.0
111291f110e0Safresh1
111391f110e0Safresh1A version number without an operator is equivalent to specifying a minimum
111491f110e0Safresh1(C<E<gt>=>).  Extra whitespace is allowed.
111591f110e0Safresh1
111691f110e0Safresh1=back
111791f110e0Safresh1
111891f110e0Safresh1=head2 from_string_hash
111991f110e0Safresh1
112091f110e0Safresh1  my $req = CPAN::Meta::Requirements->from_string_hash( \%hash );
1121*b8851fccSafresh1  my $req = CPAN::Meta::Requirements->from_string_hash( \%hash, \%opts );
112291f110e0Safresh1
1123*b8851fccSafresh1This is an alternate constructor for a CPAN::Meta::Requirements
1124*b8851fccSafresh1object. It takes a hash of module names and version requirement
1125*b8851fccSafresh1strings and returns a new CPAN::Meta::Requirements object. As with
1126*b8851fccSafresh1add_string_requirement, a version can be a Perl "v-string". Optionally,
1127*b8851fccSafresh1you can supply a hash-reference of options, exactly as with the L</new>
1128*b8851fccSafresh1method.
112991f110e0Safresh1
113091f110e0Safresh1=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
113191f110e0Safresh1
113291f110e0Safresh1=head1 SUPPORT
113391f110e0Safresh1
113491f110e0Safresh1=head2 Bugs / Feature Requests
113591f110e0Safresh1
113691f110e0Safresh1Please report any bugs or feature requests through the issue tracker
1137*b8851fccSafresh1at L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta-Requirements/issues>.
113891f110e0Safresh1You will be notified automatically of any progress on your issue.
113991f110e0Safresh1
114091f110e0Safresh1=head2 Source Code
114191f110e0Safresh1
114291f110e0Safresh1This is open source software.  The code repository is available for
114391f110e0Safresh1public review and contribution under the terms of the license.
114491f110e0Safresh1
1145*b8851fccSafresh1L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta-Requirements>
114691f110e0Safresh1
1147*b8851fccSafresh1  git clone https://github.com/Perl-Toolchain-Gang/CPAN-Meta-Requirements.git
114891f110e0Safresh1
114991f110e0Safresh1=head1 AUTHORS
115091f110e0Safresh1
115191f110e0Safresh1=over 4
115291f110e0Safresh1
115391f110e0Safresh1=item *
115491f110e0Safresh1
115591f110e0Safresh1David Golden <dagolden@cpan.org>
115691f110e0Safresh1
115791f110e0Safresh1=item *
115891f110e0Safresh1
115991f110e0Safresh1Ricardo Signes <rjbs@cpan.org>
116091f110e0Safresh1
116191f110e0Safresh1=back
116291f110e0Safresh1
1163*b8851fccSafresh1=head1 CONTRIBUTORS
1164*b8851fccSafresh1
1165*b8851fccSafresh1=for stopwords Ed J Karen Etheridge Leon Timmermans robario
1166*b8851fccSafresh1
1167*b8851fccSafresh1=over 4
1168*b8851fccSafresh1
1169*b8851fccSafresh1=item *
1170*b8851fccSafresh1
1171*b8851fccSafresh1Ed J <mohawk2@users.noreply.github.com>
1172*b8851fccSafresh1
1173*b8851fccSafresh1=item *
1174*b8851fccSafresh1
1175*b8851fccSafresh1Karen Etheridge <ether@cpan.org>
1176*b8851fccSafresh1
1177*b8851fccSafresh1=item *
1178*b8851fccSafresh1
1179*b8851fccSafresh1Leon Timmermans <fawaka@gmail.com>
1180*b8851fccSafresh1
1181*b8851fccSafresh1=item *
1182*b8851fccSafresh1
1183*b8851fccSafresh1robario <webmaster@robario.com>
1184*b8851fccSafresh1
1185*b8851fccSafresh1=back
1186*b8851fccSafresh1
118791f110e0Safresh1=head1 COPYRIGHT AND LICENSE
118891f110e0Safresh1
118991f110e0Safresh1This software is copyright (c) 2010 by David Golden and Ricardo Signes.
119091f110e0Safresh1
119191f110e0Safresh1This is free software; you can redistribute it and/or modify it under
119291f110e0Safresh1the same terms as the Perl 5 programming language system itself.
119391f110e0Safresh1
119491f110e0Safresh1=cut
1195