Giter VIP home page Giter VIP logo

cpan-meta-requirements's People

Contributors

haarg avatar karenetheridge avatar leont avatar miyagawa avatar mohawk2 avatar pghmcfc avatar rjbs avatar robario avatar xdg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cpan-meta-requirements's Issues

Feature: Add support for requirements in the form of PackageURLs (purls)

Hei!

I'd like to propose to add support to specifying requirements in the form of PackageURLs (purls), in work in addition to the existing ways (using dist/module names).

With this, I'm hoping that we can get a step closer to supporting requirements that work across ecosystem boundaries.

e.g. the following...

prereqs => {
  runtime => {
    requires => {
      'CPAN::Meta::Requirements' => '0.102',
      'Library::Foo' => '>= 1.208, <= 2.206',
      'Module::Bar'  => '>= v1.2.3, != v1.2.8',
      'Xyzzy'        => '== 6.01',
      'Module::Foo'  => '1.0',
    },
  },
}

...could be written as...

prereqs => {
  runtime => {
    requires => {
      'pkg:cpan/CPAN::Meta::Requirements' => 'vers:cpan/0.102', # resolves to same as above
      'pkg:cpan/Library::Foo' => 'vers:cpan/>=1.208|<=2.206',   # resolves to same as above
      'pkg:cpan/Module::Bar'  => 'vers:cpan/>=v1.2.3|!=v1.2.8', # resolves to same as above
      'pkg:cpan/Xyzzy'        => 'vers:cpan/==6.01',            # resolves to same as above
      'Module::Foo'           => '1.0',                         # old way continues to work
    },
  },
}

...and while this is fine, this also opens for a bunch of really cool new things!

prereqs => {
  develop => {
    requires => {
      'Dist::Zilla' => 0,
      'pkg:github/twbs/bootstrap' => 'vers:github/>5.0', # we embed bootstrap.js in this dist, so let's specify that it's a dep
    },
  },
  configure => {
    requires => {
      'pkg:deb/ubuntu/xz-utils' => 'vers:deb/>=4.0|!=5.6.1|!=5.6.2', # depend on xz-utils, but don't want vulnerable releases
    },
  },
  build => {
    requires => {
      'pkg:deb/ubuntu/libmysqlclient-dev' => 'vers:deb/>7.0',  # we use mysql's header files for an FFI
      'pkg:deb/debian/mysqlclient-dev' => 'vers:deb/>7.0',   # pretend that Debian's mysql header files are in a different package
    },
  },
}

I'm also hoping this to be a foundation for allowing non-cpan software to state any requirements they have for components published on CPAN, and maybe even one day make it easier for packagers (the folks that re-package CPAN dists into .deb or .rpm or other package archives) have an easier time figuring out how to translate and resolve dependencies across ecosystem boundaries. ๐Ÿ˜

But for CPAN's case, I'm thinking support for purls starts with CPAN::Meta::Requirements?

I'm not entirely sure what's the best way to go about this, but since @giterlizzi recently added support for the 'vers' schema in URI::PackageURL, I'm thinking that's a place to start looking.

Should that module be made smaller/leaner? Are there other requirements (eg. around governance) that need to be fulfilled?

What needs be in place for a feature like this to be added to CPAN::Meta::Requirements?

(edit: added some more examples and clarifications)

Add compatibility with older versions of version.pm.

The patch below provides compatibility with version.pm 0.77, as distributed with Perl 5.10.1.

