File Coverage

blib/lib/DhMakePerl/Utils.pm
Criterion Covered Total %
statement 15 17 88.2
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 21 23 91.3


line stmt bran cond sub pod time code
1             package DhMakePerl::Utils;
2              
3 5     5   610161 use strict;
  5         18  
  5         192  
4 5     5   25 use warnings;
  5         9  
  5         456  
5              
6             our $VERSION = '0.71';
7              
8             =head1 NAME
9              
10             DhMakePerl::Utils - helper routines for dh-make-perl and alike
11              
12             =head1 SYNOPSIS
13              
14             use DhMakePerl::Utils qw(is_core_module);
15              
16             my $v = is_core_module('Test::More', '1.002');
17             my $v = nice_perl_ver('5.010001');
18              
19             =cut
20              
21             our @EXPORT_OK = qw(
22             find_core_perl_dependency
23             find_cpan_module find_cpan_distribution
24             is_core_module
25             nice_perl_ver
26             split_version_relation
27             );
28              
29 5     5   104 use base 'Exporter';
  5         8  
  5         936  
30              
31 5     5   182 use 5.10.0;
  5         26  
32              
33 5     5   72327 use Module::CoreList ();
  5         294528  
  5         2940  
34 5     5   4185 use Debian::Dependency;
  0            
  0            
