@@ -13,6 +13,7 @@ use Class::Tiny qw/uri/;
1313
1414use Carp;
1515use CPAN::Meta::YAML;
16+ use CPAN::Meta::Requirements;
1617use HTTP::Tiny;
1718
1819=attr uri
@@ -38,25 +39,61 @@ sub search_packages {
3839 Carp::croak(" Argument to search_packages must be hash reference" )
3940 unless ref $args eq ' HASH' ;
4041
41- # only support direct package query
4242 return
43- unless keys %$args == 1 && exists $args -> {package } && ref $args -> {package } eq ' ' ;
43+ unless exists $args -> {package } && ref $args -> {package } eq ' ' ;
4444
4545 my $mod = $args -> {package };
46- my $res = HTTP::Tiny-> new-> get( $self -> uri . " package/$mod " );
47- return unless $res -> {success };
4846
49- if ( my $yaml = CPAN::Meta::YAML-> read_string( $res -> {content } ) ) {
50- my $meta = $yaml -> [0];
51- if ( $meta && $meta -> {distfile } ) {
52- my $file = $meta -> {distfile };
47+ if ($args -> {version } || $args -> {version_range }) {
48+ my $res = HTTP::Tiny-> new-> get( $self -> uri . " history/$mod " );
49+ return unless $res -> {success };
50+
51+ my $range = defined $args -> {version } ? " == $args ->{version}" : $args -> {version_range };
52+ my $reqs = CPAN::Meta::Requirements-> from_string_hash({ $mod => $range });
53+
54+ my @found ;
55+ for my $line ( split /\r?\n/, $res -> {content } ) {
56+ if ($line =~ / ^$mod \s +(\S +)\s +(\S +)$ / ) {
57+ push @found , {
58+ version => $1 ,
59+ version_o => version::-> parse($1 ),
60+ distfile => $2 ,
61+ };
62+ }
63+ }
64+
65+ my $match ;
66+ for my $try (sort { $b -> {version_o } <=> $a -> {version_o } } @found ) {
67+ if ($reqs -> accepts_module($mod => $try -> {version_o })) {
68+ $match = $try , last ;
69+ }
70+ }
71+
72+ if ($match ) {
73+ my $file = $match -> {distfile };
5374 $file =~ s { ^./../} {} ; # strip leading
5475 return {
5576 package => $mod ,
56- version => $meta -> {version },
77+ version => $match -> {version },
5778 uri => " cpan:///distfile/$file " ,
5879 };
5980 }
81+ } else {
82+ my $res = HTTP::Tiny-> new-> get( $self -> uri . " package/$mod " );
83+ return unless $res -> {success };
84+
85+ if ( my $yaml = CPAN::Meta::YAML-> read_string( $res -> {content } ) ) {
86+ my $meta = $yaml -> [0];
87+ if ( $meta && $meta -> {distfile } ) {
88+ my $file = $meta -> {distfile };
89+ $file =~ s { ^./../} {} ; # strip leading
90+ return {
91+ package => $mod ,
92+ version => $meta -> {version },
93+ uri => " cpan:///distfile/$file " ,
94+ };
95+ }
96+ }
6097 }
6198
6299 return ;
@@ -76,6 +113,9 @@ sub search_authors { return }; # not supported
76113
77114 $index = CPAN::Common::Index::MetaDB->new;
78115
116+ $index->search_packages({ package => "Moose" });
117+ $index->search_packages({ package => "Moose", version_range => ">= 2.0" });
118+
79119=head1 DESCRIPTION
80120
81121This module implements a CPAN::Common::Index that searches for packages against
0 commit comments