File Coverage

blib/lib/DhMakePerl/Command/Packaging.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package DhMakePerl::Command::Packaging;
2              
3 5     5   26586541 use strict;
  5         18  
  5         247  
4 5     5   31 use warnings;
  5         16  
  5         441  
5              
6             our $VERSION = '0.84';
7              
8 5     5   150 use feature 'switch';
  5         13  
  5         1055  
9              
10             =head1 NAME
11              
12             DhMakePerl::Command::Packaging - common routines for 'make' and 'refresh' dh-make-perl commands
13              
14             =cut
15              
16 5     5   31 use base 'DhMakePerl';
  5         29  
  5         3300  
17              
18             __PACKAGE__->mk_accessors(
19             qw( main_dir debian_dir
20             mod_cpan_version
21             meta perlname author
22             version rules docs examples copyright
23             control
24             dist_ini
25             )
26             );
27              
28             use Array::Unique;
29             use Carp qw(confess);
30             use Config::INI::Reader ();
31             use CPAN ();
32             use CPAN::Meta;
33             use Cwd qw( getcwd );
34             use Debian::Control::FromCPAN;
35             use Debian::Dependencies;
36             use Debian::Rules;
37             use DhMakePerl::PodParser ();
38             use File::Basename qw(basename dirname);
39             use File::Find qw(find);
40             use File::Path ();
41             use File::Which;
42             use File::Spec::Functions qw(catfile catpath splitpath);
43             use Parse::DebianChangelog;
44             use Text::Balanced qw(extract_quotelike);
45             use Text::Wrap qw(fill);
46             use User::pwent;
47              
48             use constant debstdversion => '3.9.6';
49              
50             our %DEFAULTS = (
51             );
52              
53             sub new {
54             my $class = shift;
55             $class = ref($class) if ref($class);
56              
57             my $self = $class->SUPER::new(@_);
58              
59             while( my( $k, $v ) = each %DEFAULTS ) {
60             $self->$k($v) unless defined $self->$k;
61             }
62              
63             $self->cfg or die "cfg is mandatory";
64              
65             my @docs;
66             tie @docs, 'Array::Unique';
67              
68             $self->docs( \@docs );
69              
70             my @examples;
71             tie @examples, 'Array::Unique';
72              
73             $self->examples( \@examples );
74              
75             $self->control( Debian::Control::FromCPAN->new )
76             unless $self->control;
77              
78             return $self;
79             }
80              
81             =head1 METHODS
82              
83             =over
84              
85             =item main_file(file_name)
86              
87             Constructs a file name relative to the main source directory, L
88              
89             =cut
90              
91             sub main_file {
92             my( $self, $file ) = @_;
93              
94             catfile( $self->main_dir, $file );
95             }
96              
97             =item debian_file(file_name)
98              
99             Constructs a file name relative to the debian/ sub-directory of the main source
100             directory.
101              
102             =cut
103              
104             sub debian_file {
105             my( $self, $file ) = @_;
106              
107             catfile( $self->main_file('debian'), $file );
108             }
109              
110             sub build_pl {
111             my ($self) = @_;
112              
113             return $self->main_file('Build.PL');
114             }
115              
116             sub makefile_pl {
117             my ($self) = @_;
118              
119             return $self->main_file('Makefile.PL');
120             }
121              
122             sub get_developer {
123             my $self = shift;
124              
125             my $email = $self->cfg->email;
126              
127             my ( $user, $pwnam, $name, $mailh );
128             $user = $ENV{LOGNAME} || $ENV{USER};
129             $pwnam = getpwuid($<);
130             die "Cannot determine current user\n" unless $pwnam;
131             if ( defined $ENV{DEBFULLNAME} ) {
132             $name = $ENV{DEBFULLNAME};
133             }
134             else {
135             $name = $pwnam->gecos;
136             $name =~ s/,.*//;
137             }
138             $user ||= $pwnam->name;
139             $name ||= $user;
140             $email ||= ( $ENV{DEBEMAIL} || $ENV{EMAIL} );
141             unless ($email) {
142             chomp( $mailh = `cat /etc/mailname` );
143             $email = $user . '@' . $mailh;
144             }
145              
146             $email =~ s/^(.*)\s+<(.*)>$/$2/;
147              
148             return "$name <$email>";
149             }
150              
151             sub fill_maintainer {
152             my $self = shift;
153              
154             my $src = $self->control->source;
155             my $maint = $self->get_developer;
156              
157             if ( $self->cfg->pkg_perl ) {
158             my $pkg_perl_maint
159             = "Debian Perl Group ";
160             unless ( ( $src->Maintainer // '' ) eq $pkg_perl_maint ) {
161             my $old_maint = $src->Maintainer;
162             $src->Maintainer($pkg_perl_maint);
163             $src->Uploaders->add($old_maint) if $old_maint;
164             }
165              
166             $src->Uploaders->add($maint);
167             }
168             else {
169             $src->Maintainer($maint);
170             }
171             }
172              
173             sub process_meta {
174             my ($self) = @_;
175              
176             $self->meta({});
177              
178             # Command line option nometa causes this function not to be run
179             if( $self->cfg->nometa ) {
180             return;
181             }
182              
183             my $meta = $self->main_file('META.json');
184             if ( -e $meta ) {
185             print "Using META.json\n" if $self->cfg->verbose;
186             }
187             else {
188             $meta = $self->main_file('META.yml');
189             if ( -e $meta ) {
190             print "Using META.yml\n" if $self->cfg->verbose;
191             }
192             else {
193             print "WARNING: Neither META.json nor META.yml was found\n";
194             return;
195             }
196             }
197              
198             $meta = CPAN::Meta->load_file($meta);
199             $self->meta( $meta->as_struct );
200              
201             my $dist_ini_fn = $self->main_file('dist.ini');
202             $self->dist_ini( Config::INI::Reader->read_file($dist_ini_fn) )
203             if -e $dist_ini_fn;
204             }
205              
206             sub set_package_name {
207             my $self = shift;
208              
209             my $pkgname;
210             if (defined $self->cfg->packagename) {
211             $pkgname = $self->cfg->packagename;
212             }
213             else {
214             $pkgname = Debian::Control::FromCPAN->module_name_to_pkg_name( $self->perlname );
215             }
216              
217             $self->control->source->Source($pkgname)
218             unless $self->control->source->Source;
219              
220             $self->control->binary_tie->Push( $pkgname =>
221             Debian::Control::Stanza::Binary->new( { Package => $pkgname } ) )
222             unless $self->control->binary->{$pkgname};
223             }
224              
225             sub pkgname {
226             @_ == 1 or die 'Syntax: $obj->pkgname()';
227              
228             my $self = shift;
229              
230             my $pkg = $self->control->binary_tie->Values(0)->Package;
231              
232             defined($pkg) and $pkg ne ''
233             or confess "called before set_package_name()";
234              
235             return $pkg;
236             }
237              
238             sub srcname {
239             @_ == 1 or die 'Syntax: $obj->srcname()';
240              
241             my $self = shift;
242              
243             my $pkg = $self->control->source->Source;
244              
245             defined($pkg) and $pkg ne ''
246             or confess "called before set_package_name()";
247              
248             return $pkg;
249             }
250              
251             sub get_wnpp {
252             my ( $self, $package ) = @_;
253              
254             return undef unless $self->cfg->network;
255              
256             my $wnpp = Debian::WNPP::Query->new(
257             { cache_file => catfile( $self->cfg->home_dir, 'wnpp.cache' ) } );
258             my @bugs = $wnpp->bugs_for_package($package);
259             return $bugs[0];
260             }
261              
262             sub extract_basic {
263             my ($self) = @_;
264              
265             $self->extract_name_ver();
266              
267             my $src = $self->control->source;
268             my $bin = $self->control->binary_tie->Values(0);
269              
270             $src->Section('perl') unless defined $src->Section;
271             $src->Priority('optional') unless defined $src->Priority;
272              
273             if ( $self->cfg->arch ) {
274             printf "Forcing architecture to '%s'\n", $self->cfg->arch;
275             $bin->Architecture( $self->cfg->arch );
276             }
277             else {
278             $bin->Architecture('all');
279             find( sub { $self->check_for_xs }, $self->main_dir );
280             }
281              
282             $self->cfg->dh('9')
283             if $bin->Architecture eq 'any'
284             and not $self->cfg->_explicitly_set->{dh};
285              
286             printf(
287             "Found: %s %s (%s arch=%s)\n",
288             $self->perlname, $self->version,
289             $self->pkgname, $bin->Architecture
290             ) if $self->cfg->verbose;
291             $self->debian_dir( $self->main_file('debian') );
292              
293             find(
294             { no_chdir => 1,
295             wanted => sub {
296             return if $File::Find::name =~ $self->cfg->exclude;
297              
298             if (/\.(pm|pod)$/) {
299             $self->extract_desc($_)
300             unless $bin->short_description
301             and $bin->long_description;
302             $self->extract_basic_copyright($_)
303             unless $self->author and $self->copyright;
304             }
305             },
306             },
307             $self->main_dir
308             );
309             }
310              
311             sub sanitize_version {
312             my $self = shift;
313             my ($ver) = @_;
314              
315             return undef unless defined($ver);
316              
317             $ver =~ s/^v//;
318             $ver =~ s/[^-.+a-zA-Z0-9]+/-/g;
319             $ver = "0$ver" unless $ver =~ /^\d/;
320              
321             return $ver;
322             }
323              
324             sub extract_name_ver {
325             my ($self) = @_;
326              
327             my ( $name, $ver );
328              
329             if ( defined $self->meta->{name} and defined $self->meta->{version} ) {
330             $name = $self->meta->{name};
331             $ver = $self->meta->{version};
332             }
333             elsif ( defined $self->cfg->packagename and defined $self->cfg->version ) {
334             $name = $self->cfg->packagename;
335             $ver = $self->cfg->version;
336             }
337             else {
338             if ( -e $self->build_pl ) {
339             print "Extracting name and version from Build.PL\n";
340             $self->extract_name_ver_from_build( $self->build_pl );
341             }
342             elsif ( -e $self->makefile_pl ) {
343             print "Extracting name and version from Makefile.PL\n";
344             $self->extract_name_ver_from_makefile( $self->makefile_pl );
345             }
346             else {
347             if ( $self->cfg->cpan ) {
348             my $name = $self->cfg->cpan;
349             $name =~ s/::/-/g;
350             $self->perlname($name);
351             }
352             else {
353             die "Unable to determine dist name, no Build.PL, no Makefile.PL\nPlease use --cpan.\n";
354             }
355             }
356             $name = $self->perlname;
357             $ver = $self->version;
358             }
359              
360             $ver = $self->cfg->version
361             if $self->cfg->version;
362              
363             # final sanitazing of name and version
364             $name =~ s/::/-/g if defined $name;
365             $ver = $self->sanitize_version($ver) if defined $ver && !$self->cfg->version;
366              
367             defined($ver) and $ver ne ''
368             or die "Unable to determine dist version\. Please use --version.\n";
369              
370             defined($name) and $name ne ''
371             or die "Unable to determine dist name\. Please use --packagename.\n";
372              
373             $self->perlname($name);
374             $self->version($ver);
375              
376             $self->set_package_name;
377             }
378              
379             sub extract_name_ver_from_build {
380             my ( $self, $build ) = @_;
381             my ( $file, $name, $ver, $vfrom, $dir );
382              
383             {
384             local $/ = undef;
385             my $fh = $self->_file_r($build);
386             $file = $fh->getline;
387             }
388              
389             # Replace q[quotes] by "quotes"
390             $file =~ s/q\[(.+)]/'$1'/g;
391              
392             # Get the name
393             if ($file =~ /([\'\"]?)
394             dist_name\1\s*
395             (=>|,)
396             \s*
397             ([\'\"]?)
398             (\S+)\3/xs
399             )
400             {
401             $name = $4;
402             }
403             elsif (
404             $file =~ /([\'\"]?)
405             module_name\1\s*
406             (=>|,)
407             \s*
408             (\S+)/xs
409             )
410             {
411             $name = $self->unquote($3);
412             $name =~ s/::/-/g;
413              
414             # just in case we need it later
415             $vfrom = $name;
416             $vfrom =~ s/-/::/g;
417             $vfrom =~s{::}{/}g;
418             $vfrom = "lib/$vfrom.pm";
419             }
420             return unless defined $name;
421             $name =~ s/,.*$//;
422              
423             # band aid: need to find a solution also for build in directories
424             # warn "name is $name (cpan name: $self->cfg->cpan)\n";
425             $name = $self->cfg->cpan if ( $name eq '__PACKAGE__' && $self->cfg->cpan );
426             $name = $self->cfg->cpanplus if ( $name eq '__PACKAGE__' && $self->cfg->cpanplus );
427              
428             # Get the version
429             if ( defined $self->cfg->version ) {
430              
431             # Explicitly specified
432             $ver = $self->cfg->version;
433              
434             }
435             elsif ( $file =~ /([\'\"]?)\sdist_version\1\s*(=>|,)\s*([\'\"]?)([^\s,]*)\3/s ) {
436             $ver = $4;
437              
438             # Where is the version taken from?
439             $vfrom = $4
440             if $file
441             =~ /([\'\"]?)dist_version_from\1\s*(=>|,)\s*([\'\"]?)([^\s,]*)\3/s;
442              
443             }
444             elsif ( $file =~ /([\'\"]?)dist_version_from\1\s*(=>|,)\s*([\'\"]?)([^\s,]*)\3/s )
445             {
446             $vfrom = $4;
447              
448             }
449              
450             $dir = dirname($build) || './';
451              
452             for ( ( $name, $ver ) ) {
453             next unless defined;
454             next unless /^\$/;
455              
456             # decode simple vars
457             s/(\$\w+).*/$1/;
458             if ( $file =~ /\Q$_\E\s*=\s*([\'\"]?)(\S+)\1\s*;/ ) {
459             $_ = $2;
460             }
461             }
462              
463             unless ( defined $ver ) {
464             local $/ = "\n";
465              
466             # apply the method used by makemaker
467             if ( defined $dir
468             and defined $vfrom
469             and -f "$dir/$vfrom"
470             and -r "$dir/$vfrom" )
471             {
472             my $fh = $self->_file_r("$dir/$vfrom");
473             while ( my $lin = $fh->getline ) {
474             if ( $lin =~ /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/ ) {
475             no strict;
476              
477             #warn "ver: $lin";
478             $ver = ( eval $lin )[0];
479             last;
480             }
481             }
482             $fh->close;
483             }
484             else {
485             if ( $self->mod_cpan_version ) {
486             $ver = $self->mod_cpan_version;
487             warn "Cannot use internal module data to gather the "
488             . "version; using cpan_version\n";
489             }
490             else {
491             die "Cannot use internal module data to gather the "
492             . "version; use --cpan or --version\n";
493             }
494             }
495             }
496              
497             $self->perlname($name);
498             $self->version($ver);
499              
500             $self->set_package_name;
501              
502             if ( defined($vfrom) ) {
503             $self->extract_desc("$dir/$vfrom");
504             $self->extract_basic_copyright("$dir/$vfrom");
505             }
506             }
507              
508             sub extract_name_ver_from_makefile {
509             my ( $self, $makefile ) = @_;
510             my ( $file, $name, $ver, $vfrom, $dir );
511              
512             {
513             local $/ = undef;
514             my $fh = $self->_file_r($makefile);
515             $file = $fh->getline;
516             }
517              
518             # Get the name
519             if ($file =~ /([\'\"]?)
520             DISTNAME\1\s*
521             (=>|,)
522             \s*
523             (\S+)/xs
524             )
525             {
526              
527             # Regular MakeMaker
528             $name = $self->unquote($3);
529             }
530             elsif (
531             $file =~ /([\'\"]?)
532             NAME\1\s*
533             (=>|,)
534             \s*
535             (\S+)\s*,?/xs
536             )
537             {
538              
539             # Regular MakeMaker
540             $name = $self->unquote($3);
541             }
542             elsif (
543             $file =~ m{
544             name
545             \s*
546             (\S+) # Quoted name
547             \s*;
548             }xs
549             )
550             {
551              
552             # Module::Install syntax
553             $name = $self->unquote($1);
554             }
555             return unless defined $name;
556             $name =~ s/,.*$//;
557              
558             # band aid: need to find a solution also for build in directories
559             # warn "name is $name (cpan name: $self->cfg->cpan)\n";
560             $name = $self->cfg->cpan if ( $name eq '__PACKAGE__' && $self->cfg->cpan );
561             $name = $self->cfg->cpanplus if ( $name eq '__PACKAGE__' && $self->cfg->cpanplus );
562              
563             # Get the version
564             if ( defined $self->cfg->version ) {
565              
566             # Explicitly specified
567             $ver = $self->cfg->version;
568              
569             }
570             elsif ( $file =~ /([\'\"]?)\bVERSION\1\s*(=>|,)\s*([\'\"]?)([^\s,]*)\3/s ) {
571              
572             # Regular MakeMaker
573             $ver = $4;
574              
575             # Where is the version taken from?
576             $vfrom = $4
577             if $file
578             =~ /([\'\"]?)VERSION_FROM\1\s*(=>|,)\s*([\'\"]?)([^\s,]*)\3/s;
579              
580             }
581             elsif ( $file =~ /([\'\"]?)VERSION_FROM\1\s*(=>|,)\s*([\'\"]?)([^\s,]*)\3/s )
582             {
583              
584             # Regular MakeMaker pointing to where the version is taken from
585             $vfrom = $4;
586              
587             }
588             elsif (
589             $file =~ m{
590             \bversion\b\s* # The word version
591             \(?\s* # Optional open-parens
592             (['"]?) # Optional quotes
593             ([\d_.]+) # The actual version.
594             \1 # Optional close-quotes
595             \s*\)? # Optional close-parenthesis.
596             }sx
597             ) {
598              
599             # Module::Install
600             $ver = $2;
601             }
602              
603             $dir = dirname($makefile) || './';
604              
605             for ( ( $name, $ver ) ) {
606             next unless defined;
607             next unless /^\$/;
608              
609             # decode simple vars
610             s/(\$\w+).*/$1/;
611             if ( $file =~ /\Q$_\E\s*=\s*([\'\"]?)(\S+)\1\s*;/ ) {
612             $_ = $2;
613             }
614             }
615              
616             unless ( defined $ver ) {
617             local $/ = "\n";
618              
619             # apply the method used by makemaker
620             if ( defined $dir
621             and defined $vfrom
622             and -f "$dir/$vfrom"
623             and -r "$dir/$vfrom" )
624             {
625             my $fh = $self->_file_r("$dir/$vfrom");
626             while ( my $lin = $fh->getline ) {
627             if ( $lin =~ /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/ ) {
628             no strict;
629              
630             #warn "ver: $lin";
631             $ver = ( eval $lin )[0];
632             last;
633             }
634             }
635             $fh->close;
636             }
637             else {
638             if ( $self->mod_cpan_version ) {
639             $ver = $self->mod_cpan_version;
640             warn "Cannot use internal module data to gather the "
641             . "version; using cpan_version\n";
642             }
643             else {
644             die "Cannot use internal module data to gather the "
645             . "version; use --cpan or --version\n";
646             }
647             }
648             }
649              
650             $self->perlname($name);
651             $self->version($ver);
652              
653             $self->set_package_name;
654              
655             if ( defined($vfrom) ) {
656             $self->extract_desc("$dir/$vfrom");
657             $self->extract_basic_copyright("$dir/$vfrom");
658             }
659             }
660              
661             sub extract_desc {
662             my ( $self, $file ) = @_;
663              
664             my $bin = $self->control->binary_tie->Values(0);
665             my $desc = $bin->short_description;
666              
667             $desc and return;
668              
669             return unless -f $file;
670             my ( $parser, $modulename );
671             $parser = new DhMakePerl::PodParser;
672             $parser->set_names(qw(NAME DESCRIPTION DETAILS));
673             $parser->parse_from_file($file);
674             if ( $desc ) {
675              
676             # No-op - We already have it, probably from the command line
677              
678             }
679             elsif ( $self->meta->{abstract} ) {
680              
681             # Get it from META.yml
682             $desc = $self->meta->{abstract};
683              
684             }
685             elsif ( my $my_desc = $parser->get('NAME') ) {
686              
687             # Parse it, fix it, send it!
688             $my_desc =~ s/^\s*\S+\s+-\s+//s;
689             $my_desc =~ s/^\s+//s;
690             $my_desc =~ s/\s+$//s;
691             $my_desc =~ s/^([^\s])/ $1/mg;
692             $my_desc =~ s/\n.*$//s;
693             $desc = $my_desc;
694             }
695              
696             if ( defined($desc) ) {
697             # Replace linefeed (not followed by a space) in short description with
698             # spaces
699             $desc =~ s/\n(?=\S)/ /gs;
700             $desc =~ s/^\s+//; # strip leading spaces
701             }
702              
703             # have a fall-back for the short description
704             $desc ||= '(no short description found)';
705              
706             $bin->short_description($desc);
707              
708             my $long_desc;
709             unless ( $bin->long_description ) {
710             $long_desc
711             = $parser->get('DESCRIPTION')
712             || $parser->get('DETAILS')
713             || '';
714             ( $modulename = $self->perlname ) =~ s/-/::/g;
715             $long_desc =~ s/This module/$modulename/;
716             $long_desc =~ s/This library/$modulename/;
717              
718             local ($Text::Wrap::columns) = 78;
719             $long_desc = fill( "", "", $long_desc );
720             }
721              
722             if ( defined($long_desc) ) {
723             $long_desc =~ s/^[\s\n]+//s;
724             $long_desc =~ s/\s+$//s;
725             $long_desc =~ s/^\t/ /mg;
726             $long_desc =~ s/\r//g;
727             $long_desc = '(no description was found)' if $long_desc eq '';
728              
729             $bin->long_description(
730             "$long_desc\n\nThis description was automagically extracted from the module by dh-make-perl.\n"
731             );
732             }
733              
734             $parser->cleanup;
735             }
736              
737             sub check_for_xs {
738             my ($self) = @_;
739              
740             # we need the relative path here. Otherwise the check will give bogus
741             # results if the working dir matches the pattern
742             my $rel_path = substr( $File::Find::name, length( $self->main_dir ) );
743             ( $rel_path !~ m{/(?:examples?|samples|eg|t|docs|win32?|demos?)/} )
744             and
745             ( !$self->cfg->exclude or $rel_path !~ $self->cfg->exclude )
746             && /\.(xs|c|cpp|cxx)$/i
747             && do {
748             $self->control->binary_tie->Values(0)->Architecture('any');
749             };
750             }
751              
752             sub extract_basic_copyright {
753             my ( $self, $file ) = @_;
754              
755             for my $f ( map( $self->main_file($_), qw(LICENSE LICENCE COPYING) ) ) {
756             if ( -f $f ) {
757             my $fh = $self->_file_r($f);
758             $self->copyright( join( '', $fh->getlines ) );
759             }
760             }
761              
762             if ( defined($file) ) {
763             my ( $parser, $modulename );
764             $parser = new DhMakePerl::PodParser;
765             return unless -f $file;
766             $parser->set_names(qw(COPYRIGHT AUTHOR AUTHORS));
767             $parser->parse_from_file($file);
768              
769             $self->copyright( $parser->get('COPYRIGHT')
770             || $parser->get('LICENSE')
771             || $parser->get('COPYRIGHT & LICENSE') )
772             unless $self->copyright;
773              
774             if ( !$self->author ) {
775             if ( ref $self->meta->{author} ) {
776              
777             # Does the author information appear in META.yml?
778             $self->author( join( ', ', @{ $self->meta->{author} } ) );
779             }
780             else {
781              
782             # Get it from the POD - and clean up
783             # trailing/preceding spaces!
784             my $a = $parser->get('AUTHOR') || $parser->get('AUTHORS');
785             $a =~ s/^\s*(\S.*\S)\s*$/$1/gs if $a;
786             $self->author($a);
787             }
788             }
789              
790             $parser->cleanup;
791             }
792             }
793              
794             sub extract_docs {
795             my ( $self ) = @_;
796              
797             my $dir = $self->main_dir;
798              
799             $dir .= '/' unless $dir =~ m(/$);
800             find(
801             { preprocess => sub {
802             my $bn = basename $File::Find::dir;
803             return ()
804             if $bn eq '.svn-base'
805             or $bn eq '.svn'
806             or $bn eq '.git';
807              
808             return @_;
809             },
810             wanted => sub {
811             push(
812             @{ $self->docs },
813             substr( $File::Find::name, length($dir) )
814             )
815             if (
816             $File::Find::name ne $self->main_dir . '/README'
817             and /^\b(README|TODO|BUGS|NEWS|ANNOUNCE|CONTRIBUTING)\b/i
818             and !/\.(pod|pm)$/
819             and ( !$self->cfg->exclude
820             or $File::Find::name !~ $self->cfg->exclude )
821             and !/\.svn-base$/
822             and $File::Find::name
823             !~ m{debian/README\.(?:source|[Dd]ebian)}
824             );
825             },
826             },
827             $dir
828             );
829             }
830              
831             sub extract_examples {
832             my ( $self ) = @_;
833              
834             my $dir = $self->main_dir;
835              
836             $dir .= '/' unless $dir =~ m{/$};
837             find(
838             sub {
839             return if $_ eq '.'; # skip the directory itself
840             my $exampleguess = substr( $File::Find::name, length($dir) );
841             push( @{ $self->examples },
842             ( -d $exampleguess ? $exampleguess . '/*' : $exampleguess ) )
843             if ( /^(examples?|eg|samples?)$/i
844             and ( !$self->cfg->exclude or $File::Find::name !~ $self->cfg->exclude )
845             );
846             },
847             $dir
848             );
849             }
850              
851             sub read_rules {
852             my $self = shift;
853              
854             return if $self->rules;
855              
856             my $file = $self->debian_file('rules');
857              
858             $self->rules( Debian::Rules->new($file) );
859             }
860              
861             sub create_rules {
862             my ( $self ) = @_;
863              
864             my $file = $self->debian_file('rules');
865              
866             $self->rules( Debian::Rules->new($file) );
867              
868             if ( $self->rules->is_dhtiny ) {
869             print "$file already uses dh tiny rules\n"
870             if $self->cfg->verbose;
871             return;
872             }
873              
874             $self->backup_file($file);
875              
876             my $rulesname = 'rules.dh.tiny';
877              
878             for my $source (
879             catfile( $self->cfg->home_dir, $rulesname ),
880             catfile( $self->cfg->data_dir, $rulesname )
881             ) {
882             if ( -e $source ) {
883             print "Using rules: $source\n" if $self->cfg->verbose;
884             $self->rules->read($source);
885             last;
886             };
887             }
888             $self->rules->write;
889             chmod( 0755, $file ) or die "chmod($file): $!";
890             }
891              
892             sub create_compat {
893             my ( $self, $file ) = @_;
894              
895             my $fh = $self->_file_w($file);
896             $fh->print( $self->cfg->dh, "\n" );
897             $fh->close;
898             }
899              
900             sub update_file_list( $ % ) {
901             my ( $self, %p ) = @_;
902              
903             my $pkgname = $self->pkgname;
904              
905             while ( my ( $file, $new_content ) = each %p ) {
906             next unless @$new_content;
907             # pkgname.foo file
908             my $pkg_file = $self->debian_file("$pkgname.$file");
909             my %uniq_content;
910             my @existing_content;
911              
912             # if a package.foo exists read its values first
913             if ( -r $pkg_file ) {
914             my $fh = $self->_file_r($pkg_file);
915             @existing_content = $fh->getlines;
916             chomp(@existing_content);
917              
918             # make list of files for package.foo unique
919             $uniq_content{$_} = 1 for @existing_content;
920             }
921              
922             $uniq_content{$_} = 1 for @$new_content;
923              
924             # write package.foo file with unique entries
925             open F, '>', $pkg_file or die $!;
926             for ( @existing_content, @$new_content ) {
927              
928             # we have the unique hash
929             # we delete from it each printed line
930             # so if a line is not in the hash, this means we have already
931             # printed it
932             next unless exists $uniq_content{$_};
933              
934             delete $uniq_content{$_};
935             print F "$_\n";
936             }
937             close F;
938             }
939             }
940              
941             sub create_copyright {
942             my ( $self, $filename ) = @_;
943              
944             my ( $fh, %fields, @res, @incomplete, $year );
945             $fh = $self->_file_w($filename);
946              
947             # In case author string spawns more than one line, indent them all.
948             my $cprt_author = $self->author || '(information incomplete)';
949             $cprt_author =~ s/\n/\n /gs;
950             $cprt_author =~ s/^\s*$/ ./gm;
951              
952             push @res, 'Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/';
953              
954             # Header section
955             %fields = (
956             'Upstream-Name' => $self->perlname,
957             'Upstream-Contact' => $cprt_author,
958             'Source' => $self->upsurl
959             );
960             for my $key ( sort keys %fields ) {
961             my $full = "$key";
962             if ( $fields{$key} ) {
963             push @res, "$full: $fields{$key}";
964             }
965             else {
966             push @incomplete, "Could not get the information for $full";
967             }
968             }
969             push( @res,
970             "DISCLAIMER: This copyright info was automatically extracted ",
971             " from the perl module. It may not be accurate, so you better ",
972             " check the module sources in order to ensure the module for its ",
973             " inclusion in Debian or for general legal information. Please, ",
974             " if licensing information is incorrectly generated, file a bug ",
975             " on dh-make-perl.",
976             " NOTE: Don't forget to remove this disclaimer once you are happy",
977             " with this file." );
978             push @res, '';
979              
980             # Files section - We cannot "parse" the module's licensing
981             # information for anything besides general information.
982             push @res, 'Files: *';
983              
984             my $cprt_year;
985             if ( $self->dist_ini
986             and $self->dist_ini->{_}{copyright_year} )
987             {
988             $cprt_year = $self->dist_ini->{_}{copyright_year};
989             }
990             # Absence of author should have already been reported in the
991             # Header section
992             push @res,
993             "Copyright: " . ( $cprt_year ? "$cprt_year, " : '' ) . $cprt_author;
994              
995             # This is far from foolproof, but usually works with most
996             # boilerplate-generated modules.
997             #
998             # We go over the most common combinations only
999              
1000             my ( %texts, %licenses );
1001             %texts = (
1002             'Artistic' =>
1003             " This program is free software; you can redistribute it and/or modify\n"
1004             . " it under the terms of the Artistic License, which comes with Perl.\n"
1005             . " .\n"
1006             . " On Debian systems, the complete text of the Artistic License can be\n"
1007             . " found in `/usr/share/common-licenses/Artistic'.",
1008             'Artistic-2.0' => do {
1009             require Software::License::Artistic_2_0;
1010             my $artistic2 = Software::License::Artistic_2_0->new(
1011             { holder => 'noname', } );
1012             my $text = $artistic2->license;
1013             $text =~ s/\n$//s;
1014             $text =~ s/^\n/.\n/mg;
1015             $text =~ s/^/ /mg;
1016             $text;
1017             },
1018             'GPL-1+' =>
1019             " This program is free software; you can redistribute it and/or modify\n"
1020             . " it under the terms of the GNU General Public License as published by\n"
1021             . " the Free Software Foundation; either version 1, or (at your option)\n"
1022             . " any later version.\n"
1023             . " .\n"
1024             . " On Debian systems, the complete text of version 1 of the GNU General\n"
1025             . " Public License can be found in `/usr/share/common-licenses/GPL-1'.",
1026             'GPL-2' =>
1027             " This program is free software; you can redistribute it and/or modify\n"
1028             . " it under the terms of the GNU General Public License as published by\n"
1029             . " the Free Software Foundation; version 2 dated June, 1991.\n"
1030             . " .\n"
1031             . " On Debian systems, the complete text of version 2 of the GNU General\n"
1032             . " Public License can be found in `/usr/share/common-licenses/GPL-2'.",
1033             'GPL-2+' =>
1034             " This program is free software; you can redistribute it and/or modify\n"
1035             . " it under the terms of the GNU General Public License as published by\n"
1036             . " the Free Software Foundation; version 2 dated June, 1991, or (at your\n"
1037             . " option) any later version.\n"
1038             . " .\n"
1039             . " On Debian systems, the complete text of version 2 of the GNU General\n"
1040             . " Public License can be found in `/usr/share/common-licenses/GPL-2'.",
1041             'GPL-3' =>
1042             " This program is free software; you can redistribute it and/or modify\n"
1043             . " it under the terms of the GNU General Public License as published by\n"
1044             . " the Free Software Foundation; version 3 dated June, 2007.\n"
1045             . " .\n"
1046             . " On Debian systems, the complete text of version 3 of the GNU General\n"
1047             . " Public License can be found in `/usr/share/common-licenses/GPL-3'.",
1048             'GPL-3+' =>
1049             " This program is free software; you can redistribute it and/or modify\n"
1050             . " it under the terms of the GNU General Public License as published by\n"
1051             . " the Free Software Foundation; version 3 dated June, 2007, or (at your\n"
1052             . " option) any later version.\n"
1053             . " .\n"
1054             . " On Debian systems, the complete text of version 3 of the GNU General\n"
1055             . " Public License can be found in `/usr/share/common-licenses/GPL-3'.",
1056             'Apache-2.0' =>
1057             " Licensed under the Apache License, Version 2.0 (the \"License\");\n"
1058             . " you may not use this file except in compliance with the License.\n"
1059             . " You may obtain a copy of the License at\n"
1060             . " http://www.apache.org/licenses/LICENSE-2.0\n"
1061             . " Unless required by applicable law or agreed to in writing, software\n"
1062             . " distributed under the License is distributed on an \"AS IS\" BASIS,\n"
1063             . " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
1064             . " See the License for the specific language governing permissions and\n"
1065             . " limitations under the License.\n"
1066             . " .\n"
1067             . " On Debian systems, the complete text of the Apache License,\n"
1068             . " Version 2.0 can be found in `/usr/share/common-licenses/Apache-2.0'.",
1069             'unparsable' =>
1070             " No known license could be automatically determined for this module.\n"
1071             . " If this module conforms to a commonly used license, please report this\n"
1072             . " as a bug in dh-make-perl. In any case, please find the proper license\n"
1073             . " and fix this file!"
1074             );
1075              
1076             if ( $self->meta->{license} or $self->copyright ) {
1077             my $mangle_cprt;
1078              
1079             # Pre-mangle the copyright information for the common similar cases
1080             $mangle_cprt = $self->copyright || ''; # avoid warning
1081             $mangle_cprt =~ s/GENERAL PUBLIC LICENSE/GPL/g;
1082              
1083             # Of course, more licenses (i.e. LGPL, BSD-like, Public
1084             # Domain, etc.) could be added... Feel free to do so. Keep in
1085             # mind that many licenses are not meant to be used as
1086             # templates (i.e. you must add the author name and some
1087             # information within the licensing text as such).
1088             if ( $self->meta->{license} ) {
1089             foreach ( @{ $self->meta->{license} } ) {
1090             if (/apache_2_0/) { $licenses{'Apache-2.0'} = 1; next; }
1091             if (/artistic_1/) { $licenses{'Artistic'} = 1; next; }
1092             if (/artistic_2/) { $licenses{'Artistic-2.0'} = 1; next; }
1093              
1094             # EU::MM and M::B converts the 'gpl' without a version to gpl_1.
1095             # As GPL without a version means *any* GPL, I think it's safe to use GPL-1+ here
1096             if (/gpl_1/) { $licenses{'GPL-1+'} = 1; next; }
1097              
1098             if (/perl_5/) {
1099             $licenses{'GPL-1+'} = 1;
1100             $licenses{'Artistic'} = 1;
1101             next;
1102             }
1103             }
1104             }
1105             else {
1106             if ( $mangle_cprt =~ /terms\s*as\s*Perl\s*itself/is ) {
1107             $licenses{'GPL-1+'} = 1;
1108             $licenses{'Artistic'} = 1;
1109             }
1110              
1111             if ( $mangle_cprt =~ /[^L]GPL/ ) {
1112             if ( $mangle_cprt =~ /GPL.*version\s*1.*later\s+version/is ) {
1113             $licenses{'GPL-1+'} = 1;
1114             }
1115             elsif (
1116             $mangle_cprt =~ /GPL.*version\s*2.*later\s+version/is )
1117             {
1118             $licenses{'GPL-2+'} = 1;
1119             }
1120             elsif ( $mangle_cprt =~ /GPL.*version\s*2/is ) {
1121             $licenses{'GPL-2'} = 1;
1122             }
1123             elsif (
1124             $mangle_cprt =~ /GPL.*version\s*3.*later\s+version/is )
1125             {
1126             $licenses{'GPL-3+'} = 1;
1127             }
1128             elsif ( $mangle_cprt =~ /GPL.*version\s*3/is ) {
1129             $licenses{'GPL-3'} = 1;
1130             }
1131             }
1132              
1133             if ( $mangle_cprt =~ /Artistic\s*License\s*2\.0/is ) {
1134             $licenses{'Artistic-2.0'} = 1;
1135             }
1136             elsif ( $mangle_cprt =~ /Artistic\s*License/is ) {
1137             $licenses{'Artistic'} = 1;
1138             }
1139              
1140             if ( $mangle_cprt =~ /Apache\s*License.*2\.0/is ) {
1141             $licenses{'Apache-2.0'} = 1;
1142             }
1143              
1144             # Other licenses?
1145              
1146             if ( !keys(%licenses) ) {
1147             $licenses{unparsable} = 1;
1148             push( @incomplete,
1149             "Licensing information is present, but cannot be parsed"
1150             );
1151             }
1152             }
1153              
1154             push @res, "License: " . join( ' or ', sort keys %licenses );
1155              
1156             }
1157             else {
1158             push @res, "License: ";
1159             push @incomplete, 'No licensing information found';
1160             }
1161              
1162             # debian/* files information - We default to the module being
1163             # licensed as the super-set of the module and Perl itself.
1164             $licenses{'Artistic'} = $licenses{'GPL-1+'} = 1;
1165             $year = (localtime)[5] + 1900;
1166             push( @res, "", "Files: debian/*" );
1167             if ( $self->cfg->command eq 'refresh' ) {
1168             my @from_changelog
1169             = $self->copyright_from_changelog( $self->get_developer, $year );
1170             $from_changelog[0] = "Copyright:" . $from_changelog[0];
1171             push @res, @from_changelog;
1172             }
1173             else {
1174             push @res, "Copyright: $year, " . $self->get_developer;
1175             }
1176             push @res, "License: " . join( ' or ', sort keys %licenses );
1177              
1178             map { $texts{$_} && push( @res, '', "License: $_", $texts{$_} ) }
1179             sort keys %licenses;
1180              
1181             $fh->print( join( "\n", @res, '' ) );
1182             $fh->close;
1183              
1184             $self->_warn_incomplete_copyright( join( "\n", @incomplete ) )
1185             if @incomplete;
1186             }
1187              
1188             sub upsurl {
1189             my $self = shift;
1190             return sprintf( "https://metacpan.org/release/%s", $self->perlname );
1191             }
1192              
1193              
1194             my $ACTUAL_NAME_RE = '\pL[\s\pL\-\'\.]*\pL';
1195              
1196             # See http://www.faqs.org/rfcs/rfc2822.html
1197             # Section 3.4.1
1198             use Email::Address;
1199             my $EMAIL_RE = $Email::Address::addr_spec;
1200              
1201             my $EMAIL_CHANGES_RE = qr{
1202             ^ # beginining of line
1203             \s+\*\s # item marker
1204             Email\schange:\s # email change token
1205             ($ACTUAL_NAME_RE) # actual name
1206             \s+->\s+ # gap between name and email
1207             ($EMAIL_RE) # email address
1208             $ # end of line
1209             }xms;
1210              
1211             my $PERSON_PARSE_RE = qr{
1212             \A # beginining of string
1213             ($ACTUAL_NAME_RE) # actual name
1214             \s # gap
1215             \<$EMAIL_RE\> # logged email
1216             \z # end of string
1217             }xms;
1218              
1219             # This is what needs fixing.
1220             sub copyright_from_changelog {
1221             my ( $self, $firstmaint, $firstyear ) = @_;
1222             my %maintainers = ();
1223             @{ $maintainers{$firstmaint} } = ($firstyear);
1224             my $chglog = Parse::DebianChangelog->init(
1225             { infile => $self->debian_file('changelog') } );
1226             my %email_changes = ();
1227             foreach ( $chglog->data() ) {
1228             my $person = $_->Maintainer;
1229             my $date = $_->Date;
1230             my @date_pieces = split( " ", $date );
1231             my $year = $date_pieces[3];
1232             if (my %changes = ($_->Changes =~ m/$EMAIL_CHANGES_RE/xmsg)) {
1233             # This way round since we are going backward in time thru changelog
1234             foreach my $p (keys %changes) {
1235             $changes{$p} =~ s{[\s\n]+$}{}xms;
1236             }
1237             %email_changes = (
1238             %changes,
1239             %email_changes
1240             );
1241             }
1242             if (my ($name) = ($person =~ $PERSON_PARSE_RE)) {
1243             if (exists $email_changes{$name}) {
1244             $person = "$name <$email_changes{$name}>";
1245             }
1246             }
1247             if ( defined( $maintainers{$person} ) ) {
1248             push @{ $maintainers{$person} }, $year;
1249             @{ $maintainers{$person} } = sort( @{ $maintainers{$person} } );
1250             }
1251             else {
1252             @{ $maintainers{$person} } = ($year);
1253             }
1254             }
1255             my @strings;
1256             foreach my $maint_name ( keys %maintainers ) {
1257             my $str = " ";
1258             my %uniq = map { $_ => 0 } @{ $maintainers{$maint_name} };
1259             foreach ( sort keys %uniq ) {
1260             $str .= $_;
1261             $str .= ", ";
1262             }
1263             $str .= $maint_name;
1264             push @strings, $str;
1265             }
1266             @strings = sort @strings;
1267             return @strings;
1268             }
1269              
1270             sub _warn_incomplete_copyright {
1271             my $self = shift;
1272              
1273             print '*' x 10, '
1274             Copyright information incomplete!
1275              
1276             Upstream copyright information could not be automatically determined.
1277              
1278             If you are building this package for your personal use, you might disregard
1279             this information; however, if you intend to upload this package to Debian
1280             (or in general, if you plan on distributing it), you must look into the
1281             complete copyright information.
1282              
1283             The causes for this warning are:
1284             ', @_, "\n";
1285             }
1286              
1287             sub write_source_format {
1288             my ( $self, $path ) = @_;
1289              
1290             my ( $vol, $dir, $file ) = splitpath($path);
1291             $dir = catpath( $vol, $dir );
1292              
1293             if ( $self->cfg->source_format eq '1.0' ) {
1294             # this is the default, remove debian/source
1295             File::Path::rmtree($dir);
1296             }
1297             else {
1298             # make sure the directory exists
1299             File::Path::mkpath($dir) unless -d $dir;
1300              
1301             my $fh = $self->_file_w($path);
1302             $fh->print( $self->cfg->source_format, "\n" );
1303             $fh->close;
1304             }
1305             }
1306              
1307             sub module_build {
1308             my $self = shift;
1309              
1310             # dehbelper prefers Makefile.PL over Build.PL unless the former is a
1311             # Module::Build::Compat wrapper
1312             return 'Module-Build' if $self->makefile_pl_is_MBC;
1313              
1314             return 'MakeMaker' if -e $self->makefile_pl;
1315              
1316             return ( -f $self->main_file('Build.PL') ) ? "Module-Build" : "MakeMaker";
1317             }
1318              
1319             =item explained_dependency I<$reason>, I<$dependencies>, I<@dependencies>
1320              
1321             Adds the list of dependencies to I<$dependencies> and shows I<$reason> if in
1322             verbose mode.
1323              
1324             Used to both bump a dependency and tell the user why.
1325              
1326             I<$dependencies> is an instance of L class, and
1327             I<@dependencies> is a list of L instances or strings.
1328              
1329             The message printed looks like C<< $reason needs @dependencies >>.
1330              
1331             =cut
1332              
1333             sub explained_dependency {
1334             my ( $self, $reason, $deps, @to_add ) = @_;
1335              
1336             $deps->add(@to_add);
1337              
1338             warn sprintf( "%s needs %s\n", $reason, join( ', ', @to_add ) );
1339             }
1340              
1341             =item configure_cpan
1342              
1343             Configure CPAN module. It is safe to call this method more than once, it will
1344             do nothing if CPAN is already configured.
1345              
1346             =cut
1347              
1348             sub configure_cpan {
1349             my $self = shift;
1350              
1351             return if $CPAN::Config_loaded;
1352              
1353             my $save_cwd = getcwd();
1354              
1355             CPAN::HandleConfig->load( be_silent => not $self->cfg->verbose )
1356             if $self->cfg->network;
1357              
1358             unshift( @{ $CPAN::Config->{'urllist'} }, $self->cfg->cpan_mirror )
1359             if $self->cfg->cpan_mirror;
1360              
1361             $CPAN::Config->{'tar_verbosity'} = $self->cfg->verbose ? 'v' : '';
1362             $CPAN::Config->{'load_module_verbosity'}
1363             = $self->cfg->verbose ? 'verbose' : 'silent';
1364              
1365             $CPAN::Config->{build_requires_install_policy} = 'no';
1366             $CPAN::Config->{prerequisites_policy} = 'ignore';
1367              
1368             chdir $save_cwd;
1369             }
1370              
1371             =item discover_dependencies
1372              
1373             Just a wrapper around $self->control->discover_dependencies which provides the
1374             right parameters to it.
1375              
1376             Returns a list of missing modules.
1377              
1378             =cut
1379              
1380             sub discover_dependencies {
1381             my $self = shift;
1382              
1383             if ( my $apt_contents = $self->get_apt_contents ) {
1384              
1385             my $wnpp_query;
1386             $wnpp_query
1387             = Debian::WNPP::Query->new(
1388             { cache_file => catfile( $self->cfg->home_dir, 'wnpp.cache' ) } )
1389             if $self->cfg->network;
1390              
1391             # control->discover_dependencies needs configured CPAN
1392             $self->configure_cpan;
1393              
1394             return $self->control->discover_dependencies(
1395             { dir => $self->main_dir,
1396             verbose => $self->cfg->verbose,
1397             apt_contents => $self->apt_contents,
1398             require_deps => $self->cfg->requiredeps,
1399             wnpp_query => $wnpp_query,
1400             intrusive => $self->cfg->intrusive,
1401             }
1402             );
1403             }
1404             elsif (which('apt-file')) {
1405             warn "No APT contents can be loaded but apt-file seems installed.\n";
1406             warn "Please run 'apt-file update' as root.\n";
1407             warn "(If that doesn't help, please report a bug against dh-make-perl.)\n";
1408             warn "Dependencies not updated.\n";
1409              
1410             return ();
1411             }
1412             else {
1413             warn "No APT contents can be loaded.\n";
1414             warn "Please install 'apt-file' package (at least version 2.5.0) and\n";
1415             warn "run 'apt-file update' as root.\n";
1416             warn "Dependencies not updated.\n";
1417              
1418             return ();
1419             }
1420             }
1421              
1422             =item discover_utility_deps
1423              
1424             Determines whether certain versions of L and other packages are
1425             needed by the build process.
1426              
1427             The following special cases are detected:
1428              
1429             =over
1430              
1431             =item Module::Build::Tiny
1432              
1433             if L is present in the build-dependencies, debhelper
1434             dependency is raised to 9.20140227~.
1435              
1436             =item dh --with=quilt
1437              
1438             C needs quilt.
1439              
1440             =item quilt.make
1441              
1442             If F is included in F, a
1443             build-dependency on C is added.
1444              
1445             =item Module::Build
1446              
1447             The proper build-dependency in this case is
1448              
1449             perl
1450              
1451             The on perl without a version is set as Lenny has already 5.10 which
1452             includes first Module::Build.
1453              
1454             =back
1455              
1456             =cut
1457              
1458             sub discover_utility_deps {
1459             my ( $self, $control ) = @_;
1460              
1461             my $deps = $control->source->Build_Depends;
1462              
1463             # remove any existing dependencies
1464             $deps->remove( 'quilt', 'debhelper' );
1465              
1466             # start with the minimum
1467             my $debhelper_version = $self->cfg->dh;
1468              
1469             if ( $control->binary_tie->Values(0)->Architecture eq 'all' ) {
1470             $control->source->Build_Depends_Indep->add('perl');
1471             }
1472             else {
1473             $deps->add('perl');
1474             $debhelper_version = '9.20120312~' if $debhelper_version eq '9';
1475             }
1476             $deps->add( Debian::Dependency->new( 'debhelper', $debhelper_version ) );
1477              
1478             $self->explained_dependency( 'Module::Build::Tiny', $deps,
1479             'debhelper (>= 9.20140227~)' )
1480             if $deps->has('libmodule-build-tiny-perl');
1481              
1482             for ( @{ $self->rules->lines } ) {
1483             $self->explained_dependency(
1484             'dh --with=quilt',
1485             $deps, 'quilt',
1486             ) if /dh\s+.*--with[= ]quilt/;
1487              
1488             $self->explained_dependency(
1489             'dh --with=bash-completion',
1490             $deps,
1491             'bash-completion'
1492             ) if (/dh\s+.*--with[= ]bash[-_]completion/);
1493              
1494             $self->explained_dependency(
1495             'dh --with=perl_dbi',
1496             $deps,
1497             'libdbi-perl'
1498             ) if (/dh\s+.*--with[= ]perl[-_]dbi/);
1499              
1500             $self->explained_dependency( 'quilt.make', $deps, 'quilt' )
1501             if m{^include /usr/share/quilt/quilt.make};
1502              
1503             }
1504              
1505             # there are old packages that still build-depend on libmodule-build-perl
1506             # or perl (>= 5.10) | libmodule-build-perl.
1507             # Since M::B is part of perl 5.10, the build-dependency needs correction
1508             # and we replace this Build-Depends with simply perl, as lenny has the
1509             # required version.
1510             # Remove perl from Build-Depends-Indep as then perl will be already in
1511             # Build-Depends.
1512             if ( $self->module_build eq 'Module-Build' ) {
1513             $deps->remove('perl (>= 5.10) | libmodule-build-perl');
1514             $deps->remove('libmodule-build-perl');
1515             $control->source->Build_Depends_Indep->remove('perl');
1516             $self->explained_dependency( 'Module::Build', $deps,
1517             'perl' );
1518             }
1519              
1520             # some mandatory dependencies
1521             my $bin_deps = $control->binary_tie->Values(0)->Depends;
1522             $bin_deps += '${shlibs:Depends}'
1523             if $self->control->binary_tie->Values(0)->Architecture eq 'any';
1524             $bin_deps += '${misc:Depends}, ${perl:Depends}';
1525             }
1526              
1527             =item makefile_pl_is_MBC
1528              
1529             Checks if F is a compatibility wrapper around Build.PL provided by
1530             Module::Build::Compat.
1531              
1532             =cut
1533              
1534             sub makefile_pl_is_MBC
1535             {
1536             my $self = shift;
1537              
1538             my $mf = $self->makefile_pl;
1539              
1540             return undef unless -e $mf;
1541              
1542             my $fh = $self->_file_r($mf);
1543              
1544             while( defined( $_ = <$fh> ) ) {
1545             if ( /^[^#"]*Module::Build::Compat/ ) {
1546             return 1;
1547             }
1548             }
1549              
1550             return 0;
1551             }
1552              
1553             =item backup_file(file_name)
1554              
1555             Creates a backup copy of the specified file by adding C<.bak> to its name. If
1556             the backup already exists, it is overwritten.
1557              
1558             Does nothing unless the C option is set.
1559              
1560             =cut
1561              
1562             sub backup_file {
1563             my( $self, $file ) = @_;
1564              
1565             if ( $self->cfg->backups ) {
1566             warn "W: overwriting $file.bak\n"
1567             if -e "$file.bak" and $self->cfg->verbose;
1568             rename( $file, "$file.bak" );
1569             }
1570             }
1571              
1572             =item unquote(I)
1573              
1574             Runs its argument through L's C method and
1575             returns the extracted content with quotes removed. Dies if C
1576             can't find quoted string.
1577              
1578             =cut
1579              
1580             sub unquote {
1581             my ( $self, $input ) = @_;
1582              
1583             my $unquoted = (extract_quotelike($input))[5];
1584              
1585             die "Unable to find quoted string in [$input]" unless defined $unquoted;
1586              
1587             return $unquoted;
1588             }
1589              
1590             =item create_upstream_metadata
1591              
1592             Populates F with information from F.
1593              
1594             =cut
1595              
1596             sub create_upstream_metadata {
1597             my $self = shift;
1598             my $meta = $self->meta;
1599              
1600             return unless %$meta;
1601              
1602             require YAML::XS;
1603              
1604             my %upstream;
1605              
1606             $upstream{"Archive"} = 'CPAN';
1607             $upstream{"Name"} = $meta->{name};
1608             $upstream{"Contact"} = join( ', ', @{ $meta->{author} } );
1609             # $upstream{"Homepage"} = $meta->{resources}->{homepage};
1610             $upstream{"Bug-Database"} = $meta->{resources}->{bugtracker}->{web};
1611             $upstream{"Bug-Submit"} = $meta->{resources}->{bugtracker}->{mailto};
1612             $upstream{"Repository"} = $meta->{resources}->{repository}->{url};
1613             $upstream{"Repository-Browse"} = $meta->{resources}->{repository}->{web};
1614              
1615             foreach ( keys %upstream ) {
1616             delete $upstream{$_} unless defined $upstream{$_};
1617             }
1618              
1619             my $dir = File::Spec->catdir( $self->main_dir, 'debian', 'upstream' );
1620              
1621             mkdir($dir);
1622             YAML::XS::DumpFile( File::Spec->catfile( $dir, 'metadata' ), \%upstream );
1623             }
1624              
1625             =back
1626              
1627             =cut
1628              
1629             sub _file_r {
1630             my ( $self, $filename ) = @_;
1631              
1632             my $fh = IO::File->new( $filename, 'r' )
1633             or die "Cannot open $filename: $!\n";
1634             return $fh;
1635             }
1636              
1637             sub _file_w {
1638             my ( $self, $filename ) = @_;
1639              
1640             my $fh = IO::File->new( $filename, 'w' )
1641             or die "Cannot open $filename: $!\n";
1642             return $fh;
1643             }
1644              
1645             =head1 COPYRIGHT & LICENSE
1646              
1647             =over 4
1648              
1649             =item Copyright (C) 2000, 2001 Paolo Molaro
1650              
1651             =item Copyright (C) 2002, 2003, 2008 Ivan Kohler
1652              
1653             =item Copyright (C) 2003, 2004 Marc 'HE' Brockschmidt
1654              
1655             =item Copyright (C) 2005-2007 Gunnar Wolf
1656              
1657             =item Copyright (C) 2006 Frank Lichtenheld
1658              
1659             =item Copyright (C) 2007-2014 Gregor Herrmann
1660              
1661             =item Copyright (C) 2007,2008,2009,2010,2012,2013 Damyan Ivanov
1662              
1663             =item Copyright (C) 2008, Roberto C. Sanchez
1664              
1665             =item Copyright (C) 2009-2011, Salvatore Bonaccorso
1666              
1667             =item Copyright (C) 2011, Nicholas Bamber
1668              
1669             =back
1670              
1671             This program is free software; you can redistribute it and/or modify it under
1672             the terms of the GNU General Public License version 2 as published by the Free
1673             Software Foundation.
1674              
1675             This program is distributed in the hope that it will be useful, but WITHOUT ANY
1676             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
1677             PARTICULAR PURPOSE. See the GNU General Public License for more details.
1678              
1679             You should have received a copy of the GNU General Public License along with
1680             this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
1681             Street, Fifth Floor, Boston, MA 02110-1301 USA.
1682              
1683             =cut
1684              
1685             1;