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