File Coverage

blib/lib/DhMakePerl/Utils.pm
Criterion Covered Total %
statement 12 14 85.7
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 17 19 89.4


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