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