This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update ExtUtils-Manifest to CPAN version 1.58
[perl5.git] / cpan / ExtUtils-Manifest / lib / ExtUtils / Manifest.pm
1 package ExtUtils::Manifest;
2
3 require Exporter;
4 use Config;
5 use File::Basename;
6 use File::Copy 'copy';
7 use File::Find;
8 use File::Spec;
9 use Carp;
10 use strict;
11
12 use vars qw($VERSION @ISA @EXPORT_OK 
13           $Is_MacOS $Is_VMS $Is_VMS_mode $Is_VMS_lc $Is_VMS_nodot
14           $Debug $Verbose $Quiet $MANIFEST $DEFAULT_MSKIP);
15
16 $VERSION = '1.58';
17 @ISA=('Exporter');
18 @EXPORT_OK = qw(mkmanifest
19                 manicheck  filecheck  fullcheck  skipcheck
20                 manifind   maniread   manicopy   maniadd
21                 maniskip
22                );
23
24 $Is_MacOS = $^O eq 'MacOS';
25 $Is_VMS   = $^O eq 'VMS';
26 $Is_VMS_mode = 0;
27 $Is_VMS_lc = 0;
28 $Is_VMS_nodot = 0;  # No dots in dir names or double dots in files
29
30 if ($Is_VMS) {
31     require VMS::Filespec if $Is_VMS;
32     my $vms_unix_rpt;
33     my $vms_efs;
34     my $vms_case;
35
36     $Is_VMS_mode = 1;
37     $Is_VMS_lc = 1;
38     $Is_VMS_nodot = 1;
39     if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
40         $vms_unix_rpt = VMS::Feature::current("filename_unix_report");
41         $vms_efs = VMS::Feature::current("efs_charset");
42         $vms_case = VMS::Feature::current("efs_case_preserve");
43     } else {
44         my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
45         my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || '';
46         my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
47         $vms_unix_rpt = $unix_rpt =~ /^[ET1]/i; 
48         $vms_efs = $efs_charset =~ /^[ET1]/i;
49         $vms_case = $efs_case =~ /^[ET1]/i;
50     }
51     $Is_VMS_lc = 0 if ($vms_case);
52     $Is_VMS_mode = 0 if ($vms_unix_rpt);
53     $Is_VMS_nodot = 0 if ($vms_efs);
54 }
55
56 $Debug   = $ENV{PERL_MM_MANIFEST_DEBUG} || 0;
57 $Verbose = defined $ENV{PERL_MM_MANIFEST_VERBOSE} ?
58                    $ENV{PERL_MM_MANIFEST_VERBOSE} : 1;
59 $Quiet = 0;
60 $MANIFEST = 'MANIFEST';
61
62 $DEFAULT_MSKIP = File::Spec->catfile( dirname(__FILE__), "$MANIFEST.SKIP" );
63
64
65 =head1 NAME
66
67 ExtUtils::Manifest - utilities to write and check a MANIFEST file
68
69 =head1 SYNOPSIS
70
71     use ExtUtils::Manifest qw(...funcs to import...);
72
73     mkmanifest();
74
75     my @missing_files    = manicheck;
76     my @skipped          = skipcheck;
77     my @extra_files      = filecheck;
78     my($missing, $extra) = fullcheck;
79
80     my $found    = manifind();
81
82     my $manifest = maniread();
83
84     manicopy($read,$target);
85
86     maniadd({$file => $comment, ...});
87
88
89 =head1 DESCRIPTION
90
91 =head2 Functions
92
93 ExtUtils::Manifest exports no functions by default.  The following are
94 exported on request
95
96 =over 4
97
98 =item mkmanifest
99
100     mkmanifest();
101
102 Writes all files in and below the current directory to your F<MANIFEST>.
103 It works similar to the result of the Unix command
104
105     find . > MANIFEST
106
107 All files that match any regular expression in a file F<MANIFEST.SKIP>
108 (if it exists) are ignored.
109
110 Any existing F<MANIFEST> file will be saved as F<MANIFEST.bak>.
111
112 =cut
113
114 sub _sort {
115     return sort { lc $a cmp lc $b } @_;
116 }
117
118 sub mkmanifest {
119     my $manimiss = 0;
120     my $read = (-r 'MANIFEST' && maniread()) or $manimiss++;
121     $read = {} if $manimiss;
122     local *M;
123     my $bakbase = $MANIFEST;
124     $bakbase =~ s/\./_/g if $Is_VMS_nodot; # avoid double dots
125     rename $MANIFEST, "$bakbase.bak" unless $manimiss;
126     open M, "> $MANIFEST" or die "Could not open $MANIFEST: $!";
127     my $skip = maniskip();
128     my $found = manifind();
129     my($key,$val,$file,%all);
130     %all = (%$found, %$read);
131     $all{$MANIFEST} = ($Is_VMS_mode ? "$MANIFEST\t\t" : '') .
132                      'This list of files'
133         if $manimiss; # add new MANIFEST to known file list
134     foreach $file (_sort keys %all) {
135         if ($skip->($file)) {
136             # Policy: only remove files if they're listed in MANIFEST.SKIP.
137             # Don't remove files just because they don't exist.
138             warn "Removed from $MANIFEST: $file\n" if $Verbose and exists $read->{$file};
139             next;
140         }
141         if ($Verbose){
142             warn "Added to $MANIFEST: $file\n" unless exists $read->{$file};
143         }
144         my $text = $all{$file};
145         $file = _unmacify($file);
146         my $tabs = (5 - (length($file)+1)/8);
147         $tabs = 1 if $tabs < 1;
148         $tabs = 0 unless $text;
149         if ($file =~ /\s/) {
150             $file =~ s/([\\'])/\\$1/g;
151             $file = "'$file'";
152         }
153         print M $file, "\t" x $tabs, $text, "\n";
154     }
155     close M;
156 }
157
158 # Geez, shouldn't this use File::Spec or File::Basename or something?  
159 # Why so careful about dependencies?
160 sub clean_up_filename {
161   my $filename = shift;
162   $filename =~ s|^\./||;
163   $filename =~ s/^:([^:]+)$/$1/ if $Is_MacOS;
164   return $filename;
165 }
166
167
168 =item manifind
169
170     my $found = manifind();
171
172 returns a hash reference. The keys of the hash are the files found
173 below the current directory.
174
175 =cut
176
177 sub manifind {
178     my $p = shift || {};
179     my $found = {};
180
181     my $wanted = sub {
182         my $name = clean_up_filename($File::Find::name);
183         warn "Debug: diskfile $name\n" if $Debug;
184         return if -d $_;
185
186         if( $Is_VMS_lc ) {
187             $name =~ s#(.*)\.$#\L$1#;
188             $name = uc($name) if $name =~ /^MANIFEST(\.SKIP)?$/i;
189         }
190         $found->{$name} = "";
191     };
192
193     # We have to use "$File::Find::dir/$_" in preprocess, because 
194     # $File::Find::name is unavailable.
195     # Also, it's okay to use / here, because MANIFEST files use Unix-style 
196     # paths.
197     find({wanted => $wanted},
198          $Is_MacOS ? ":" : ".");
199
200     return $found;
201 }
202
203
204 =item manicheck
205
206     my @missing_files = manicheck();
207
208 checks if all the files within a C<MANIFEST> in the current directory
209 really do exist. If C<MANIFEST> and the tree below the current
210 directory are in sync it silently returns an empty list.
211 Otherwise it returns a list of files which are listed in the
212 C<MANIFEST> but missing from the directory, and by default also
213 outputs these names to STDERR.
214
215 =cut
216
217 sub manicheck {
218     return _check_files();
219 }
220
221
222 =item filecheck
223
224     my @extra_files = filecheck();
225
226 finds files below the current directory that are not mentioned in the
227 C<MANIFEST> file. An optional file C<MANIFEST.SKIP> will be
228 consulted. Any file matching a regular expression in such a file will
229 not be reported as missing in the C<MANIFEST> file. The list of any
230 extraneous files found is returned, and by default also reported to
231 STDERR.
232
233 =cut
234
235 sub filecheck {
236     return _check_manifest();
237 }
238
239
240 =item fullcheck
241
242     my($missing, $extra) = fullcheck();
243
244 does both a manicheck() and a filecheck(), returning then as two array
245 refs.
246
247 =cut
248
249 sub fullcheck {
250     return [_check_files()], [_check_manifest()];
251 }
252
253
254 =item skipcheck
255
256     my @skipped = skipcheck();
257
258 lists all the files that are skipped due to your C<MANIFEST.SKIP>
259 file.
260
261 =cut
262
263 sub skipcheck {
264     my($p) = @_;
265     my $found = manifind();
266     my $matches = maniskip();
267
268     my @skipped = ();
269     foreach my $file (_sort keys %$found){
270         if (&$matches($file)){
271             warn "Skipping $file\n" unless $Quiet;
272             push @skipped, $file;
273             next;
274         }
275     }
276
277     return @skipped;
278 }
279
280
281 sub _check_files {
282     my $p = shift;
283     my $dosnames=(defined(&Dos::UseLFN) && Dos::UseLFN()==0);
284     my $read = maniread() || {};
285     my $found = manifind($p);
286
287     my(@missfile) = ();
288     foreach my $file (_sort keys %$read){
289         warn "Debug: manicheck checking from $MANIFEST $file\n" if $Debug;
290         if ($dosnames){
291             $file = lc $file;
292             $file =~ s=(\.(\w|-)+)=substr ($1,0,4)=ge;
293             $file =~ s=((\w|-)+)=substr ($1,0,8)=ge;
294         }
295         unless ( exists $found->{$file} ) {
296             warn "No such file: $file\n" unless $Quiet;
297             push @missfile, $file;
298         }
299     }
300
301     return @missfile;
302 }
303
304
305 sub _check_manifest {
306     my($p) = @_;
307     my $read = maniread() || {};
308     my $found = manifind($p);
309     my $skip  = maniskip();
310
311     my @missentry = ();
312     foreach my $file (_sort keys %$found){
313         next if $skip->($file);
314         warn "Debug: manicheck checking from disk $file\n" if $Debug;
315         unless ( exists $read->{$file} ) {
316             my $canon = $Is_MacOS ? "\t" . _unmacify($file) : '';
317             warn "Not in $MANIFEST: $file$canon\n" unless $Quiet;
318             push @missentry, $file;
319         }
320     }
321
322     return @missentry;
323 }
324
325
326 =item maniread
327
328     my $manifest = maniread();
329     my $manifest = maniread($manifest_file);
330
331 reads a named C<MANIFEST> file (defaults to C<MANIFEST> in the current
332 directory) and returns a HASH reference with files being the keys and
333 comments being the values of the HASH.  Blank lines and lines which
334 start with C<#> in the C<MANIFEST> file are discarded.
335
336 =cut
337
338 sub maniread {
339     my ($mfile) = @_;
340     $mfile ||= $MANIFEST;
341     my $read = {};
342     local *M;
343     unless (open M, "< $mfile"){
344         warn "Problem opening $mfile: $!";
345         return $read;
346     }
347     local $_;
348     while (<M>){
349         chomp;
350         next if /^\s*#/;
351
352         my($file, $comment);
353
354         # filename may contain spaces if enclosed in ''
355         # (in which case, \\ and \' are escapes)
356         if (($file, $comment) = /^'(\\[\\']|.+)+'\s*(.*)/) {
357             $file =~ s/\\([\\'])/$1/g;
358         }
359         else {
360             ($file, $comment) = /^(\S+)\s*(.*)/;
361         }
362         next unless $file;
363
364         if ($Is_MacOS) {
365             $file = _macify($file);
366             $file =~ s/\\([0-3][0-7][0-7])/sprintf("%c", oct($1))/ge;
367         }
368         elsif ($Is_VMS_mode) {
369             require File::Basename;
370             my($base,$dir) = File::Basename::fileparse($file);
371             # Resolve illegal file specifications in the same way as tar
372             if ($Is_VMS_nodot) {
373                 $dir =~ tr/./_/;
374                 my(@pieces) = split(/\./,$base);
375                 if (@pieces > 2)
376                     { $base = shift(@pieces) . '.' . join('_',@pieces); }
377                 my $okfile = "$dir$base";
378                 warn "Debug: Illegal name $file changed to $okfile\n" if $Debug;
379                 $file = $okfile;
380             } 
381             $file = lc($file)
382                 unless $Is_VMS_lc &&($file =~ /^MANIFEST(\.SKIP)?$/);
383         }
384
385         $read->{$file} = $comment;
386     }
387     close M;
388     $read;
389 }
390
391 =item maniskip
392
393     my $skipchk = maniskip();
394     my $skipchk = maniskip($manifest_skip_file);
395
396     if ($skipchk->($file)) { .. }
397
398 reads a named C<MANIFEST.SKIP> file (defaults to C<MANIFEST.SKIP> in
399 the current directory) and returns a CODE reference that tests whether
400 a given filename should be skipped.
401
402 =cut
403
404 # returns an anonymous sub that decides if an argument matches
405 sub maniskip {
406     my @skip ;
407     my $mfile = shift || "$MANIFEST.SKIP";
408     _check_mskip_directives($mfile) if -f $mfile;
409     local(*M, $_);
410     open M, "< $mfile" or open M, "< $DEFAULT_MSKIP" or return sub {0};
411     while (<M>){
412       chomp;
413       s/\r//;
414       $_ =~ qr{^\s*(?:(?:'([^\\']*(?:\\.[^\\']*)*)')|([^#\s]\S*))?(?:(?:\s*)|(?:\s+(.*?)\s*))$};
415       #my $comment = $3;
416       my $filename = $2;
417       if ( defined($1) ) { 
418         $filename = $1; 
419         $filename =~ s/\\(['\\])/$1/g;
420       }
421       next if (not defined($filename) or not $filename);
422       push @skip, _macify($filename);
423     }
424     close M;
425     return sub {0} unless (scalar @skip > 0);
426
427     my $opts = $Is_VMS_mode ? '(?i)' : '';
428
429     # Make sure each entry is isolated in its own parentheses, in case
430     # any of them contain alternations
431     my $regex = join '|', map "(?:$_)", @skip;
432
433     return sub { $_[0] =~ qr{$opts$regex} };
434 }
435
436 # checks for the special directives
437 #   #!include_default
438 #   #!include /path/to/some/manifest.skip
439 # in a custom MANIFEST.SKIP for, for including
440 # the content of, respectively, the default MANIFEST.SKIP
441 # and an external manifest.skip file
442 sub _check_mskip_directives {
443     my $mfile = shift;
444     local (*M, $_);
445     my @lines = ();
446     my $flag = 0;
447     unless (open M, "< $mfile") {
448         warn "Problem opening $mfile: $!";
449         return;
450     }
451     while (<M>) {
452         if (/^#!include_default\s*$/) {
453             if (my @default = _include_mskip_file()) {
454                 push @lines, @default;
455                 warn "Debug: Including default MANIFEST.SKIP\n" if $Debug;
456                 $flag++;
457             }
458             next;
459         }
460         if (/^#!include\s+(.*)\s*$/) {
461             my $external_file = $1;
462             if (my @external = _include_mskip_file($external_file)) {
463                 push @lines, @external;
464                 warn "Debug: Including external $external_file\n" if $Debug;
465                 $flag++;
466             }
467             next;
468         }
469         push @lines, $_;
470     }
471     close M;
472     return unless $flag;
473     my $bakbase = $mfile;
474     $bakbase =~ s/\./_/g if $Is_VMS_nodot;  # avoid double dots
475     rename $mfile, "$bakbase.bak";
476     warn "Debug: Saving original $mfile as $bakbase.bak\n" if $Debug;
477     unless (open M, "> $mfile") {
478         warn "Problem opening $mfile: $!";
479         return;
480     }
481     print M $_ for (@lines);
482     close M;
483     return;
484 }
485
486 # returns an array containing the lines of an external
487 # manifest.skip file, if given, or $DEFAULT_MSKIP
488 sub _include_mskip_file {
489     my $mskip = shift || $DEFAULT_MSKIP;
490     unless (-f $mskip) {
491         warn qq{Included file "$mskip" not found - skipping};
492         return;
493     }
494     local (*M, $_);
495     unless (open M, "< $mskip") {
496         warn "Problem opening $mskip: $!";
497         return;
498     }
499     my @lines = ();
500     push @lines, "\n#!start included $mskip\n";
501     push @lines, $_ while <M>;
502     close M;
503     push @lines, "#!end included $mskip\n\n";
504     return @lines;
505 }
506
507 =item manicopy
508
509     manicopy(\%src, $dest_dir);
510     manicopy(\%src, $dest_dir, $how);
511
512 Copies the files that are the keys in %src to the $dest_dir.  %src is
513 typically returned by the maniread() function.
514
515     manicopy( maniread(), $dest_dir );
516
517 This function is useful for producing a directory tree identical to the 
518 intended distribution tree. 
519
520 $how can be used to specify a different methods of "copying".  Valid
521 values are C<cp>, which actually copies the files, C<ln> which creates
522 hard links, and C<best> which mostly links the files but copies any
523 symbolic link to make a tree without any symbolic link.  C<cp> is the 
524 default.
525
526 =cut
527
528 sub manicopy {
529     my($read,$target,$how)=@_;
530     croak "manicopy() called without target argument" unless defined $target;
531     $how ||= 'cp';
532     require File::Path;
533     require File::Basename;
534
535     $target = VMS::Filespec::unixify($target) if $Is_VMS_mode;
536     File::Path::mkpath([ $target ],! $Quiet,$Is_VMS ? undef : 0755);
537     foreach my $file (keys %$read){
538         if ($Is_MacOS) {
539             if ($file =~ m!:!) { 
540                 my $dir = _maccat($target, $file);
541                 $dir =~ s/[^:]+$//;
542                 File::Path::mkpath($dir,1,0755);
543             }
544             cp_if_diff($file, _maccat($target, $file), $how);
545         } else {
546             $file = VMS::Filespec::unixify($file) if $Is_VMS_mode;
547             if ($file =~ m!/!) { # Ilya, that hurts, I fear, or maybe not?
548                 my $dir = File::Basename::dirname($file);
549                 $dir = VMS::Filespec::unixify($dir) if $Is_VMS_mode;
550                 File::Path::mkpath(["$target/$dir"],! $Quiet,$Is_VMS ? undef : 0755);
551             }
552             cp_if_diff($file, "$target/$file", $how);
553         }
554     }
555 }
556
557 sub cp_if_diff {
558     my($from, $to, $how)=@_;
559     if (! -f $from) {
560         carp "$from not found";
561         return;
562     }
563     my($diff) = 0;
564     local(*F,*T);
565     open(F,"< $from\0") or die "Can't read $from: $!\n";
566     if (open(T,"< $to\0")) {
567         local $_;
568         while (<F>) { $diff++,last if $_ ne <T>; }
569         $diff++ unless eof(T);
570         close T;
571     }
572     else { $diff++; }
573     close F;
574     if ($diff) {
575         if (-e $to) {
576             unlink($to) or confess "unlink $to: $!";
577         }
578         STRICT_SWITCH: {
579             best($from,$to), last STRICT_SWITCH if $how eq 'best';
580             cp($from,$to), last STRICT_SWITCH if $how eq 'cp';
581             ln($from,$to), last STRICT_SWITCH if $how eq 'ln';
582             croak("ExtUtils::Manifest::cp_if_diff " .
583                   "called with illegal how argument [$how]. " .
584                   "Legal values are 'best', 'cp', and 'ln'.");
585         }
586     }
587 }
588
589 sub cp {
590     my ($srcFile, $dstFile) = @_;
591     my ($access,$mod) = (stat $srcFile)[8,9];
592
593     copy($srcFile,$dstFile);
594     utime $access, $mod + ($Is_VMS ? 1 : 0), $dstFile;
595     _manicopy_chmod($srcFile, $dstFile);
596 }
597
598
599 sub ln {
600     my ($srcFile, $dstFile) = @_;
601     # Fix-me - VMS can support links.
602     return &cp if $Is_VMS or ($^O eq 'MSWin32' and Win32::IsWin95());
603     link($srcFile, $dstFile);
604
605     unless( _manicopy_chmod($srcFile, $dstFile) ) {
606         unlink $dstFile;
607         return;
608     }
609     1;
610 }
611
612 # 1) Strip off all group and world permissions.
613 # 2) Let everyone read it.
614 # 3) If the owner can execute it, everyone can.
615 sub _manicopy_chmod {
616     my($srcFile, $dstFile) = @_;
617
618     my $perm = 0444 | (stat $srcFile)[2] & 0700;
619     chmod( $perm | ( $perm & 0100 ? 0111 : 0 ), $dstFile );
620 }
621
622 # Files that are often modified in the distdir.  Don't hard link them.
623 my @Exceptions = qw(MANIFEST META.yml SIGNATURE);
624 sub best {
625     my ($srcFile, $dstFile) = @_;
626
627     my $is_exception = grep $srcFile =~ /$_/, @Exceptions;
628     if ($is_exception or !$Config{d_link} or -l $srcFile) {
629         cp($srcFile, $dstFile);
630     } else {
631         ln($srcFile, $dstFile) or cp($srcFile, $dstFile);
632     }
633 }
634
635 sub _macify {
636     my($file) = @_;
637
638     return $file unless $Is_MacOS;
639
640     $file =~ s|^\./||;
641     if ($file =~ m|/|) {
642         $file =~ s|/+|:|g;
643         $file = ":$file";
644     }
645
646     $file;
647 }
648
649 sub _maccat {
650     my($f1, $f2) = @_;
651
652     return "$f1/$f2" unless $Is_MacOS;
653
654     $f1 .= ":$f2";
655     $f1 =~ s/([^:]:):/$1/g;
656     return $f1;
657 }
658
659 sub _unmacify {
660     my($file) = @_;
661
662     return $file unless $Is_MacOS;
663
664     $file =~ s|^:||;
665     $file =~ s|([/ \n])|sprintf("\\%03o", unpack("c", $1))|ge;
666     $file =~ y|:|/|;
667
668     $file;
669 }
670
671
672 =item maniadd
673
674   maniadd({ $file => $comment, ...});
675
676 Adds an entry to an existing F<MANIFEST> unless its already there.
677
678 $file will be normalized (ie. Unixified).  B<UNIMPLEMENTED>
679
680 =cut
681
682 sub maniadd {
683     my($additions) = shift;
684
685     _normalize($additions);
686     _fix_manifest($MANIFEST);
687
688     my $manifest = maniread();
689     my @needed = grep { !exists $manifest->{$_} } keys %$additions;
690     return 1 unless @needed;
691
692     open(MANIFEST, ">>$MANIFEST") or 
693       die "maniadd() could not open $MANIFEST: $!";
694
695     foreach my $file (_sort @needed) {
696         my $comment = $additions->{$file} || '';
697         if ($file =~ /\s/) {
698             $file =~ s/([\\'])/\\$1/g;
699             $file = "'$file'";
700         }
701         printf MANIFEST "%-40s %s\n", $file, $comment;
702     }
703     close MANIFEST or die "Error closing $MANIFEST: $!";
704
705     return 1;
706 }
707
708
709 # Sometimes MANIFESTs are missing a trailing newline.  Fix this.
710 sub _fix_manifest {
711     my $manifest_file = shift;
712
713     open MANIFEST, $MANIFEST or die "Could not open $MANIFEST: $!";
714
715     # Yes, we should be using seek(), but I'd like to avoid loading POSIX
716     # to get SEEK_*
717     my @manifest = <MANIFEST>;
718     close MANIFEST;
719
720     unless( $manifest[-1] =~ /\n\z/ ) {
721         open MANIFEST, ">>$MANIFEST" or die "Could not open $MANIFEST: $!";
722         print MANIFEST "\n";
723         close MANIFEST;
724     }
725 }
726
727
728 # UNIMPLEMENTED
729 sub _normalize {
730     return;
731 }
732
733
734 =back
735
736 =head2 MANIFEST
737
738 A list of files in the distribution, one file per line.  The MANIFEST
739 always uses Unix filepath conventions even if you're not on Unix.  This
740 means F<foo/bar> style not F<foo\bar>.
741
742 Anything between white space and an end of line within a C<MANIFEST>
743 file is considered to be a comment.  Any line beginning with # is also
744 a comment. Beginning with ExtUtils::Manifest 1.52, a filename may
745 contain whitespace characters if it is enclosed in single quotes; single
746 quotes or backslashes in that filename must be backslash-escaped.
747
748     # this a comment
749     some/file
750     some/other/file            comment about some/file
751     'some/third file'          comment
752
753
754 =head2 MANIFEST.SKIP
755
756 The file MANIFEST.SKIP may contain regular expressions of files that
757 should be ignored by mkmanifest() and filecheck(). The regular
758 expressions should appear one on each line. Blank lines and lines
759 which start with C<#> are skipped.  Use C<\#> if you need a regular
760 expression to start with a C<#>.
761
762 For example:
763
764     # Version control files and dirs.
765     \bRCS\b
766     \bCVS\b
767     ,v$
768     \B\.svn\b
769
770     # Makemaker generated files and dirs.
771     ^MANIFEST\.
772     ^Makefile$
773     ^blib/
774     ^MakeMaker-\d
775
776     # Temp, old and emacs backup files.
777     ~$
778     \.old$
779     ^#.*#$
780     ^\.#
781
782 If no MANIFEST.SKIP file is found, a default set of skips will be
783 used, similar to the example above.  If you want nothing skipped,
784 simply make an empty MANIFEST.SKIP file.
785
786 In one's own MANIFEST.SKIP file, certain directives
787 can be used to include the contents of other MANIFEST.SKIP
788 files. At present two such directives are recognized.
789
790 =over 4
791
792 =item #!include_default
793
794 This inserts the contents of the default MANIFEST.SKIP file
795
796 =item #!include /Path/to/another/manifest.skip
797
798 This inserts the contents of the specified external file
799
800 =back
801
802 The included contents will be inserted into the MANIFEST.SKIP
803 file in between I<#!start included /path/to/manifest.skip>
804 and I<#!end included /path/to/manifest.skip> markers.
805 The original MANIFEST.SKIP is saved as MANIFEST.SKIP.bak.
806
807 =head2 EXPORT_OK
808
809 C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
810 C<&maniread>, and C<&manicopy> are exportable.
811
812 =head2 GLOBAL VARIABLES
813
814 C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
815 results in both a different C<MANIFEST> and a different
816 C<MANIFEST.SKIP> file. This is useful if you want to maintain
817 different distributions for different audiences (say a user version
818 and a developer version including RCS).
819
820 C<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
821 all functions act silently.
822
823 C<$ExtUtils::Manifest::Debug> defaults to 0.  If set to a true value,
824 or if PERL_MM_MANIFEST_DEBUG is true, debugging output will be
825 produced.
826
827 =head1 DIAGNOSTICS
828
829 All diagnostic output is sent to C<STDERR>.
830
831 =over 4
832
833 =item C<Not in MANIFEST:> I<file>
834
835 is reported if a file is found which is not in C<MANIFEST>.
836
837 =item C<Skipping> I<file>
838
839 is reported if a file is skipped due to an entry in C<MANIFEST.SKIP>.
840
841 =item C<No such file:> I<file>
842
843 is reported if a file mentioned in a C<MANIFEST> file does not
844 exist.
845
846 =item C<MANIFEST:> I<$!>
847
848 is reported if C<MANIFEST> could not be opened.
849
850 =item C<Added to MANIFEST:> I<file>
851
852 is reported by mkmanifest() if $Verbose is set and a file is added
853 to MANIFEST. $Verbose is set to 1 by default.
854
855 =back
856
857 =head1 ENVIRONMENT
858
859 =over 4
860
861 =item B<PERL_MM_MANIFEST_DEBUG>
862
863 Turns on debugging
864
865 =back
866
867 =head1 SEE ALSO
868
869 L<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
870
871 =head1 AUTHOR
872
873 Andreas Koenig C<andreas.koenig@anima.de>
874
875 Maintained by Michael G Schwern C<schwern@pobox.com> within the
876 ExtUtils-MakeMaker package and, as a separate CPAN package, by
877 Randy Kobes C<r.kobes@uwinnipeg.ca>.
878
879 =cut
880
881 1;