35              
36             =head1 FUNCTIONS
37              
38             None of he following functions is exported by default.
39              
40             =over
41              
42             =item find_cpan_module
43              
44             Returns CPAN::Module object that corresponds to the supplied argument. Returns
45             undef if no module is found by CPAN.
46              
47             If the CPAN module needs to be configured in some way, that should be done
48             before calling this function.
49              
50             =cut
51              
52             sub find_cpan_module {
53             my( $name ) = @_;
54              
55             my $mod;
56              
57             # expand() returns a list of matching items when called in list
58             # context, so after retrieving it, we try to match exactly what
59             # the user asked for. Specially important when there are
60             # different modules which only differ in case.
61             #
62             # This Closes: #451838
63             my @mod = CPAN::Shell->expand( 'Module', '/^' . $name . '$/' );
64              
65             foreach (@mod) {
66             my $file = $_->cpan_file();
67             $file =~ s#.*/##; # remove directory
68             $file =~ s/(.*)-.*/$1/; # remove version and extension
69             $file =~ s/-/::/g; # convert dashes to colons
70             if ( $file eq $name ) {
71             $mod = $_;
72             last;
73             }
74             }
75             $mod = shift @mod unless ($mod);
76              
77             return $mod;
78             }
79              
80             =item find_cpan_distribution
81              
82             Returns CPAN::Distribution object that corresponds to the supplied argument.
83             Returns undef if no distribution is found by CPAN.
84              
85             If the CPAN module needs to be configured in some way, that should be done
86             before calling this function.
87              
88             =cut
89              
90             sub find_cpan_distribution {
91             my( $name ) = @_;
92              
93             $name =~ s/::/-/g;
94              
95             return CPAN::Shell->expand( 'Distribution',
96             "/\\/$name-[^\\/]+\\.(tar|zip)/" );
97             }
98              
99             =item is_core_module I, I
100              
101             Returns the version of the C package containing the given I (at
102             least version I).
103              
104             Returns C if I is not a core module.
105              
106             =cut
107              
108             sub is_core_module {
109             my ( $module, $ver ) = @_;
110              
111             my $v = Module::CoreList->first_release($module, $ver); # 5.009002
112              
113             return unless defined $v;
114              
115             $v = version->new($v); # v5.9.2
116             ( $v = $v->normal ) =~ s/^v//; # "5.9.2"
117              
118             return $v;
119             }
120              
121             =item nice_perl_ver I
122              
123             Re-formats perl version to match Debian's perl package versions.
124              
125             For example C<5.010> (and C<5.01>) is converted to C<5.10>.
126              
127             =cut
128              
129             sub nice_perl_ver {
130             my( $v ) = @_;
131              
132             if( $v =~ /\.(\d+)$/ and $v !~ /\..+\./ ) { # do nothing for 5.9.1
133             my $minor = $1;
134             if( length($minor) % 3 ) {
135             # right-pad with zeroes so that the number of digits after the dot
136             # is a multiple of 3
137             $minor .= '0' x ( 3 - length($minor) % 3 );
138             }
139              
140             my $ver = 0 + substr( $minor, 0, 3 );
141             if( length($minor) > 3 ) {
142             $ver .= '.' . ( 0 + substr( $minor, 3 ) );
143             }
144             $v =~ s/\.\d+$/.$ver/;
145              
146             $v .= '.0' if $v =~ /^\d+\.\d+$/; # force three-component version
147             }
148              
149             return $v;
150             }
151              
152             =item core_module_perls I[, I]
153              
154             Returns a list of Perl versions that have I. If I is
155             given, the list contains only Perl versions containing I at least
156             version I.
157              
158             =cut
159              
160             sub core_module_perls {
161             my( $module, $version ) = @_;
162              
163             my @ret;
164              
165             $version = version->new($version) if $version;
166              
167             for my $v(
168             sort keys %Module::CoreList::version ){
169              
170             # Module::CoreList::version includes families (i.e. "5") as well as
171             # full versions, skip the families.
172             next unless ($v =~ /^\d+\.\d+(?:\.|$)/);
173              
174             next unless exists $Module::CoreList::version{$v}{$module};
175              
176             my $found = $Module::CoreList::version{$v}{$module};
177              
178             push @ret, $v
179             if not $version
180             or $found and version->new($found) >= $version;
181             }
182              
183             return @ret;
184             }
185              
186             =item find_core_perl_dependency( $module[, $version] )
187              
188             return a dependency on perl containing the required module version. If the
189             module is not available in any perl released by Debian, return undef.
190              
191             =cut
192              
193             our %debian_perl = (
194             '5.8' => {
195             min => Dpkg::Version->new('5.8.8'),
196             max => Dpkg::Version->new('5.8.8'),
197             },
198             '5.10' => {
199             min => Dpkg::Version->new('5.10.0'),
200             max => Dpkg::Version->new('5.10.1'),
201             },
202             );
203              
204             sub find_core_perl_dependency {
205             my ( $module, $version ) = @_;
206              
207             if ( $module eq 'perl' ) {
208             return Debian::Dependency->new('perl') unless $version;
209              
210             return Debian::Dependency->new( 'perl', nice_perl_ver($version) );
211             }
212              
213             my $perl_dep;
214              
215             my @perl_releases = core_module_perls( $module, $version );
216              
217             for my $v (@perl_releases) {
218             $v = nice_perl_ver($v);
219              
220             $v =~ /^(\d+\.\d+)(?:\.|$)/;
221             my $major = $1 or die "[$v] is a strange version";
222              
223             # we want to avoid depending on things like 5.8.9 which aren't in
224             # Debian and can contain stuff newer than in 5.10.0
225             if ( $debian_perl{$major}
226             and $debian_perl{$major}{max} >= $v )
227             {
228             return Debian::Dependency->new( 'perl', $v );
229             }
230             }
231              
232             # not a core module
233             return undef;
234             }
235              
236             =item split_version_relation I
237              
238             Splits the string, typically found in dependency fields' values in CPAN META
239             into relation and version. If no relation is found in the string, C<< >= >> is
240             assumed.
241              
242             Returns a list of relation and version. The relation is suitable for using in
243             Debian package dependency version requirements.
244              
245             For example
246              
247             =over
248              
249             =item split_version_relation('0.45') returns ( '>=', '0.45' )
250              
251             =item split_version_relation('< 0.56') returns ( '<<', '0.56' )
252              
253             =back
254              
255             =cut
256              
257             sub split_version_relation {
258             my $in = shift;
259              
260             $in =~ s/^\s*([<>=!])\s*//;
261              
262             my $rel = $1 // '>=';
263              
264             $rel = '>>' if $rel eq '>';
265              
266             $rel = '<<' if $rel eq '<';
267              
268             return ( $rel, $in );
269             }
270              
271             =back
272              
273             =head1 COPYRIGHT & LICENSE
274              
275             =over
276              
277             =item Copyright (C) 2008, 2009, 2010 Damyan Ivanov
278              
279             =back
280              
281             This program is free software; you can redistribute it and/or modify it under
282             the terms of the GNU General Public License version 2 as published by the Free
283             Software Foundation.
284              
285             This program is distributed in the hope that it will be useful, but WITHOUT ANY
286             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
287             PARTICULAR PURPOSE. See the GNU General Public License for more details.
288              
289             You should have received a copy of the GNU General Public License along with
290             this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
291             Street, Fifth Floor, Boston, MA 02110-1301 USA.
292              
293             =cut
294              
295             1; # End of DhMakePerl