xref: /openbsd-src/gnu/usr.bin/perl/cpan/ExtUtils-Manifest/lib/ExtUtils/Manifest.pm (revision 898184e3e61f9129feb5978fad5a8c6865f00b92)
1package ExtUtils::Manifest;
2
3require Exporter;
4use Config;
5use File::Basename;
6use File::Copy 'copy';
7use File::Find;
8use File::Spec;
9use Carp;
10use strict;
11
12use 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.57';
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
30if ($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
67ExtUtils::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
93ExtUtils::Manifest exports no functions by default.  The following are
94exported on request
95
96=over 4
97
98=item mkmanifest
99
100    mkmanifest();
101
102Writes all files in and below the current directory to your F<MANIFEST>.
103It works similar to the result of the Unix command
104
105    find . > MANIFEST
106
107All files that match any regular expression in a file F<MANIFEST.SKIP>
108(if it exists) are ignored.
109
110Any existing F<MANIFEST> file will be saved as F<MANIFEST.bak>.
111
112=cut
113
114sub _sort {
115    return sort { lc $a cmp lc $b } @_;
116}
117
118sub 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?
160sub 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
172returns a hash reference. The keys of the hash are the files found
173below the current directory.
174
175=cut
176
177sub 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
208checks if all the files within a C<MANIFEST> in the current directory
209really do exist. If C<MANIFEST> and the tree below the current
210directory are in sync it silently returns an empty list.
211Otherwise it returns a list of files which are listed in the
212C<MANIFEST> but missing from the directory, and by default also
213outputs these names to STDERR.
214
215=cut
216
217sub manicheck {
218    return _check_files();
219}
220
221
222=item filecheck
223
224    my @extra_files = filecheck();
225
226finds files below the current directory that are not mentioned in the
227C<MANIFEST> file. An optional file C<MANIFEST.SKIP> will be
228consulted. Any file matching a regular expression in such a file will
229not be reported as missing in the C<MANIFEST> file. The list of any
230extraneous files found is returned, and by default also reported to
231STDERR.
232
233=cut
234
235sub filecheck {
236    return _check_manifest();
237}
238
239
240=item fullcheck
241
242    my($missing, $extra) = fullcheck();
243
244does both a manicheck() and a filecheck(), returning then as two array
245refs.
246
247=cut
248
249sub fullcheck {
250    return [_check_files()], [_check_manifest()];
251}
252
253
254=item skipcheck
255
256    my @skipped = skipcheck();
257
258lists all the files that are skipped due to your C<MANIFEST.SKIP>
259file.
260
261=cut
262
263sub 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
281sub _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
305sub _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
331reads a named C<MANIFEST> file (defaults to C<MANIFEST> in the current
332directory) and returns a HASH reference with files being the keys and
333comments being the values of the HASH.  Blank lines and lines which
334start with C<#> in the C<MANIFEST> file are discarded.
335
336=cut
337
338sub 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
398reads a named C<MANIFEST.SKIP> file (defaults to C<MANIFEST.SKIP> in
399the current directory) and returns a CODE reference that tests whether
400a given filename should be skipped.
401
402=cut
403
404# returns an anonymous sub that decides if an argument matches
405sub 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
442sub _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
488sub _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
512Copies the files that are the keys in %src to the $dest_dir.  %src is
513typically returned by the maniread() function.
514
515    manicopy( maniread(), $dest_dir );
516
517This function is useful for producing a directory tree identical to the
518intended distribution tree.
519
520$how can be used to specify a different methods of "copying".  Valid
521values are C<cp>, which actually copies the files, C<ln> which creates
522hard links, and C<best> which mostly links the files but copies any
523symbolic link to make a tree without any symbolic link.  C<cp> is the
524default.
525
526=cut
527
528sub 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
557sub 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
589sub 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
599sub 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.
615sub _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.
623my @Exceptions = qw(MANIFEST META.yml SIGNATURE);
624sub 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
635sub _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
649sub _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
659sub _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
676Adds 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
682sub maniadd {
683    my($additions) = shift;
684
685    _normalize($additions);
686    _fix_manifest($MANIFEST);
687
688    my $manifest = maniread();
689    my @needed = grep { !exists $manifest->{$_} } keys %$additions;
690    return 1 unless @needed;
691
692    open(MANIFEST, ">>$MANIFEST") or
693      die "maniadd() could not open $MANIFEST: $!";
694
695    foreach my $file (_sort @needed) {
696        my $comment = $additions->{$file} || '';
697        if ($file =~ /\s/) {
698            $file =~ s/([\\'])/\\$1/g;
699            $file = "'$file'";
700        }
701        printf MANIFEST "%-40s %s\n", $file, $comment;
702    }
703    close MANIFEST or die "Error closing $MANIFEST: $!";
704
705    return 1;
706}
707
708
709# Sometimes MANIFESTs are missing a trailing newline.  Fix this.
710sub _fix_manifest {
711    my $manifest_file = shift;
712
713    open MANIFEST, $MANIFEST or die "Could not open $MANIFEST: $!";
714
715    # Yes, we should be using seek(), but I'd like to avoid loading POSIX
716    # to get SEEK_*
717    my @manifest = <MANIFEST>;
718    close MANIFEST;
719
720    unless( $manifest[-1] =~ /\n\z/ ) {
721        open MANIFEST, ">>$MANIFEST" or die "Could not open $MANIFEST: $!";
722        print MANIFEST "\n";
723        close MANIFEST;
724    }
725}
726
727
728# UNIMPLEMENTED
729sub _normalize {
730    return;
731}
732
733
734=back
735
736=head2 MANIFEST
737
738A list of files in the distribution, one file per line.  The MANIFEST
739always uses Unix filepath conventions even if you're not on Unix.  This
740means F<foo/bar> style not F<foo\bar>.
741
742Anything between white space and an end of line within a C<MANIFEST>
743file is considered to be a comment.  Any line beginning with # is also
744a comment. Beginning with ExtUtils::Manifest 1.52, a filename may
745contain whitespace characters if it is enclosed in single quotes; single
746quotes or backslashes in that filename must be backslash-escaped.
747
748    # this a comment
749    some/file
750    some/other/file            comment about some/file
751    'some/third file'          comment
752
753
754=head2 MANIFEST.SKIP
755
756The file MANIFEST.SKIP may contain regular expressions of files that
757should be ignored by mkmanifest() and filecheck(). The regular
758expressions should appear one on each line. Blank lines and lines
759which start with C<#> are skipped.  Use C<\#> if you need a regular
760expression to start with a C<#>.
761
762For example:
763
764    # Version control files and dirs.
765    \bRCS\b
766    \bCVS\b
767    ,v$
768    \B\.svn\b
769
770    # Makemaker generated files and dirs.
771    ^MANIFEST\.
772    ^Makefile$
773    ^blib/
774    ^MakeMaker-\d
775
776    # Temp, old and emacs backup files.
777    ~$
778    \.old$
779    ^#.*#$
780    ^\.#
781
782If no MANIFEST.SKIP file is found, a default set of skips will be
783used, similar to the example above.  If you want nothing skipped,
784simply make an empty MANIFEST.SKIP file.
785
786In one's own MANIFEST.SKIP file, certain directives
787can be used to include the contents of other MANIFEST.SKIP
788files. At present two such directives are recognized.
789
790=over 4
791
792=item #!include_default
793
794This inserts the contents of the default MANIFEST.SKIP file
795
796=item #!include /Path/to/another/manifest.skip
797
798This inserts the contents of the specified external file
799
800=back
801
802The included contents will be inserted into the MANIFEST.SKIP
803file in between I<#!start included /path/to/manifest.skip>
804and I<#!end included /path/to/manifest.skip> markers.
805The original MANIFEST.SKIP is saved as MANIFEST.SKIP.bak.
806
807=head2 EXPORT_OK
808
809C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
810C<&maniread>, and C<&manicopy> are exportable.
811
812=head2 GLOBAL VARIABLES
813
814C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
815results in both a different C<MANIFEST> and a different
816C<MANIFEST.SKIP> file. This is useful if you want to maintain
817different distributions for different audiences (say a user version
818and a developer version including RCS).
819
820C<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
821all functions act silently.
822
823C<$ExtUtils::Manifest::Debug> defaults to 0.  If set to a true value,
824or if PERL_MM_MANIFEST_DEBUG is true, debugging output will be
825produced.
826
827=head1 DIAGNOSTICS
828
829All diagnostic output is sent to C<STDERR>.
830
831=over 4
832
833=item C<Not in MANIFEST:> I<file>
834
835is reported if a file is found which is not in C<MANIFEST>.
836
837=item C<Skipping> I<file>
838
839is reported if a file is skipped due to an entry in C<MANIFEST.SKIP>.
840
841=item C<No such file:> I<file>
842
843is reported if a file mentioned in a C<MANIFEST> file does not
844exist.
845
846=item C<MANIFEST:> I<$!>
847
848is reported if C<MANIFEST> could not be opened.
849
850=item C<Added to MANIFEST:> I<file>
851
852is reported by mkmanifest() if $Verbose is set and a file is added
853to MANIFEST. $Verbose is set to 1 by default.
854
855=back
856
857=head1 ENVIRONMENT
858
859=over 4
860
861=item B<PERL_MM_MANIFEST_DEBUG>
862
863Turns on debugging
864
865=back
866
867=head1 SEE ALSO
868
869L<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
870
871=head1 AUTHOR
872
873Andreas Koenig C<andreas.koenig@anima.de>
874
875Maintained by Michael G Schwern C<schwern@pobox.com> within the
876ExtUtils-MakeMaker package and, as a separate CPAN package, by
877Randy Kobes C<r.kobes@uwinnipeg.ca>.
878
879=cut
880
8811;
882