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