This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update ExtUtils::Manifest from 1.72 to 1.73
[perl5.git] / cpan / ExtUtils-Manifest / lib / ExtUtils / Manifest.pm
1 package ExtUtils::Manifest; # git description: 1.72-7-g54209ce
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.73';
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->rel2abs(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.73
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 ...
93
94 =head1 FUNCTIONS
95
96 ExtUtils::Manifest exports no functions by default.  The following are
97 exported on request:
98
99 =head2 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 =head2 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 =head2 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 =head2 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 =head2 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 =head2 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 =head2 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 =head2 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 =head2 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 =head2 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 =head2 MANIFEST
759
760 A list of files in the distribution, one file per line.  The MANIFEST
761 always uses Unix filepath conventions even if you're not on Unix.  This
762 means F<foo/bar> style not F<foo\bar>.
763
764 Anything between white space and an end of line within a C<MANIFEST>
765 file is considered to be a comment.  Any line beginning with # is also
766 a comment. Beginning with ExtUtils::Manifest 1.52, a filename may
767 contain whitespace characters if it is enclosed in single quotes; single
768 quotes or backslashes in that filename must be backslash-escaped.
769
770     # this a comment
771     some/file
772     some/other/file            comment about some/file
773     'some/third file'          comment
774
775
776 =head2 MANIFEST.SKIP
777
778 The file MANIFEST.SKIP may contain regular expressions of files that
779 should be ignored by mkmanifest() and filecheck(). The regular
780 expressions should appear one on each line. Blank lines and lines
781 which start with C<#> are skipped.  Use C<\#> if you need a regular
782 expression to start with a C<#>.
783
784 For example:
785
786     # Version control files and dirs.
787     \bRCS\b
788     \bCVS\b
789     ,v$
790     \B\.svn\b
791
792     # Makemaker generated files and dirs.
793     ^MANIFEST\.
794     ^Makefile$
795     ^blib/
796     ^MakeMaker-\d
797
798     # Temp, old and emacs backup files.
799     ~$
800     \.old$
801     ^#.*#$
802     ^\.#
803
804 If no MANIFEST.SKIP file is found, a default set of skips will be
805 used, similar to the example above.  If you want nothing skipped,
806 simply make an empty MANIFEST.SKIP file.
807
808 In one's own MANIFEST.SKIP file, certain directives
809 can be used to include the contents of other MANIFEST.SKIP
810 files. At present two such directives are recognized.
811
812 =over 4
813
814 =item #!include_default
815
816 This inserts the contents of the default MANIFEST.SKIP file
817
818 =item #!include /Path/to/another/manifest.skip
819
820 This inserts the contents of the specified external file
821
822 =back
823
824 The included contents will be inserted into the MANIFEST.SKIP
825 file in between I<#!start included /path/to/manifest.skip>
826 and I<#!end included /path/to/manifest.skip> markers.
827 The original MANIFEST.SKIP is saved as MANIFEST.SKIP.bak.
828
829 =head2 EXPORT_OK
830
831 C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
832 C<&maniread>, and C<&manicopy> are exportable.
833
834 =head2 GLOBAL VARIABLES
835
836 C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
837 results in both a different C<MANIFEST> and a different
838 C<MANIFEST.SKIP> file. This is useful if you want to maintain
839 different distributions for different audiences (say a user version
840 and a developer version including RCS).
841
842 C<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
843 all functions act silently.
844
845 C<$ExtUtils::Manifest::Debug> defaults to 0.  If set to a true value,
846 or if PERL_MM_MANIFEST_DEBUG is true, debugging output will be
847 produced.
848
849 =head1 DIAGNOSTICS
850
851 All diagnostic output is sent to C<STDERR>.
852
853 =over 4
854
855 =item C<Not in MANIFEST:> I<file>
856
857 is reported if a file is found which is not in C<MANIFEST>.
858
859 =item C<Skipping> I<file>
860
861 is reported if a file is skipped due to an entry in C<MANIFEST.SKIP>.
862
863 =item C<No such file:> I<file>
864
865 is reported if a file mentioned in a C<MANIFEST> file does not
866 exist.
867
868 =item C<MANIFEST:> I<$!>
869
870 is reported if C<MANIFEST> could not be opened.
871
872 =item C<Added to MANIFEST:> I<file>
873
874 is reported by mkmanifest() if $Verbose is set and a file is added
875 to MANIFEST. $Verbose is set to 1 by default.
876
877 =back
878
879 =head1 ENVIRONMENT
880
881 =over 4
882
883 =item B<PERL_MM_MANIFEST_DEBUG>
884
885 Turns on debugging
886
887 =back
888
889 =head1 SEE ALSO
890
891 L<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
892
893 =head1 AUTHOR
894
895 Andreas Koenig C<andreas.koenig@anima.de>
896
897 Currently maintained by the Perl Toolchain Gang.
898
899 =head1 COPYRIGHT AND LICENSE
900
901 This software is copyright (c) 1996- by Andreas Koenig.
902
903 This is free software; you can redistribute it and/or modify it under
904 the same terms as the Perl 5 programming language system itself.
905
906 =cut
907
908 1;