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