From e5c6e6d9c56fbfc54508fa2c32b03a5a870b7553 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 23 Apr 2014 22:10:41 +0000 Subject: oops, remove 5.16 tlperl files git-svn-id: svn://tug.org/texlive/trunk@33649 c570f23f-e606-0410-a88d-b1316a301751 --- Master/tlpkg/tlperl/lib/version/Internals.pod | 698 ------------------------ Master/tlpkg/tlperl/lib/version/Requirements.pm | 597 -------------------- 2 files changed, 1295 deletions(-) delete mode 100644 Master/tlpkg/tlperl/lib/version/Internals.pod delete mode 100644 Master/tlpkg/tlperl/lib/version/Requirements.pm (limited to 'Master/tlpkg/tlperl/lib/version') diff --git a/Master/tlpkg/tlperl/lib/version/Internals.pod b/Master/tlpkg/tlperl/lib/version/Internals.pod deleted file mode 100644 index ff63eba6af0..00000000000 --- a/Master/tlpkg/tlperl/lib/version/Internals.pod +++ /dev/null @@ -1,698 +0,0 @@ -=head1 NAME - -version::Internals - Perl extension for Version Objects - -=head1 DESCRIPTION - -Overloaded version objects for all modern versions of Perl. This documents -the internal data representation and underlying code for version.pm. See -F for daily usage. This document is only useful for users -interested in the gory details. - -=head1 WHAT IS A VERSION? - -For the purposes of this module, a version "number" is a sequence of -positive integer values separated by one or more decimal points and -optionally a single underscore. This corresponds to what Perl itself -uses for a version, as well as extending the "version as number" that -is discussed in the various editions of the Camel book. - -There are actually two distinct kinds of version objects: - -=over 4 - -=item Decimal Versions - -Any version which "looks like a number", see L. This -also includes versions with a single decimal point and a single embedded -underscore, see L, even though these must be quoted -to preserve the underscore formatting. - -=item Dotted-Decimal Versions - -Also referred to as "Dotted-Integer", these contains more than one decimal -point and may have an optional embedded underscore, see L. This is what is commonly used in most open source software as -the "external" version (the one used as part of the tag or tarfile name). -A leading 'v' character is now required and will warn if it missing. - -=back - -Both of these methods will produce similar version objects, in that -the default stringification will yield the version L only -if required: - - $v = version->new(1.002); # 1.002, but compares like 1.2.0 - $v = version->new(1.002003); # 1.002003 - $v2 = version->new("v1.2.3"); # v1.2.3 - -In specific, version numbers initialized as L will -stringify as they were originally created (i.e. the same string that was -passed to C. Version numbers initialized as L -will be stringified as L. - -=head2 Decimal Versions - -These correspond to historical versions of Perl itself prior to 5.6.0, -as well as all other modules which follow the Camel rules for the -$VERSION scalar. A Decimal version is initialized with what looks like -a floating point number. Leading zeros B significant and trailing -zeros are implied so that a minimum of three places is maintained -between subversions. What this means is that any subversion (digits -to the right of the decimal place) that contains less than three digits -will have trailing zeros added to make up the difference, but only for -purposes of comparison with other version objects. For example: - - # Prints Equivalent to - $v = version->new( 1.2); # 1.2 v1.200.0 - $v = version->new( 1.02); # 1.02 v1.20.0 - $v = version->new( 1.002); # 1.002 v1.2.0 - $v = version->new( 1.0023); # 1.0023 v1.2.300 - $v = version->new( 1.00203); # 1.00203 v1.2.30 - $v = version->new( 1.002003); # 1.002003 v1.2.3 - -All of the preceding examples are true whether or not the input value is -quoted. The important feature is that the input value contains only a -single decimal. See also L. - -IMPORTANT NOTE: As shown above, if your Decimal version contains more -than 3 significant digits after the decimal place, it will be split on -each multiple of 3, so 1.0003 is equivalent to v1.0.300, due to the need -to remain compatible with Perl's own 5.005_03 == 5.5.30 interpretation. -Any trailing zeros are ignored for mathematical comparison purposes. - -=head2 Dotted-Decimal Versions - -These are the newest form of versions, and correspond to Perl's own -version style beginning with 5.6.0. Starting with Perl 5.10.0, -and most likely Perl 6, this is likely to be the preferred form. This -method normally requires that the input parameter be quoted, although -Perl's after 5.8.1 can use v-strings as a special form of quoting, but -this is highly discouraged. - -Unlike L, Dotted-Decimal Versions have more than -a single decimal point, e.g.: - - # Prints - $v = version->new( "v1.200"); # v1.200.0 - $v = version->new("v1.20.0"); # v1.20.0 - $v = qv("v1.2.3"); # v1.2.3 - $v = qv("1.2.3"); # v1.2.3 - $v = qv("1.20"); # v1.20.0 - -In general, Dotted-Decimal Versions permit the greatest amount of freedom -to specify a version, whereas Decimal Versions enforce a certain -uniformity. - -Just like L, Dotted-Decimal Versions can be used as -L. - -=head2 Alpha Versions - -For module authors using CPAN, the convention has been to note unstable -releases with an underscore in the version string. (See L.) version.pm -follows this convention and alpha releases will test as being newer than the -more recent stable release, and less than the next stable release. Only the -last element may be separated by an underscore: - - # Declaring - use version 0.77; our $VERSION = version->declare("v1.2_3"); - - # Parsing - $v1 = version->parse("v1.2_3"); - $v1 = version->parse("1.002_003"); - -Note that you B quote the version when writing an alpha Decimal version. -The stringified form of Decimal versions will always be the same string that -was used to initialize the version object. - -=head2 Regular Expressions for Version Parsing - -A formalized definition of the legal forms for version strings is -included in the main F file. Primitives are included for -common elements, although they are scoped to the file so they are useful -for reference purposes only. There are two publicly accessible scalars -that can be used in other code (not exported): - -=over 4 - -=item C<$version::LAX> - -This regexp covers all of the legal forms allowed under the current -version string parser. This is not to say that all of these forms -are recommended, and some of them can only be used when quoted. - -For dotted decimals: - - v1.2 - 1.2345.6 - v1.23_4 - -The leading 'v' is optional if two or more decimals appear. If only -a single decimal is included, then the leading 'v' is required to -trigger the dotted-decimal parsing. A leading zero is permitted, -though not recommended except when quoted, because of the risk that -Perl will treat the number as octal. A trailing underscore plus one -or more digits denotes an alpha or development release (and must be -quoted to be parsed properly). - -For decimal versions: - - 1 - 1.2345 - 1.2345_01 - -an integer portion, an optional decimal point, and optionally one or -more digits to the right of the decimal are all required. A trailing -underscore is permitted and a leading zero is permitted. Just like -the lax dotted-decimal version, quoting the values is required for -alpha/development forms to be parsed correctly. - -=item C<$version::STRICT> - -This regexp covers a much more limited set of formats and constitutes -the best practices for initializing version objects. Whether you choose -to employ decimal or dotted-decimal for is a personal preference however. - -=over 4 - -=item v1.234.5 - -For dotted-decimal versions, a leading 'v' is required, with three or -more sub-versions of no more than three digits. A leading 0 (zero) -before the first sub-version (in the above example, '1') is also -prohibited. - -=item 2.3456 - -For decimal versions, an integer portion (no leading 0), a decimal point, -and one or more digits to the right of the decimal are all required. - -=back - -=back - -Both of the provided scalars are already compiled as regular expressions -and do not contain either anchors or implicit groupings, so they can be -included in your own regular expressions freely. For example, consider -the following code: - - ($pkg, $ver) =~ / - ^[ \t]* - use [ \t]+($PKGNAME) - (?:[ \t]+($version::STRICT))? - [ \t]*; - /x; - -This would match a line of the form: - - use Foo::Bar::Baz v1.2.3; # legal only in Perl 5.8.1+ - -where C<$PKGNAME> is another regular expression that defines the legal -forms for package names. - -=head1 IMPLEMENTATION DETAILS - -=head2 Equivalence between Decimal and Dotted-Decimal Versions - -When Perl 5.6.0 was released, the decision was made to provide a -transformation between the old-style decimal versions and new-style -dotted-decimal versions: - - 5.6.0 == 5.006000 - 5.005_04 == 5.5.40 - -The floating point number is taken and split first on the single decimal -place, then each group of three digits to the right of the decimal makes up -the next digit, and so on until the number of significant digits is exhausted, -B enough trailing zeros to reach the next multiple of three. - -This was the method that version.pm adopted as well. Some examples may be -helpful: - - equivalent - decimal zero-padded dotted-decimal - ------- ----------- -------------- - 1.2 1.200 v1.200.0 - 1.02 1.020 v1.20.0 - 1.002 1.002 v1.2.0 - 1.0023 1.002300 v1.2.300 - 1.00203 1.002030 v1.2.30 - 1.002003 1.002003 v1.2.3 - -=head2 Quoting Rules - -Because of the nature of the Perl parsing and tokenizing routines, -certain initialization values B be quoted in order to correctly -parse as the intended version, especially when using the C or -L methods. While you do not have to quote decimal numbers when -creating version objects, it is always safe to quote B initial values -when using version.pm methods, as this will ensure that what you type is -what is used. - -Additionally, if you quote your initializer, then the quoted value that goes -B will be be exactly what comes B when your $VERSION is printed -(stringified). If you do not quote your value, Perl's normal numeric handling -comes into play and you may not get back what you were expecting. - -If you use a mathematic formula that resolves to a floating point number, -you are dependent on Perl's conversion routines to yield the version you -expect. You are pretty safe by dividing by a power of 10, for example, -but other operations are not likely to be what you intend. For example: - - $VERSION = version->new((qw$Revision: 1.4)[1]/10); - print $VERSION; # yields 0.14 - $V2 = version->new(100/9); # Integer overflow in decimal number - print $V2; # yields something like 11.111.111.100 - -Perl 5.8.1 and beyond are able to automatically quote v-strings but -that is not possible in earlier versions of Perl. In other words: - - $version = version->new("v2.5.4"); # legal in all versions of Perl - $newvers = version->new(v2.5.4); # legal only in Perl >= 5.8.1 - -=head2 What about v-strings? - -There are two ways to enter v-strings: a bare number with two or more -decimal points, or a bare number with one or more decimal points and a -leading 'v' character (also bare). For example: - - $vs1 = 1.2.3; # encoded as \1\2\3 - $vs2 = v1.2; # encoded as \1\2 - -However, the use of bare v-strings to initialize version objects is -B discouraged in all circumstances. Also, bare -v-strings are not completely supported in any version of Perl prior to -5.8.1. - -If you insist on using bare v-strings with Perl > 5.6.0, be aware of the -following limitations: - -1) For Perl releases 5.6.0 through 5.8.0, the v-string code merely guesses, -based on some characteristics of v-strings. You B use a three part -version, e.g. 1.2.3 or v1.2.3 in order for this heuristic to be successful. - -2) For Perl releases 5.8.1 and later, v-strings have changed in the Perl -core to be magical, which means that the version.pm code can automatically -determine whether the v-string encoding was used. - -3) In all cases, a version created using v-strings will have a stringified -form that has a leading 'v' character, for the simple reason that sometimes -it is impossible to tell whether one was present initially. - -=head2 Version Object Internals - -version.pm provides an overloaded version object that is designed to both -encapsulate the author's intended $VERSION assignment as well as make it -completely natural to use those objects as if they were numbers (e.g. for -comparisons). To do this, a version object contains both the original -representation as typed by the author, as well as a parsed representation -to ease comparisons. Version objects employ L methods to -simplify code that needs to compare, print, etc the objects. - -The internal structure of version objects is a blessed hash with several -components: - - bless( { - 'original' => 'v1.2.3_4', - 'alpha' => 1, - 'qv' => 1, - 'version' => [ - 1, - 2, - 3, - 4 - ] - }, 'version' ); - -=over 4 - -=item original - -A faithful representation of the value used to initialize this version -object. The only time this will not be precisely the same characters -that exist in the source file is if a short dotted-decimal version like -v1.2 was used (in which case it will contain 'v1.2'). This form is -B discouraged, in that it will confuse you and your users. - -=item qv - -A boolean that denotes whether this is a decimal or dotted-decimal version. -See L. - -=item alpha - -A boolean that denotes whether this is an alpha version. NOTE: that the -underscore can can only appear in the last position. See L. - -=item version - -An array of non-negative integers that is used for comparison purposes with -other version objects. - -=back - -=head2 Replacement UNIVERSAL::VERSION - -In addition to the version objects, this modules also replaces the core -UNIVERSAL::VERSION function with one that uses version objects for its -comparisons. The return from this operator is always the stringified form -as a simple scalar (i.e. not an object), but the warning message generated -includes either the stringified form or the normal form, depending on how -it was called. - -For example: - - package Foo; - $VERSION = 1.2; - - package Bar; - $VERSION = "v1.3.5"; # works with all Perl's (since it is quoted) - - package main; - use version; - - print $Foo::VERSION; # prints 1.2 - - print $Bar::VERSION; # prints 1.003005 - - eval "use foo 10"; - print $@; # prints "foo version 10 required..." - eval "use foo 1.3.5; # work in Perl 5.6.1 or better - print $@; # prints "foo version 1.3.5 required..." - - eval "use bar 1.3.6"; - print $@; # prints "bar version 1.3.6 required..." - eval "use bar 1.004"; # note Decimal version - print $@; # prints "bar version 1.004 required..." - - -IMPORTANT NOTE: This may mean that code which searches for a specific -string (to determine whether a given module is available) may need to be -changed. It is always better to use the built-in comparison implicit in -C or C, rather than manually poking at C<< class->VERSION >> -and then doing a comparison yourself. - -The replacement UNIVERSAL::VERSION, when used as a function, like this: - - print $module->VERSION; - -will also exclusively return the stringified form. See L -for more details. - -=head1 USAGE DETAILS - -=head2 Using modules that use version.pm - -As much as possible, the version.pm module remains compatible with all -current code. However, if your module is using a module that has defined -C<$VERSION> using the version class, there are a couple of things to be -aware of. For purposes of discussion, we will assume that we have the -following module installed: - - package Example; - use version; $VERSION = qv('1.2.2'); - ...module code here... - 1; - -=over 4 - -=item Decimal versions always work - -Code of the form: - - use Example 1.002003; - -will always work correctly. The C will perform an automatic -C<$VERSION> comparison using the floating point number given as the first -term after the module name (e.g. above 1.002.003). In this case, the -installed module is too old for the requested line, so you would see an -error like: - - Example version 1.002003 (v1.2.3) required--this is only version 1.002002 (v1.2.2)... - -=item Dotted-Decimal version work sometimes - -With Perl >= 5.6.2, you can also use a line like this: - - use Example 1.2.3; - -and it will again work (i.e. give the error message as above), even with -releases of Perl which do not normally support v-strings (see L above). This has to do with that fact that C only checks -to see if the second term I and passes that to the -replacement L. This is not true in Perl 5.005_04, -however, so you are B to always use a Decimal version -in your code, even for those versions of Perl which support the Dotted-Decimal -version. - -=back - -=head2 Object Methods - -=over 4 - -=item new() - -Like many OO interfaces, the new() method is used to initialize version -objects. If two arguments are passed to C, the B one will be -used as if it were prefixed with "v". This is to support historical use of the -C operator with the CVS variable $Revision, which is automatically -incremented by CVS every time the file is committed to the repository. - -In order to facilitate this feature, the following -code can be employed: - - $VERSION = version->new(qw$Revision: 2.7 $); - -and the version object will be created as if the following code -were used: - - $VERSION = version->new("v2.7"); - -In other words, the version will be automatically parsed out of the -string, and it will be quoted to preserve the meaning CVS normally -carries for versions. The CVS $Revision$ increments differently from -Decimal versions (i.e. 1.10 follows 1.9), so it must be handled as if -it were a Dotted-Decimal Version. - -A new version object can be created as a copy of an existing version -object, either as a class method: - - $v1 = version->new(12.3); - $v2 = version->new($v1); - -or as an object method: - - $v1 = version->new(12.3); - $v2 = $v1->new(12.3); - -and in each case, $v1 and $v2 will be identical. NOTE: if you create -a new object using an existing object like this: - - $v2 = $v1->new(); - -the new object B be a clone of the existing object. In the -example case, $v2 will be an empty object of the same type as $v1. - -=back - -=over 4 - -=item qv() - -An alternate way to create a new version object is through the exported -qv() sub. This is not strictly like other q? operators (like qq, qw), -in that the only delimiters supported are parentheses (or spaces). It is -the best way to initialize a short version without triggering the floating -point interpretation. For example: - - $v1 = qv(1.2); # v1.2.0 - $v2 = qv("1.2"); # also v1.2.0 - -As you can see, either a bare number or a quoted string can usually -be used interchangeably, except in the case of a trailing zero, which -must be quoted to be converted properly. For this reason, it is strongly -recommended that all initializers to qv() be quoted strings instead of -bare numbers. - -To prevent the C function from being exported to the caller's namespace, -either use version with a null parameter: - - use version (); - -or just require version, like this: - - require version; - -Both methods will prevent the import() method from firing and exporting the -C sub. - -=back - -For the subsequent examples, the following three objects will be used: - - $ver = version->new("1.2.3.4"); # see "Quoting Rules" - $alpha = version->new("1.2.3_4"); # see "Alpha Versions" - $nver = version->new(1.002); # see "Decimal Versions" - -=over 4 - -=item Normal Form - -For any version object which is initialized with multiple decimal -places (either quoted or if possible v-string), or initialized using -the L operator, the stringified representation is returned in -a normalized or reduced form (no extraneous zeros), and with a leading 'v': - - print $ver->normal; # prints as v1.2.3.4 - print $ver->stringify; # ditto - print $ver; # ditto - print $nver->normal; # prints as v1.2.0 - print $nver->stringify; # prints as 1.002, see "Stringification" - -In order to preserve the meaning of the processed version, the -normalized representation will always contain at least three sub terms. -In other words, the following is guaranteed to always be true: - - my $newver = version->new($ver->stringify); - if ($newver eq $ver ) # always true - {...} - -=back - -=over 4 - -=item Numification - -Although all mathematical operations on version objects are forbidden -by default, it is possible to retrieve a number which corresponds -to the version object through the use of the $obj->numify -method. For formatting purposes, when displaying a number which -corresponds a version object, all sub versions are assumed to have -three decimal places. So for example: - - print $ver->numify; # prints 1.002003004 - print $nver->numify; # prints 1.002 - -Unlike the stringification operator, there is never any need to append -trailing zeros to preserve the correct version value. - -=back - -=over 4 - -=item Stringification - -The default stringification for version objects returns exactly the same -string as was used to create it, whether you used C or C, -with one exception. The sole exception is if the object was created using -C and the initializer did not have two decimal places or a leading -'v' (both optional), then the stringified form will have a leading 'v' -prepended, in order to support round-trip processing. - -For example: - - Initialized as Stringifies to - ============== ============== - version->new("1.2") 1.2 - version->new("v1.2") v1.2 - qv("1.2.3") 1.2.3 - qv("v1.3.5") v1.3.5 - qv("1.2") v1.2 ### exceptional case - -See also L, as this also returns the stringified form -when used as a class method. - -IMPORTANT NOTE: There is one exceptional cases shown in the above table -where the "initializer" is not stringwise equivalent to the stringified -representation. If you use the C() operator on a version without a -leading 'v' B with only a single decimal place, the stringified output -will have a leading 'v', to preserve the sense. See the L operator -for more details. - -IMPORTANT NOTE 2: Attempting to bypass the normal stringification rules by -manually applying L and L will sometimes yield -surprising results: - - print version->new(version->new("v1.0")->numify)->normal; # v1.0.0 - -The reason for this is that the L operator will turn "v1.0" -into the equivalent string "1.000000". Forcing the outer version object -to L form will display the mathematically equivalent "v1.0.0". - -As the example in L shows, you can always create a copy of an -existing version object with the same value by the very compact: - - $v2 = $v1->new($v1); - -and be assured that both C<$v1> and C<$v2> will be completely equivalent, -down to the same internal representation as well as stringification. - -=back - -=over 4 - -=item Comparison operators - -Both C and C=E> operators perform the same comparison between -terms (upgrading to a version object automatically). Perl automatically -generates all of the other comparison operators based on those two. -In addition to the obvious equalities listed below, appending a single -trailing 0 term does not change the value of a version for comparison -purposes. In other words "v1.2" and "1.2.0" will compare as identical. - -For example, the following relations hold: - - As Number As String Truth Value - ------------- ---------------- ----------- - $ver > 1.0 $ver gt "1.0" true - $ver < 2.5 $ver lt true - $ver != 1.3 $ver ne "1.3" true - $ver == 1.2 $ver eq "1.2" false - $ver == 1.2.3.4 $ver eq "1.2.3.4" see discussion below - -It is probably best to chose either the Decimal notation or the string -notation and stick with it, to reduce confusion. Perl6 version objects -B only support Decimal comparisons. See also L. - -WARNING: Comparing version with unequal numbers of decimal points (whether -explicitly or implicitly initialized), may yield unexpected results at -first glance. For example, the following inequalities hold: - - version->new(0.96) > version->new(0.95); # 0.960.0 > 0.950.0 - version->new("0.96.1") < version->new(0.95); # 0.096.1 < 0.950.0 - -For this reason, it is best to use either exclusively L or -L with multiple decimal points. - -=back - -=over 4 - -=item Logical Operators - -If you need to test whether a version object -has been initialized, you can simply test it directly: - - $vobj = version->new($something); - if ( $vobj ) # true only if $something was non-blank - -You can also test whether a version object is an alpha version, for -example to prevent the use of some feature not present in the main -release: - - $vobj = version->new("1.2_3"); # MUST QUOTE - ...later... - if ( $vobj->is_alpha ) # True - -=back - -=head1 AUTHOR - -John Peacock Ejpeacock@cpan.orgE - -=head1 SEE ALSO - -L. - -=cut diff --git a/Master/tlpkg/tlperl/lib/version/Requirements.pm b/Master/tlpkg/tlperl/lib/version/Requirements.pm deleted file mode 100644 index 39ae2060909..00000000000 --- a/Master/tlpkg/tlperl/lib/version/Requirements.pm +++ /dev/null @@ -1,597 +0,0 @@ -use strict; -use warnings; -package Version::Requirements; -{ - $Version::Requirements::VERSION = '0.101022'; -} -# ABSTRACT: a set of version requirements for a CPAN dist - - -use Carp (); -use Scalar::Util (); -use version 0.77 (); # the ->parse method - -# We silence this warning during core tests, because this is only in core -# because it has to be, and nobody wants to see this stupid warning. -# -- rjbs, 2012-01-20 -Carp::cluck( - "Version::Requirements is deprecated; replace with CPAN::Meta::Requirements" -) unless $ENV{PERL_CORE}; - - -sub new { - my ($class) = @_; - return bless {} => $class; -} - -sub _version_object { - my ($self, $version) = @_; - - $version = (! defined $version) ? version->parse(0) - : (! Scalar::Util::blessed($version)) ? version->parse($version) - : $version; - - return $version; -} - - -BEGIN { - for my $type (qw(minimum maximum exclusion exact_version)) { - my $method = "with_$type"; - my $to_add = $type eq 'exact_version' ? $type : "add_$type"; - - my $code = sub { - my ($self, $name, $version) = @_; - - $version = $self->_version_object( $version ); - - $self->__modify_entry_for($name, $method, $version); - - return $self; - }; - - no strict 'refs'; - *$to_add = $code; - } -} - - -sub add_requirements { - my ($self, $req) = @_; - - for my $module ($req->required_modules) { - my $modifiers = $req->__entry_for($module)->as_modifiers; - for my $modifier (@$modifiers) { - my ($method, @args) = @$modifier; - $self->$method($module => @args); - }; - } - - return $self; -} - - -sub accepts_module { - my ($self, $module, $version) = @_; - - $version = $self->_version_object( $version ); - - return 1 unless my $range = $self->__entry_for($module); - return $range->_accepts($version); -} - - -sub clear_requirement { - my ($self, $module) = @_; - - return $self unless $self->__entry_for($module); - - Carp::confess("can't clear requirements on finalized requirements") - if $self->is_finalized; - - delete $self->{requirements}{ $module }; - - return $self; -} - - -sub required_modules { keys %{ $_[0]{requirements} } } - - -sub clone { - my ($self) = @_; - my $new = (ref $self)->new; - - return $new->add_requirements($self); -} - -sub __entry_for { $_[0]{requirements}{ $_[1] } } - -sub __modify_entry_for { - my ($self, $name, $method, $version) = @_; - - my $fin = $self->is_finalized; - my $old = $self->__entry_for($name); - - Carp::confess("can't add new requirements to finalized requirements") - if $fin and not $old; - - my $new = ($old || 'Version::Requirements::_Range::Range') - ->$method($version); - - Carp::confess("can't modify finalized requirements") - if $fin and $old->as_string ne $new->as_string; - - $self->{requirements}{ $name } = $new; -} - - -sub is_simple { - my ($self) = @_; - for my $module ($self->required_modules) { - # XXX: This is a complete hack, but also entirely correct. - return if $self->__entry_for($module)->as_string =~ /\s/; - } - - return 1; -} - - -sub is_finalized { $_[0]{finalized} } - - -sub finalize { $_[0]{finalized} = 1 } - - -sub as_string_hash { - my ($self) = @_; - - my %hash = map {; $_ => $self->{requirements}{$_}->as_string } - $self->required_modules; - - return \%hash; -} - - -my %methods_for_op = ( - '==' => [ qw(exact_version) ], - '!=' => [ qw(add_exclusion) ], - '>=' => [ qw(add_minimum) ], - '<=' => [ qw(add_maximum) ], - '>' => [ qw(add_minimum add_exclusion) ], - '<' => [ qw(add_maximum add_exclusion) ], -); - -sub from_string_hash { - my ($class, $hash) = @_; - - my $self = $class->new; - - for my $module (keys %$hash) { - my @parts = split qr{\s*,\s*}, $hash->{ $module }; - for my $part (@parts) { - my ($op, $ver) = split /\s+/, $part, 2; - - if (! defined $ver) { - $self->add_minimum($module => $op); - } else { - Carp::confess("illegal requirement string: $hash->{ $module }") - unless my $methods = $methods_for_op{ $op }; - - $self->$_($module => $ver) for @$methods; - } - } - } - - return $self; -} - -############################################################## - -{ - package - Version::Requirements::_Range::Exact; - sub _new { bless { version => $_[1] } => $_[0] } - - sub _accepts { return $_[0]{version} == $_[1] } - - sub as_string { return "== $_[0]{version}" } - - sub as_modifiers { return [ [ exact_version => $_[0]{version} ] ] } - - sub _clone { - (ref $_[0])->_new( version->new( $_[0]{version} ) ) - } - - sub with_exact_version { - my ($self, $version) = @_; - - return $self->_clone if $self->_accepts($version); - - Carp::confess("illegal requirements: unequal exact version specified"); - } - - sub with_minimum { - my ($self, $minimum) = @_; - return $self->_clone if $self->{version} >= $minimum; - Carp::confess("illegal requirements: minimum above exact specification"); - } - - sub with_maximum { - my ($self, $maximum) = @_; - return $self->_clone if $self->{version} <= $maximum; - Carp::confess("illegal requirements: maximum below exact specification"); - } - - sub with_exclusion { - my ($self, $exclusion) = @_; - return $self->_clone unless $exclusion == $self->{version}; - Carp::confess("illegal requirements: excluded exact specification"); - } -} - -############################################################## - -{ - package - Version::Requirements::_Range::Range; - - sub _self { ref($_[0]) ? $_[0] : (bless { } => $_[0]) } - - sub _clone { - return (bless { } => $_[0]) unless ref $_[0]; - - my ($s) = @_; - my %guts = ( - (exists $s->{minimum} ? (minimum => version->new($s->{minimum})) : ()), - (exists $s->{maximum} ? (maximum => version->new($s->{maximum})) : ()), - - (exists $s->{exclusions} - ? (exclusions => [ map { version->new($_) } @{ $s->{exclusions} } ]) - : ()), - ); - - bless \%guts => ref($s); - } - - sub as_modifiers { - my ($self) = @_; - my @mods; - push @mods, [ add_minimum => $self->{minimum} ] if exists $self->{minimum}; - push @mods, [ add_maximum => $self->{maximum} ] if exists $self->{maximum}; - push @mods, map {; [ add_exclusion => $_ ] } @{$self->{exclusions} || []}; - return \@mods; - } - - sub as_string { - my ($self) = @_; - - return 0 if ! keys %$self; - - return "$self->{minimum}" if (keys %$self) == 1 and exists $self->{minimum}; - - my @exclusions = @{ $self->{exclusions} || [] }; - - my @parts; - - for my $pair ( - [ qw( >= > minimum ) ], - [ qw( <= < maximum ) ], - ) { - my ($op, $e_op, $k) = @$pair; - if (exists $self->{$k}) { - my @new_exclusions = grep { $_ != $self->{ $k } } @exclusions; - if (@new_exclusions == @exclusions) { - push @parts, "$op $self->{ $k }"; - } else { - push @parts, "$e_op $self->{ $k }"; - @exclusions = @new_exclusions; - } - } - } - - push @parts, map {; "!= $_" } @exclusions; - - return join q{, }, @parts; - } - - sub with_exact_version { - my ($self, $version) = @_; - $self = $self->_clone; - - Carp::confess("illegal requirements: exact specification outside of range") - unless $self->_accepts($version); - - return Version::Requirements::_Range::Exact->_new($version); - } - - sub _simplify { - my ($self) = @_; - - if (defined $self->{minimum} and defined $self->{maximum}) { - if ($self->{minimum} == $self->{maximum}) { - Carp::confess("illegal requirements: excluded all values") - if grep { $_ == $self->{minimum} } @{ $self->{exclusions} || [] }; - - return Version::Requirements::_Range::Exact->_new($self->{minimum}) - } - - Carp::confess("illegal requirements: minimum exceeds maximum") - if $self->{minimum} > $self->{maximum}; - } - - # eliminate irrelevant exclusions - if ($self->{exclusions}) { - my %seen; - @{ $self->{exclusions} } = grep { - (! defined $self->{minimum} or $_ >= $self->{minimum}) - and - (! defined $self->{maximum} or $_ <= $self->{maximum}) - and - ! $seen{$_}++ - } @{ $self->{exclusions} }; - } - - return $self; - } - - sub with_minimum { - my ($self, $minimum) = @_; - $self = $self->_clone; - - if (defined (my $old_min = $self->{minimum})) { - $self->{minimum} = (sort { $b cmp $a } ($minimum, $old_min))[0]; - } else { - $self->{minimum} = $minimum; - } - - return $self->_simplify; - } - - sub with_maximum { - my ($self, $maximum) = @_; - $self = $self->_clone; - - if (defined (my $old_max = $self->{maximum})) { - $self->{maximum} = (sort { $a cmp $b } ($maximum, $old_max))[0]; - } else { - $self->{maximum} = $maximum; - } - - return $self->_simplify; - } - - sub with_exclusion { - my ($self, $exclusion) = @_; - $self = $self->_clone; - - push @{ $self->{exclusions} ||= [] }, $exclusion; - - return $self->_simplify; - } - - sub _accepts { - my ($self, $version) = @_; - - return if defined $self->{minimum} and $version < $self->{minimum}; - return if defined $self->{maximum} and $version > $self->{maximum}; - return if defined $self->{exclusions} - and grep { $version == $_ } @{ $self->{exclusions} }; - - return 1; - } -} - -1; - -__END__ -=pod - -=head1 NAME - -Version::Requirements - a set of version requirements for a CPAN dist - -=head1 VERSION - -version 0.101022 - -=head1 SYNOPSIS - - use Version::Requirements; - - my $build_requires = Version::Requirements->new; - - $build_requires->add_minimum('Library::Foo' => 1.208); - - $build_requires->add_minimum('Library::Foo' => 2.602); - - $build_requires->add_minimum('Module::Bar' => 'v1.2.3'); - - $METAyml->{build_requires} = $build_requires->as_string_hash; - -=head1 DESCRIPTION - -A Version::Requirements object models a set of version constraints like those -specified in the F or F files in CPAN distributions. It -can be built up by adding more and more constraints, and it will reduce them to -the simplest representation. - -Logically impossible constraints will be identified immediately by thrown -exceptions. - -=head1 METHODS - -=head2 new - - my $req = Version::Requirements->new; - -This returns a new Version::Requirements object. It ignores any arguments -given. - -=head2 add_minimum - - $req->add_minimum( $module => $version ); - -This adds a new minimum version requirement. If the new requirement is -redundant to the existing specification, this has no effect. - -Minimum requirements are inclusive. C<$version> is required, along with any -greater version number. - -This method returns the requirements object. - -=head2 add_maximum - - $req->add_maximum( $module => $version ); - -This adds a new maximum version requirement. If the new requirement is -redundant to the existing specification, this has no effect. - -Maximum requirements are inclusive. No version strictly greater than the given -version is allowed. - -This method returns the requirements object. - -=head2 add_exclusion - - $req->add_exclusion( $module => $version ); - -This adds a new excluded version. For example, you might use these three -method calls: - - $req->add_minimum( $module => '1.00' ); - $req->add_maximum( $module => '1.82' ); - - $req->add_exclusion( $module => '1.75' ); - -Any version between 1.00 and 1.82 inclusive would be acceptable, except for -1.75. - -This method returns the requirements object. - -=head2 exact_version - - $req->exact_version( $module => $version ); - -This sets the version required for the given module to I the given -version. No other version would be considered acceptable. - -This method returns the requirements object. - -=head2 add_requirements - - $req->add_requirements( $another_req_object ); - -This method adds all the requirements in the given Version::Requirements object -to the requirements object on which it was called. If there are any conflicts, -an exception is thrown. - -This method returns the requirements object. - -=head2 accepts_module - - my $bool = $req->accepts_modules($module => $version); - -Given an module and version, this method returns true if the version -specification for the module accepts the provided version. In other words, -given: - - Module => '>= 1.00, < 2.00' - -We will accept 1.00 and 1.75 but not 0.50 or 2.00. - -For modules that do not appear in the requirements, this method will return -true. - -=head2 clear_requirement - - $req->clear_requirement( $module ); - -This removes the requirement for a given module from the object. - -This method returns the requirements object. - -=head2 required_modules - -This method returns a list of all the modules for which requirements have been -specified. - -=head2 clone - - $req->clone; - -This method returns a clone of the invocant. The clone and the original object -can then be changed independent of one another. - -=head2 is_simple - -This method returns true if and only if all requirements are inclusive minimums --- that is, if their string expression is just the version number. - -=head2 is_finalized - -This method returns true if the requirements have been finalized by having the -C method called on them. - -=head2 finalize - -This method marks the requirements finalized. Subsequent attempts to change -the requirements will be fatal, I they would result in a change. If they -would not alter the requirements, they have no effect. - -If a finalized set of requirements is cloned, the cloned requirements are not -also finalized. - -=head2 as_string_hash - -This returns a reference to a hash describing the requirements using the -strings in the F specification. - -For example after the following program: - - my $req = Version::Requirements->new; - - $req->add_minimum('Version::Requirements' => 0.102); - - $req->add_minimum('Library::Foo' => 1.208); - - $req->add_maximum('Library::Foo' => 2.602); - - $req->add_minimum('Module::Bar' => 'v1.2.3'); - - $req->add_exclusion('Module::Bar' => 'v1.2.8'); - - $req->exact_version('Xyzzy' => '6.01'); - - my $hashref = $req->as_string_hash; - -C<$hashref> would contain: - - { - 'Version::Requirements' => '0.102', - 'Library::Foo' => '>= 1.208, <= 2.206', - 'Module::Bar' => '>= v1.2.3, != v1.2.8', - 'Xyzzy' => '== 6.01', - } - -=head2 from_string_hash - - my $req = Version::Requirements->from_string_hash( \%hash ); - -This is an alternate constructor for a Version::Requirements object. It takes -a hash of module names and version requirement strings and returns a new -Version::Requirements object. - -=head1 AUTHOR - -Ricardo Signes - -=head1 COPYRIGHT AND LICENSE - -This software is copyright (c) 2010 by Ricardo Signes. - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - -=cut - -- cgit v1.2.3