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