This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Clean up MANIFEST before creating a new one.
[perl5.git] / dist / 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.59';
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 # Make sure this MANIFEST is consistently written with native
710 # newlines and has a terminal newline.
711 sub _fix_manifest {
712     my $manifest_file = shift;
713
714     open MANIFEST, $MANIFEST or die "Could not open $MANIFEST: $!";
715     local $/;
716     my @manifest = split /(\015\012|\012|\015)/, <MANIFEST>, -1;
717     close MANIFEST;
718     my $must_rewrite = "";
719     if ($manifest[-1] eq ""){
720         # sane case: last line had a terminal newline
721         pop @manifest;
722         for (my $i=1; $i<=$#manifest; $i+=2) {
723             unless ($manifest[$i] eq "\n") {
724                 $must_rewrite = "not a newline at pos $i";
725                 last;
726             }
727         }
728     } else {
729         $must_rewrite = "last line without newline";
730     }
731
732     if ( $must_rewrite ) {
733         1 while unlink $MANIFEST; # avoid multiple versions on VMS
734         open MANIFEST, ">", $MANIFEST or die "(must_rewrite=$must_rewrite) Could not open >$MANIFEST: $!";
735         for (my $i=0; $i<=$#manifest; $i+=2) {
736             print MANIFEST "$manifest[$i]\n";
737         }
738         close MANIFEST or die "could not write $MANIFEST: $!";
739     }
740 }
741
742
743 # UNIMPLEMENTED
744 sub _normalize {
745     return;
746 }
747
748
749 =back
750
751 =head2 MANIFEST
752
753 A list of files in the distribution, one file per line.  The MANIFEST
754 always uses Unix filepath conventions even if you're not on Unix.  This
755 means F<foo/bar> style not F<foo\bar>.
756
757 Anything between white space and an end of line within a C<MANIFEST>
758 file is considered to be a comment.  Any line beginning with # is also
759 a comment. Beginning with ExtUtils::Manifest 1.52, a filename may
760 contain whitespace characters if it is enclosed in single quotes; single
761 quotes or backslashes in that filename must be backslash-escaped.
762
763     # this a comment
764     some/file
765     some/other/file            comment about some/file
766     'some/third file'          comment
767
768
769 =head2 MANIFEST.SKIP
770
771 The file MANIFEST.SKIP may contain regular expressions of files that
772 should be ignored by mkmanifest() and filecheck(). The regular
773 expressions should appear one on each line. Blank lines and lines
774 which start with C<#> are skipped.  Use C<\#> if you need a regular
775 expression to start with a C<#>.
776
777 For example:
778
779     # Version control files and dirs.
780     \bRCS\b
781     \bCVS\b
782     ,v$
783     \B\.svn\b
784
785     # Makemaker generated files and dirs.
786     ^MANIFEST\.
787     ^Makefile$
788     ^blib/
789     ^MakeMaker-\d
790
791     # Temp, old and emacs backup files.
792     ~$
793     \.old$
794     ^#.*#$
795     ^\.#
796
797 If no MANIFEST.SKIP file is found, a default set of skips will be
798 used, similar to the example above.  If you want nothing skipped,
799 simply make an empty MANIFEST.SKIP file.
800
801 In one's own MANIFEST.SKIP file, certain directives
802 can be used to include the contents of other MANIFEST.SKIP
803 files. At present two such directives are recognized.
804
805 =over 4
806
807 =item #!include_default
808
809 This inserts the contents of the default MANIFEST.SKIP file
810
811 =item #!include /Path/to/another/manifest.skip
812
813 This inserts the contents of the specified external file
814
815 =back
816
817 The included contents will be inserted into the MANIFEST.SKIP
818 file in between I<#!start included /path/to/manifest.skip>
819 and I<#!end included /path/to/manifest.skip> markers.
820 The original MANIFEST.SKIP is saved as MANIFEST.SKIP.bak.
821
822 =head2 EXPORT_OK
823
824 C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
825 C<&maniread>, and C<&manicopy> are exportable.
826
827 =head2 GLOBAL VARIABLES
828
829 C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
830 results in both a different C<MANIFEST> and a different
831 C<MANIFEST.SKIP> file. This is useful if you want to maintain
832 different distributions for different audiences (say a user version
833 and a developer version including RCS).
834
835 C<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
836 all functions act silently.
837
838 C<$ExtUtils::Manifest::Debug> defaults to 0.  If set to a true value,
839 or if PERL_MM_MANIFEST_DEBUG is true, debugging output will be
840 produced.
841
842 =head1 DIAGNOSTICS
843
844 All diagnostic output is sent to C<STDERR>.
845
846 =over 4
847
848 =item C<Not in MANIFEST:> I<file>
849
850 is reported if a file is found which is not in C<MANIFEST>.
851
852 =item C<Skipping> I<file>
853
854 is reported if a file is skipped due to an entry in C<MANIFEST.SKIP>.
855
856 =item C<No such file:> I<file>
857
858 is reported if a file mentioned in a C<MANIFEST> file does not
859 exist.
860
861 =item C<MANIFEST:> I<$!>
862
863 is reported if C<MANIFEST> could not be opened.
864
865 =item C<Added to MANIFEST:> I<file>
866
867 is reported by mkmanifest() if $Verbose is set and a file is added
868 to MANIFEST. $Verbose is set to 1 by default.
869
870 =back
871
872 =head1 ENVIRONMENT
873
874 =over 4
875
876 =item B<PERL_MM_MANIFEST_DEBUG>
877
878 Turns on debugging
879
880 =back
881
882 =head1 SEE ALSO
883
884 L<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
885
886 =head1 AUTHOR
887
888 Andreas Koenig C<andreas.koenig@anima.de>
889
890 Maintained by Michael G Schwern C<schwern@pobox.com> within the
891 ExtUtils-MakeMaker package and, as a separate CPAN package, by
892 Randy Kobes C<r.kobes@uwinnipeg.ca>.
893
894 =cut
895
896 1;