diff -ru lib/CPAN/Meta/Requirements.pm /home/vagrant/deb-build/libcpan-meta-requirements-perl/lib/CPAN/Meta/Requirements.pm
--- lib/CPAN/Meta/Requirements.pm   2013-08-30 16:17:18.000000000 +0000
+++ /home/vagrant/deb-build/libcpan-meta-requirements-perl/lib/CPAN/Meta/Requirements.pm    2013-09-03 16:14:16.234403263 +0000
@@ -28,6 +28,7 @@
   my $vobj;

   eval {
+    local $SIG{__WARN__} = sub { die "Invalid version: $_[0]" };
     $vobj  = (! defined $version)                ? version->parse(0)
            : (! Scalar::Util::blessed($version)) ? version->parse($version)
            :                                       $version;

Best regards,
Dave Lambley

test errors on 5.6

possibly related to #1 ?

cpan[1]> install CPAN::Meta::Requirements                                                                                                                                                                                                 
Reading '/Users/ether/.cpan/sources/authors/01mailrc.txt.gz'
............................................................................DONE
Reading '/Users/ether/.cpan/sources/modules/02packages.details.txt.gz'
  Database was generated on Thu, 29 May 2014 02:17:37 GMT
  HTTP::Date not available
............................................................................DONE
Reading '/Users/ether/.cpan/sources/modules/03modlist.data.gz'
DONE
Running install for module 'CPAN::Meta::Requirements'
Checksum for /Users/ether/.cpan/sources/authors/id/D/DA/DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz ok
Scanning cache /Users/ether/.cpan/build for sizes
............................................................................DONE
'YAML' not installed, will not store persistent state
Use of uninitialized value in scalar assignment at /Users/ether/.perlbrew/libs/6.2@std/lib/perl5/CPAN/Distribution.pm line 1838.
Use of uninitialized value in scalar assignment at /Users/ether/.perlbrew/libs/6.2@std/lib/perl5/CPAN/Distribution.pm line 1839.
Configuring D/DA/DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz with Makefile.PL
Use of uninitialized value in scalar assignment at /Users/ether/.perlbrew/libs/6.2@std/lib/perl5/CPAN/Distribution.pm line 1859.
Use of uninitialized value in scalar assignment at /Users/ether/.perlbrew/libs/6.2@std/lib/perl5/CPAN/Distribution.pm line 1860.
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for CPAN::Meta::Requirements
Writing MYMETA.yml and MYMETA.json
  DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz
  /Users/ether/perl5/perlbrew/perls/6.2/bin/perl Makefile.PL LIB=/Users/ether/.perlbrew/libs/6.2@std/lib/perl5 -- OK
Running make for D/DA/DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz
Use of uninitialized value in scalar assignment at /Users/ether/.perlbrew/libs/6.2@std/lib/perl5/CPAN/Distribution.pm line 2138.
cp lib/CPAN/Meta/Requirements.pm blib/lib/CPAN/Meta/Requirements.pm
Manifying blib/man3/CPAN::Meta::Requirements.0
lib/CPAN/Meta/Requirements.pm:439: Unknown command paragraph "=encoding utf-8"
  DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz
  /usr/bin/make -- OK
Running make test
PERL_DL_NONLAZY=1 /Users/ether/perl5/perlbrew/perls/6.2/bin/perl "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/accepts.t ............ ok                                             
t/bad_version_hook.t ... ok                                             
t/finalize.t ........... ok                                             
===(      29;0  0/1  0/1  11/?  1/?  0/? )==============================
#   Failed test 'we die when we can't understand a version spec: did not die'
#   at t/from-hash.t line 13.
# Looks like you failed 1 test of 4.
t/from-hash.t .......... Dubious, test returned 1 (wstat 256, 0x100)    
Failed 1/4 subtests 
t/merge.t .............. ok                                             
t/basic.t .............. ok                                             
===(      53;0  1/1  0/1 )==============================================Using /Users/ether/.cpan/build/CPAN-Meta-Requirements-2.125-K09yFC/blib
t/00-compile.t ......... ok                                             
t/00-report-prereqs.t .. # Prerequisite Report:
#    Version Module               
#   -------- ---------------------
#     1.3301 Carp                 
#       6.98 ExtUtils::MakeMaker  
#       3.40 File::Spec           
#       3.40 File::Spec::Functions
#     0.2304 File::Temp           
#       1.21 IO::Handle           
#     1.0103 IPC::Open3           
#       1.38 List::Util           
#       1.38 Scalar::Util         
#   1.001003 Test::More           
#       1.01 strict               
#     0.9908 version              
#      undef warnings             
t/00-report-prereqs.t .. ok   

Test Summary Report
-------------------
t/from-hash.t        (Wstat: 256 Tests: 4 Failed: 1)
  Failed test:  2
  Non-zero exit status: 1
Files=8, Tests=54,  0 wallclock secs ( 0.05 usr  0.02 sys +  0.54 cusr  0.10 csys =  0.71 CPU)
Result: FAIL
Failed 1/8 test programs. 1/54 subtests failed.
make: *** [test_dynamic] Error 35
  DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz
  /usr/bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:
  reports DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz
Failed during this command:
 DAGOLDEN/CPAN-Meta-Requirements-2.125.tar.gz : make_test NO

Bad handling of small fractional numeric versions

If a version number is passed in numeric form, C::M::R will use its stringified form for all its processing. This doesn't play well with small fractional versions like 0.000005, which will be stringified as '5e-06', and thus rejected as invalid. For values that are numeric (possibly checked via looks_like_number or B flags) it should stringify them using sprintf '%f' instead.

Wrong CPAN::Meta::Requirements version

The version of CPAN::Meta::Requirements in Check.pm is not consistant with what is mentioend elsewhere, and this breaks creating RPMs of this package. The following patch fixes it, please apply. Thanks!

--- CPAN-Meta-Check-0.009.orig/lib/CPAN/Meta/Check.pm 2014-06-20 19:37:50.000000000 +0200
+++ CPAN-Meta-Check-0.009/lib/CPAN/Meta/Check.pm 2015-01-25 09:58:07.366002061 +0100
@@ -8,7 +8,7 @@
our @EXPORT_OK = qw/check_requirements requirements_for verify_dependencies/;
our %EXPORT_TAGS = (all => [ @export, @EXPORT_OK ] );

-use CPAN::Meta::Requirements 2.120920;
+use CPAN::Meta::Requirements 2.121;
use Module::Metadata;

sub _check_dep {

Publicize Range classes and objects

I've requested this to rjbs numerous times on irc, but just for a record purpose I post it here.

I want to parse and handle CPAN Meta spec's "Version Range" object as a first class object. CPAN::Meta::Requirements has a fine API, but its interface is always string representation based and always works with paris of (module => version range), and the internal _Range classes are kept private.

This has led me to:

  • have to do a double parsing after CMR's normalization to construct MetaCPAN query for example (this has been addressed by #21 though)
  • have to have a fake module name when all I want is a "is this version acceptable by this version range?" operation.

I think moving _Range classes to a public class and making __entry_for a public method (like version_range_for_module) is a great start. Additionally, a simple parse API such as CPAN::Meta::Version::Range->parse($str) would be nice to have.

Version string normalization destroys alpha version info

Since _version_object runs $vobj = version->new($vobj->normal);, a version string like 2.3.0.0_01 will get warped into v2.3.0.1 after _version_object returns. Even with 2 or 3 version parts, like 2.3.0_01 or 2.3_01, the final string is corrupted.

This may be a better solution:

if ( _is_qv($vobj) && !$vobj->is_alpha ) {
    $vobj = version->new($vobj->normal);
}

Throws exception on lax version

This came to me a bit surprising. I cannot say whether it is a bug or feature. In my code I did not use eval and learned that I need it when I want to survive lax versions.

perl -E '
use CPAN::Meta::Requirements;
say "ok -- CMR version: $CPAN::Meta::Requirements::VERSION";
my $m = CPAN::Meta::Requirements->new;
$m->add_minimum(Foo => 1);
my $ok = eval { $m->accepts_module(Foo => "2.08a") };
say $ok ? "ok -- $ok" : "not ok -- $@";
'                                  
ok -- CMR version: 2.140
not ok -- Can't convert '2.08a': Invalid version format (non-numeric data)

Descriptive error messages (hopefully an object!) to get which package gives conflicts

Right now when merging two requirements, all I get is a string error saying "illegal requirements: minimum exceeds maximum at ..." with a giant stacktrace.

This isn't really helpful to present to users (using cpanm or Carmel), I'd like to display which requirement for which module gets a conflict. That should actually be doable if I walk down each module individually (because I have access to old and new requirement to add), but when calling ->add_requirements, the error message doesn't give any clue which module has the conflict.

For now like said above, I'll write my own merge wrapper to try to get them, but would be nice if the error message is more descriptive from CMR!

block a range of versions via '<=' and '>='

This is more a wishlist than an issue.

I was thinking about blocking a range of versions for a dependency module that are known to be problematic. I tried a combination of '<=4.04,>=4.09' and got the following error :

illegal requirements: minimum exceeds maximum

The thing is I don't necessarily need the users to upload to 4.09 when I know that the 3.xx branch just works. Right now, I'm blocking the 4 versions that cause a problem one by one, but it'd be nice if could block a range as well.

Wrong installation into site on 5.8.9 [rt.cpan.org #88141]

https://rt.cpan.org/Ticket/Display.html?id=88141

On perl-5.8.9 version 2.120351 is installed in core.
Version 2.122 installs into site, not into core.
Please set a proper INSTALLDIRS.

5.8.9 favors core over site.
  @INC:
    /usr/local/lib/perl5/5.8.9/x86_64-linux
    /usr/local/lib/perl5/5.8.9
    /usr/local/lib/perl5/site_perl/5.8.9/x86_64-linux
    /usr/local/lib/perl5/site_perl/5.8.9

Hence:

  CPAN.pm: Building L/LE/LEONT/CPAN-Meta-Check-0.007.tar.gz

Warning: Prerequisite 'CPAN::Meta => 2.120920' for 'LEONT/CPAN-Meta-Check-0.007.tar.gz' failed when processing 'DAGOLDEN/CPAN-Meta-2.132140.tar.gz' with 'make_test => NO'. Continuing, but chances to succeed are limited.
cp lib/CPAN/Meta/Check.pm blib/lib/CPAN/Meta/Check.pm
Manifying blib/man3/CPAN::Meta::Check.3
  LEONT/CPAN-Meta-Check-0.007.tar.gz
  /usr/bin/make -- OK
Running make test
PERL_DL_NONLAZY=1 /usr/local/bin/perl5.8.9-nt "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00-compile.t ............ CPAN::Meta::Requirements version 2.12092 required--this is only version 2.120351 at lib/CPAN/Meta/Check.pm line 13.
BEGIN failed--compilation aborted at lib/CPAN/Meta/Check.pm line 13.
Compilation failed in require at -e line 1.
t/00-compile.t ............ 1/1 
#   Failed test 'CPAN::Meta::Check loaded ok'
#   at t/00-compile.t line 62.
#                   ''
#     doesn't match '(?s-xim:^\s*CPAN::Meta::Check ok)'
# Looks like you failed 1 test of 1.
t/00-compile.t ............ Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/1 subtests 
t/10-basics.t ............. CPAN::Meta version 2.12092 required--this is only version 2.120351 at t/10-basics.t line 8.
BEGIN failed--compilation aborted at t/10-basics.t line 8.
t/10-basics.t ............. Dubious, test returned 255 (wstat 65280, 0xff00)
No subtests run 
t/release-pod-coverage.t .. skipped: these tests are for release candidate testing
t/release-pod-syntax.t .... skipped: these tests are for release candidate testing

Does 0.8.0 really not fulfil ">=0.6" ?

I know that comparing versions can be tricky, but is it really reasonable to reject version 0.8.0 when someone requires 0.6 and above?

use CPAN::Meta::Requirements;
my $build_requires = CPAN::Meta::Requirements->new;
$build_requires->add_minimum('Thrift' => '0.6');
if( $build_requires->accepts_module( 'Thrift' => '0.8.0' ) ) {
print "yes!\n";
} else {
print "nooo ...\n";
}

Ignore alpha in version comparison

re: miyagawa/cpanminus#463

CPAN::Meta::Requirements internally uses version.pm for comparing versions, and it tends to have issues with underscore/alpha in versions.

use CPAN::Meta::Requirements;
warn CPAN::Meta::Requirements
  ->from_string_hash({ Foo => "1.23" })
  ->accepts_module("Foo", "1.2_3"); # undef

Fixing it in core/version.pm is another issue, but maybe we can relax CMR to normalize the version before comparing it in version.pm. Note that version.pm's normalize function might have issues by itself, such as: https://rt.cpan.org/Public/Bug/Display.html?id=98744

Remove the use of Carp::confess

This module uses Carp::confess in some places when bad/conflicting input is supplied, and I'd say that's not a great behavior as a library. I use this library from cpanm/Carmel/Menlo and every time I call some methods I need to wrap it with try/catch to prevent a giant wall of text from being shown to the end user. Can we change it to croak?

As a bonus, some other code in this module when parsing version doesn't do this, and even strips at line... and doesn't even show the line number, so that's not very consistent.

If someone wants a stack trace for errors one can always use something like -MCarp::Always to get the trace.

โžœ  perl -MCPAN::Meta::Requirements
my $reqs = CPAN::Meta::Requirements->new;
$reqs->add_string_requirement(Foo => "<1");
$reqs->add_string_requirement(Foo => "2");
illegal requirements for Foo: minimum 2 exceeds maximum 1 at /Users/miyagawa/.plenv/versions/5.32.1/lib/perl5/5.32.1/CPAN/Meta/Requirements.pm line 752.
        CPAN::Meta::Requirements::_Range::Range::_reject_requirements(CPAN::Meta::Requirements::_Range::Range=HASH(0x15a832f28), "Foo", "minimum 2 exceeds maximum 1") called at /Users/miyagawa/.plenv/versions/5.32.1/lib/perl5/5.32.1/CPAN/Meta/Requirements.pm line 785
        CPAN::Meta::Requirements::_Range::Range::_simplify(CPAN::Meta::Requirements::_Range::Range=HASH(0x15a832f28), "Foo") called at /Users/miyagawa/.plenv/versions/5.32.1/lib/perl5/5.32.1/CPAN/Meta/Requirements.pm line 819
        CPAN::Meta::Requirements::_Range::Range::with_minimum(CPAN::Meta::Requirements::_Range::Range=HASH(0x15a0f63e0), version=HASH(0x15a0ea2e0), "Foo") called at /Users/miyagawa/.plenv/versions/5.32.1/lib/perl5/5.32.1/CPAN/Meta/Requirements.pm line 406
        CPAN::Meta::Requirements::__modify_entry_for(CPAN::Meta::Requirements=HASH(0x15a0b03b0), "Foo", "with_minimum", version=HASH(0x15a0ea2e0)) called at /Users/miyagawa/.plenv/versions/5.32.1/lib/perl5/5.32.1/CPAN/Meta/Requirements.pm line 252
        CPAN::Meta::Requirements::add_minimum(CPAN::Meta::Requirements=HASH(0x15a0b03b0), "Foo", 2) called at /Users/miyagawa/.plenv/versions/5.32.1/lib/perl5/5.32.1/CPAN/Meta/Requirements.pm line 560
        CPAN::Meta::Requirements::add_string_requirement(CPAN::Meta::Requirements=HASH(0x15a0b03b0), "Foo", 2) called at - line 3
โžœ  perl -MCPAN::Meta::Requirements
my $reqs = CPAN::Meta::Requirements->new;
$reqs->add_string_requirement(Foo => "blahblabh");
Can't convert 'blahblabh': Invalid version format (non-numeric data)

"0.00" and "!= 0.00" now simplified as "0" and "!= 0" respectively.

I'm not entirely sure where this lies in bug department. I stumbled on to it as it made one of @SineSwiper's dists fail

https://metacpan.org/source/BBYRD/Dist-Zilla-PluginBundle-Prereqs-0.93/t/01-MinimumPrereqs.t#L30

Its rather odd because "1.00" preserves the trailing part. And its not clear if this is an oversight in that CMeta is not retaining data, or its a bug in @SineSwiper's dist being too generous about testing for what "0.00" means.

Test code that is really simple to express this failure:

use strict;
use warnings;

use Test::More tests => 1;
use CPAN::Meta::Requirements;

my $source = CPAN::Meta::Requirements->new();
$source->add_string_requirement('XX' => '0.00');
$source->add_string_requirement('YY' => '!= 0.00');
$source->add_string_requirement('ZZ' => '1.00');
$source->add_string_requirement('aa' => '!= 1.00');

my $merged = CPAN::Meta::Requirements->new();
$merged->add_requirements( $source );
is_deeply(
  $merged->as_string_hash,
  $source->as_string_hash,
  "Structures are the same"
);
note explain {
  source => $source->as_string_hash,
  merged => $merged->as_string_hash
};

Output:

1..1
not ok 1 - Structures are the same
#   Failed test 'Structures are the same'
#   at /tmp/cmeta.pl line 17.
#     Structures begin differing at:
#          $got->{XX} = '0'
#     $expected->{XX} = '0.00'
# {
#   'merged' => {
#     'XX' => '0',
#     'YY' => '!= 0',
#     'ZZ' => '1.00',
#     'aa' => '!= 1.00'
#   },
#   'source' => {
#     'XX' => '0.00',
#     'YY' => '!= 0.00',
#     'ZZ' => '1.00',
#     'aa' => '!= 1.00'
#   }
# }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.