X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/4633a7c4bad06b471d9310620b7fe8ddd158cccd..5dca256ec738057dc331fb644a93eca44ad5fa14:/lib/ExtUtils/Manifest.pm diff --git a/lib/ExtUtils/Manifest.pm b/lib/ExtUtils/Manifest.pm index d19b332..9ded9b4 100644 --- a/lib/ExtUtils/Manifest.pm +++ b/lib/ExtUtils/Manifest.pm @@ -1,245 +1,342 @@ package ExtUtils::Manifest; +require Exporter; +use Config; +use File::Basename; +use File::Copy 'copy'; +use File::Find; +use File::Spec; +use Carp; +use strict; + +use vars qw($VERSION @ISA @EXPORT_OK + $Is_MacOS $Is_VMS + $Debug $Verbose $Quiet $MANIFEST $DEFAULT_MSKIP); + +$VERSION = 1.44; +@ISA=('Exporter'); +@EXPORT_OK = qw(mkmanifest + manicheck filecheck fullcheck skipcheck + manifind maniread manicopy maniadd + ); + +$Is_MacOS = $^O eq 'MacOS'; +$Is_VMS = $^O eq 'VMS'; +require VMS::Filespec if $Is_VMS; + +$Debug = $ENV{PERL_MM_MANIFEST_DEBUG} || 0; +$Verbose = defined $ENV{PERL_MM_MANIFEST_VERBOSE} ? + $ENV{PERL_MM_MANIFEST_VERBOSE} : 1; +$Quiet = 0; +$MANIFEST = 'MANIFEST'; + +$DEFAULT_MSKIP = File::Spec->catfile( dirname(__FILE__), "$MANIFEST.SKIP" ); + + =head1 NAME ExtUtils::Manifest - utilities to write and check a MANIFEST file =head1 SYNOPSIS -C + use ExtUtils::Manifest qw(...funcs to import...); -C + mkmanifest(); -C + my @missing_files = manicheck; + my @skipped = skipcheck; + my @extra_files = filecheck; + my($missing, $extra) = fullcheck; -C + my $found = manifind(); -C + my $manifest = maniread(); -C + manicopy($read,$target); -C + maniadd({$file => $comment, ...}); -C - -C =head1 DESCRIPTION -Mkmanifest() writes all files in and below the current directory to a -file named C in the current directory. It works similar to +=head2 Functions - find . -print +ExtUtils::Manifest exports no functions by default. The following are +exported on request -but in doing so checks each line in an existing C file and -includes any comments that are found in the existing C file -in the new one. Anything between white space and an end of line within -a C file is considered to be a comment. Filenames and -comments are seperated by one or more TAB characters in the -output. All files that match any regular expression in a file -C (if such a file exists) are ignored. +=over 4 -Manicheck() checks if all the files within a C in the current -directory really do exist. +=item mkmanifest -Filecheck() finds files below the current directory that are not -mentioned in the C file. An optional file C -will be consulted. Any file matching a regular expression in such a -file will not be reported as missing in the C file. + mkmanifest(); -Fullcheck() does both a manicheck() and a filecheck(). +Writes all files in and below the current directory to your F. +It works similar to -Skipcheck() lists all the files that are skipped due to your -C file. + find . > MANIFEST -Manifind() retruns a hash reference. The keys of the hash are the -files found below the current directory. +All files that match any regular expression in a file F +(if it exists) are ignored. -Maniread($file) reads a named C file (defaults to -C in the current directory) and returns a HASH reference -with files being the keys and comments being the values of the HASH. +Any existing F file will be saved as F. Lines +from the old F file is preserved, including any comments +that are found in the existing F file in the new one. -I copies the files that are the keys in -the HASH I<%$read> to the named target directory. The HASH reference -I<$read> is typically returned by the maniread() function. This -function is useful for producing a directory tree identical to the -intended distribution tree. The third parameter $how can be used to -specify a different methods of "copying". Valid values are C, -which actually copies the files, C which creates hard links, and -C which mostly links the files but copies any symbolic link to -make a tree without any symbolic link. Best is the default. +=cut -=head1 MANIFEST.SKIP +sub _sort { + return sort { lc $a cmp lc $b } @_; +} -The file MANIFEST.SKIP may contain regular expressions of files that -should be ignored by mkmanifest() and filecheck(). The regular -expressions should appear one on each line. A typical example: +sub mkmanifest { + my $manimiss = 0; + my $read = (-r 'MANIFEST' && maniread()) or $manimiss++; + $read = {} if $manimiss; + local *M; + rename $MANIFEST, "$MANIFEST.bak" unless $manimiss; + open M, ">$MANIFEST" or die "Could not open $MANIFEST: $!"; + my $skip = _maniskip(); + my $found = manifind(); + my($key,$val,$file,%all); + %all = (%$found, %$read); + $all{$MANIFEST} = ($Is_VMS ? "$MANIFEST\t\t" : '') . 'This list of files' + if $manimiss; # add new MANIFEST to known file list + foreach $file (_sort keys %all) { + if ($skip->($file)) { + # Policy: only remove files if they're listed in MANIFEST.SKIP. + # Don't remove files just because they don't exist. + warn "Removed from $MANIFEST: $file\n" if $Verbose and exists $read->{$file}; + next; + } + if ($Verbose){ + warn "Added to $MANIFEST: $file\n" unless exists $read->{$file}; + } + my $text = $all{$file}; + ($file,$text) = split(/\s+/,$text,2) if $Is_VMS && $text; + $file = _unmacify($file); + my $tabs = (5 - (length($file)+1)/8); + $tabs = 1 if $tabs < 1; + $tabs = 0 unless $text; + print M $file, "\t" x $tabs, $text, "\n"; + } + close M; +} - \bRCS\b - ^MANIFEST\. - ^Makefile$ - ~$ - \.html$ - \.old$ - ^blib/ - ^MakeMaker-\d +# Geez, shouldn't this use File::Spec or File::Basename or something? +# Why so careful about dependencies? +sub clean_up_filename { + my $filename = shift; + $filename =~ s|^\./||; + $filename =~ s/^:([^:]+)$/$1/ if $Is_MacOS; + return $filename; +} -=head1 EXPORT_OK -C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>, -C<&maniread>, and C<&manicopy> are exportable. +=item manifind -=head1 DIAGNOSTICS + my $found = manifind(); -All diagnostic output is sent to C. +returns a hash reference. The keys of the hash are the files found +below the current directory. -=over +=cut -=item C I +sub manifind { + my $p = shift || {}; + my $found = {}; + + my $wanted = sub { + my $name = clean_up_filename($File::Find::name); + warn "Debug: diskfile $name\n" if $Debug; + return if -d $_; + + if( $Is_VMS ) { + $name =~ s#(.*)\.$#\L$1#; + $name = uc($name) if $name =~ /^MANIFEST(\.SKIP)?$/i; + } + $found->{$name} = ""; + }; + + # We have to use "$File::Find::dir/$_" in preprocess, because + # $File::Find::name is unavailable. + # Also, it's okay to use / here, because MANIFEST files use Unix-style + # paths. + find({wanted => $wanted}, + $Is_MacOS ? ":" : "."); + + return $found; +} -is reported if a file is found, that is missing in the C -file which is excluded by a regular expression in the file -C. -=item C I +=item manicheck -is reported if a file mentioned in a C file does not -exist. + my @missing_files = manicheck(); -=item C I<$!> +checks if all the files within a C in the current directory +really do exist. If C and the tree below the current +directory are in sync it silently returns an empty list. +Otherwise it returns a list of files which are listed in the +C but missing from the directory, and by default also +outputs these names to STDERR. -is reported if C could not be opened. +=cut -=item C I +sub manicheck { + return _check_files(); +} -is reported by mkmanifest() if $Verbose is set and a file is added -to MANIFEST. $Verbose is set to 1 by default. -=back +=item filecheck -=head1 AUTHOR + my @extra_files = filecheck(); -Andreas Koenig Fkoenig@franz.ww.TU-Berlin.DEE> +finds files below the current directory that are not mentioned in the +C file. An optional file C will be +consulted. Any file matching a regular expression in such a file will +not be reported as missing in the C file. The list of any +extraneous files found is returned, and by default also reported to +STDERR. =cut -require Exporter; -@ISA=('Exporter'); -@EXPORT_OK = ('mkmanifest', 'manicheck', 'fullcheck', 'filecheck', - 'skipcheck', 'maniread', 'manicopy'); - -use Config; -use File::Find; -use Carp; +sub filecheck { + return _check_manifest(); +} -$Debug = 0; -$Verbose = 1; -$Is_VMS = $Config{'osname'} eq 'VMS'; -$VERSION = $VERSION = substr(q$Revision: 1.15 $,10,4); +=item fullcheck -$Quiet = 0; + my($missing, $extra) = fullcheck(); -sub mkmanifest { - my $manimiss = 0; - my $read = maniread() or $manimiss++; - $read = {} if $manimiss; - my $matches = _maniskip(); - my $found = manifind(); - my($key,$val,$file,%all); - my %all = (%$found, %$read); - local *M; - rename "MANIFEST", "MANIFEST.bak" unless $manimiss; - open M, ">MANIFEST" or die "Could not open MANIFEST: $!"; - foreach $file (sort keys %all) { - next if &$matches($file); - if ($Verbose){ - warn "Added to MANIFEST: $file\n" unless exists $read->{$file}; - } - my $text = $all{$file}; - ($file,$text) = split(/\s+/,$text,2) if $Is_VMS; - my $tabs = (5 - (length($file)+1)/8); - $tabs = 1 if $tabs < 1; - $tabs = 0 unless $text; - print M $file, "\t" x $tabs, $text, "\n"; - } - close M; -} +does both a manicheck() and a filecheck(), returning then as two array +refs. -sub manifind { - local $found = {}; - find(sub {return if -d $_; - (my $name = $File::Find::name) =~ s|./||; - warn "Debug: diskfile $name\n" if $Debug; - $name =~ s#(.*)\.$#\L$1# if $Is_VMS; - $found->{$name} = "";}, "."); - $found; -} +=cut sub fullcheck { - _manicheck(3); + return [_check_files()], [_check_manifest()]; } -sub manicheck { - return @{(_manicheck(1))[0]}; -} -sub filecheck { - return @{(_manicheck(2))[1]}; -} +=item skipcheck + + my @skipped = skipcheck(); + +lists all the files that are skipped due to your C +file. + +=cut sub skipcheck { - _manicheck(6); + my($p) = @_; + my $found = manifind(); + my $matches = _maniskip(); + + my @skipped = (); + foreach my $file (_sort keys %$found){ + if (&$matches($file)){ + warn "Skipping $file\n"; + push @skipped, $file; + next; + } + } + + return @skipped; } -sub _manicheck { - my($arg) = @_; - my $read = maniread(); - my $file; - my(@missfile,@missentry); - if ($arg & 1){ - my $found = manifind(); - foreach $file (sort keys %$read){ - warn "Debug: manicheck checking from MANIFEST $file\n" if $Debug; - unless ( exists $found->{$file} ) { - warn "No such file: $file\n" unless $Quiet; - push @missfile, $file; - } - } + +sub _check_files { + my $p = shift; + my $dosnames=(defined(&Dos::UseLFN) && Dos::UseLFN()==0); + my $read = maniread() || {}; + my $found = manifind($p); + + my(@missfile) = (); + foreach my $file (_sort keys %$read){ + warn "Debug: manicheck checking from $MANIFEST $file\n" if $Debug; + if ($dosnames){ + $file = lc $file; + $file =~ s=(\.(\w|-)+)=substr ($1,0,4)=ge; + $file =~ s=((\w|-)+)=substr ($1,0,8)=ge; + } + unless ( exists $found->{$file} ) { + warn "No such file: $file\n" unless $Quiet; + push @missfile, $file; + } } - if ($arg & 2){ - $read ||= {}; - my $matches = _maniskip(); - my $found = manifind(); - my $skipwarn = $arg & 4; - foreach $file (sort keys %$found){ - if (&$matches($file)){ - warn "Skipping $file\n" if $skipwarn; - next; - } - warn "Debug: manicheck checking from disk $file\n" if $Debug; - unless ( exists $read->{$file} ) { - warn "Not in MANIFEST: $file\n" unless $Quiet; - push @missentry, $file; - } - } + + return @missfile; +} + + +sub _check_manifest { + my($p) = @_; + my $read = maniread() || {}; + my $found = manifind($p); + my $skip = _maniskip(); + + my @missentry = (); + foreach my $file (_sort keys %$found){ + next if $skip->($file); + warn "Debug: manicheck checking from disk $file\n" if $Debug; + unless ( exists $read->{$file} ) { + my $canon = $Is_MacOS ? "\t" . _unmacify($file) : ''; + warn "Not in $MANIFEST: $file$canon\n" unless $Quiet; + push @missentry, $file; + } } - (\@missfile,\@missentry); + + return @missentry; } + +=item maniread + + my $manifest = maniread(); + my $manifest = maniread($manifest_file); + +reads a named C file (defaults to C in the current +directory) and returns a HASH reference with files being the keys and +comments being the values of the HASH. Blank lines and lines which +start with C<#> in the C file are discarded. + +=cut + sub maniread { my ($mfile) = @_; - $mfile = "MANIFEST" unless defined $mfile; + $mfile ||= $MANIFEST; my $read = {}; local *M; unless (open M, $mfile){ - warn "$mfile: $!"; - return $read; + warn "$mfile: $!"; + return $read; } + local $_; while (){ - chomp; - if ($Is_VMS) { /^(\S+)/ and $read->{"\L$1"}=$_; } - else { /^(\S+)\s*(.*)/ and $read->{$1}=$2; } + chomp; + next if /^\s*#/; + + my($file, $comment) = /^(\S+)\s*(.*)/; + next unless $file; + + if ($Is_MacOS) { + $file = _macify($file); + $file =~ s/\\([0-3][0-7][0-7])/sprintf("%c", oct($1))/ge; + } + elsif ($Is_VMS) { + require File::Basename; + my($base,$dir) = File::Basename::fileparse($file); + # Resolve illegal file specifications in the same way as tar + $dir =~ tr/./_/; + my(@pieces) = split(/\./,$base); + if (@pieces > 2) { $base = shift(@pieces) . '.' . join('_',@pieces); } + my $okfile = "$dir$base"; + warn "Debug: Illegal name $file changed to $okfile\n" if $Debug; + $file = $okfile; + $file = lc($file) unless $file =~ /^MANIFEST(\.SKIP)?$/; + } + + $read->{$file} = $comment; } close M; $read; @@ -247,54 +344,84 @@ sub maniread { # returns an anonymous sub that decides if an argument matches sub _maniskip { - my ($mfile) = @_; - my $matches = sub {0}; my @skip ; - my $mfile = "MANIFEST.SKIP" unless defined $mfile; - local *M; - return $matches unless -f $mfile; - open M, $mfile or return $matches; + my $mfile = "$MANIFEST.SKIP"; + local(*M,$_); + open M, $mfile or open M, $DEFAULT_MSKIP or return sub {0}; while (){ chomp; + next if /^#/; next if /^\s*$/; - push @skip, $_; + push @skip, _macify($_); } close M; - my $opts = $Is_VMS ? 'oi ' : 'o '; - my $sub = "\$matches = " - . "sub { my(\$arg)=\@_; return 1 if " - . join (" || ", (map {s!/!\\/!g; "\$arg =~ m/$_/$opts"} @skip), 0) - . " }"; - eval $sub; - print "Debug: $sub\n" if $Debug; - $matches; + my $opts = $Is_VMS ? '(?i)' : ''; + + # Make sure each entry is isolated in its own parentheses, in case + # any of them contain alternations + my $regex = join '|', map "(?:$_)", @skip; + + return sub { $_[0] =~ qr{$opts$regex} }; } +=item manicopy + + manicopy(\%src, $dest_dir); + manicopy(\%src, $dest_dir, $how); + +Copies the files that are the keys in %src to the $dest_dir. %src is +typically returned by the maniread() function. + + manicopy( maniread(), $dest_dir ); + +This function is useful for producing a directory tree identical to the +intended distribution tree. + +$how can be used to specify a different methods of "copying". Valid +values are C, which actually copies the files, C which creates +hard links, and C which mostly links the files but copies any +symbolic link to make a tree without any symbolic link. C is the +default. + +=cut + sub manicopy { my($read,$target,$how)=@_; croak "manicopy() called without target argument" unless defined $target; - $how = 'cp' unless defined $how && $how; + $how ||= 'cp'; require File::Path; require File::Basename; - my(%dirs,$file); + $target = VMS::Filespec::unixify($target) if $Is_VMS; - umask 0; - foreach $file (keys %$read){ - $file = VMS::Filespec::unixify($file) if $Is_VMS; - my $dir = File::Basename::dirname($file); - File::Path::mkpath(["$target/$dir"],1,0755); - if ($Is_VMS) { vms_cp_if_diff($file,"$target/$file"); } - else { cp_if_diff($file, "$target/$file", $how); } + File::Path::mkpath([ $target ],! $Quiet,$Is_VMS ? undef : 0755); + foreach my $file (keys %$read){ + if ($Is_MacOS) { + if ($file =~ m!:!) { + my $dir = _maccat($target, $file); + $dir =~ s/[^:]+$//; + File::Path::mkpath($dir,1,0755); + } + cp_if_diff($file, _maccat($target, $file), $how); + } else { + $file = VMS::Filespec::unixify($file) if $Is_VMS; + if ($file =~ m!/!) { # Ilya, that hurts, I fear, or maybe not? + my $dir = File::Basename::dirname($file); + $dir = VMS::Filespec::unixify($dir) if $Is_VMS; + File::Path::mkpath(["$target/$dir"],! $Quiet,$Is_VMS ? undef : 0755); + } + cp_if_diff($file, "$target/$file", $how); + } } } sub cp_if_diff { - my($from,$to, $how)=@_; - -f $from || carp "$0: $from not found"; + my($from, $to, $how)=@_; + -f $from or carp "$0: $from not found"; my($diff) = 0; local(*F,*T); - open(F,$from) or croak "Can't read $from: $!\n"; - if (open(T,$to)) { + open(F,"< $from\0") or die "Can't read $from: $!\n"; + if (open(T,"< $to\0")) { + local $_; while () { $diff++,last if $_ ne ; } $diff++ unless eof(T); close T; @@ -305,58 +432,273 @@ sub cp_if_diff { if (-e $to) { unlink($to) or confess "unlink $to: $!"; } - &$how($from, $to); - } -} - -# Do the comparisons here rather than spawning off another process -sub vms_cp_if_diff { - my($from,$to) = @_; - my($diff) = 0; - local(*F,*T); - open(F,$from) or croak "Can't read $from: $!\n"; - if (open(T,$to)) { - while () { $diff++,last if $_ ne ; } - $diff++ unless eof(T); - close T; - } - else { $diff++; } - close F; - if ($diff) { - system('copy',vmsify($from),vmsify($to)) & 1 - or confess "Copy failed: $!"; + STRICT_SWITCH: { + best($from,$to), last STRICT_SWITCH if $how eq 'best'; + cp($from,$to), last STRICT_SWITCH if $how eq 'cp'; + ln($from,$to), last STRICT_SWITCH if $how eq 'ln'; + croak("ExtUtils::Manifest::cp_if_diff " . + "called with illegal how argument [$how]. " . + "Legal values are 'best', 'cp', and 'ln'."); + } } } sub cp { my ($srcFile, $dstFile) = @_; - my $buf; - open (IN,"<$srcFile") or die "Can't open input $srcFile: $!\n"; - open (OUT,">$dstFile") or die "Can't open output $dstFile: $!\n"; - my ($perm,$access,$mod) = (stat IN)[2,8,9]; - syswrite(OUT, $buf, $len) while $len = sysread(IN, $buf, 8192); - close IN; - close OUT; - utime $access, $mod, $dstFile; - # chmod a+rX-w,go-w - chmod( 0444 | ( $perm & 0111 ? 0111 : 0 ), $dstFile ); + my ($access,$mod) = (stat $srcFile)[8,9]; + + copy($srcFile,$dstFile); + utime $access, $mod + ($Is_VMS ? 1 : 0), $dstFile; + _manicopy_chmod($dstFile); } + sub ln { my ($srcFile, $dstFile) = @_; + return &cp if $Is_VMS or ($^O eq 'MSWin32' and Win32::IsWin95()); link($srcFile, $dstFile); - local($_) = $dstFile; # chmod a+r,go-w+X (except "X" only applies to u=x) - my $mode= 0444 | (stat)[2] & 0700; - chmod( $mode | ( $mode & 0100 ? 0111 : 0 ), $_ ); + + unless( _manicopy_chmod($dstFile) ) { + unlink $dstFile; + return; + } + 1; +} + +# 1) Strip off all group and world permissions. +# 2) Let everyone read it. +# 3) If the owner can execute it, everyone can. +sub _manicopy_chmod { + my($file) = shift; + + my $perm = 0444 | (stat $file)[2] & 0700; + chmod( $perm | ( $perm & 0100 ? 0111 : 0 ), $file ); } sub best { my ($srcFile, $dstFile) = @_; - if (-l $srcFile) { + if (!$Config{d_link} or -l $srcFile) { cp($srcFile, $dstFile); } else { - ln($srcFile, $dstFile); + ln($srcFile, $dstFile) or cp($srcFile, $dstFile); + } +} + +sub _macify { + my($file) = @_; + + return $file unless $Is_MacOS; + + $file =~ s|^\./||; + if ($file =~ m|/|) { + $file =~ s|/+|:|g; + $file = ":$file"; + } + + $file; +} + +sub _maccat { + my($f1, $f2) = @_; + + return "$f1/$f2" unless $Is_MacOS; + + $f1 .= ":$f2"; + $f1 =~ s/([^:]:):/$1/g; + return $f1; +} + +sub _unmacify { + my($file) = @_; + + return $file unless $Is_MacOS; + + $file =~ s|^:||; + $file =~ s|([/ \n])|sprintf("\\%03o", unpack("c", $1))|ge; + $file =~ y|:|/|; + + $file; +} + + +=item maniadd + + maniadd({ $file => $comment, ...}); + +Adds an entry to an existing F unless its already there. + +$file will be normalized (ie. Unixified). B + +=cut + +sub maniadd { + my($additions) = shift; + + _normalize($additions); + _fix_manifest($MANIFEST); + + my $manifest = maniread(); + my @needed = grep { !exists $manifest->{$_} } keys %$additions; + return 1 unless @needed; + + open(MANIFEST, ">>$MANIFEST") or + die "maniadd() could not open $MANIFEST: $!"; + + foreach my $file (_sort @needed) { + my $comment = $additions->{$file} || ''; + printf MANIFEST "%-40s %s\n", $file, $comment; + } + close MANIFEST or die "Error closing $MANIFEST: $!"; + + return 1; +} + + +# Sometimes MANIFESTs are missing a trailing newline. Fix this. +sub _fix_manifest { + my $manifest_file = shift; + + open MANIFEST, $MANIFEST or die "Could not open $MANIFEST: $!"; + + # Yes, we should be using seek(), but I'd like to avoid loading POSIX + # to get SEEK_* + my @manifest = ; + close MANIFEST; + + unless( $manifest[-1] =~ /\n\z/ ) { + open MANIFEST, ">>$MANIFEST" or die "Could not open $MANIFEST: $!"; + print MANIFEST "\n"; + close MANIFEST; } } + +# UNIMPLEMENTED +sub _normalize { + return; +} + + +=back + +=head2 MANIFEST + +A list of files in the distribution, one file per line. The MANIFEST +always uses Unix filepath conventions even if you're not on Unix. This +means F style not F. + +Anything between white space and an end of line within a C +file is considered to be a comment. Any line beginning with # is also +a comment. + + # this a comment + some/file + some/other/file comment about some/file + + +=head2 MANIFEST.SKIP + +The file MANIFEST.SKIP may contain regular expressions of files that +should be ignored by mkmanifest() and filecheck(). The regular +expressions should appear one on each line. Blank lines and lines +which start with C<#> are skipped. Use C<\#> if you need a regular +expression to start with a C<#>. + +For example: + + # Version control files and dirs. + \bRCS\b + \bCVS\b + ,v$ + \B\.svn\b + + # Makemaker generated files and dirs. + ^MANIFEST\. + ^Makefile$ + ^blib/ + ^MakeMaker-\d + + # Temp, old and emacs backup files. + ~$ + \.old$ + ^#.*#$ + ^\.# + +If no MANIFEST.SKIP file is found, a default set of skips will be +used, similar to the example above. If you want nothing skipped, +simply make an empty MANIFEST.SKIP file. + + +=head2 EXPORT_OK + +C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>, +C<&maniread>, and C<&manicopy> are exportable. + +=head2 GLOBAL VARIABLES + +C<$ExtUtils::Manifest::MANIFEST> defaults to C. Changing it +results in both a different C and a different +C file. This is useful if you want to maintain +different distributions for different audiences (say a user version +and a developer version including RCS). + +C<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value, +all functions act silently. + +C<$ExtUtils::Manifest::Debug> defaults to 0. If set to a true value, +or if PERL_MM_MANIFEST_DEBUG is true, debugging output will be +produced. + +=head1 DIAGNOSTICS + +All diagnostic output is sent to C. + +=over 4 + +=item C I + +is reported if a file is found which is not in C. + +=item C I + +is reported if a file is skipped due to an entry in C. + +=item C I + +is reported if a file mentioned in a C file does not +exist. + +=item C I<$!> + +is reported if C could not be opened. + +=item C I + +is reported by mkmanifest() if $Verbose is set and a file is added +to MANIFEST. $Verbose is set to 1 by default. + +=back + +=head1 ENVIRONMENT + +=over 4 + +=item B + +Turns on debugging + +=back + +=head1 SEE ALSO + +L which has handy targets for most of the functionality. + +=head1 AUTHOR + +Andreas Koenig C + +Currently maintained by Michael G Schwern C + +=cut + 1;