1N/AExtUtils::Manifest - utilities to write and check a MANIFEST file 1N/A use ExtUtils::Manifest qw(...funcs to import...); 1N/A my @missing_files = manicheck; 1N/A my @skipped = skipcheck; 1N/A my @extra_files = filecheck; 1N/A my($missing, $extra) = fullcheck; 1N/A my $found = manifind(); 1N/A my $manifest = maniread(); 1N/A manicopy($read,$target); 1N/A maniadd({$file => $comment, ...}); 1N/AExtUtils::Manifest exports no functions by default. The following are 1N/AWrites all files in and below the current directory to your F<MANIFEST>. 1N/AAll files that match any regular expression in a file F<MANIFEST.SKIP> 1N/A(if it exists) are ignored. 1N/AAny existing F<MANIFEST> file will be saved as F<MANIFEST.bak>. Lines 1N/Afrom the old F<MANIFEST> file is preserved, including any comments 1N/Athat are found in the existing F<MANIFEST> file in the new one. 1N/A return sort {
lc $a
cmp lc $b } @_;
1N/A open M,
">$MANIFEST" or die "Could not open $MANIFEST: $!";
1N/A # Policy: only remove files if they're listed in MANIFEST.SKIP. 1N/A # Don't remove files just because they don't exist. 1N/A warn "Added to $MANIFEST: $file\n" unless exists $
read->{$
file};
1N/A# Geez, shouldn't this use File::Spec or File::Basename or something? 1N/A# Why so careful about dependencies? 1N/A my $found = manifind(); 1N/Areturns a hash reference. The keys of the hash are the files found 1N/Abelow the current directory. 1N/A my $p =
shift || {};
1N/A warn "Debug: diskfile $name\n" if $
Debug;
1N/A # We have to use "$File::Find::dir/$_" in preprocess, because 1N/A # $File::Find::name is unavailable. 1N/A # Also, it's okay to use / here, because MANIFEST files use Unix-style 1N/A my @missing_files = manicheck(); 1N/Achecks if all the files within a C<MANIFEST> in the current directory 1N/Areally do exist. If C<MANIFEST> and the tree below the current 1N/Adirectory are in sync it silently returns an empty list. 1N/AOtherwise it returns a list of files which are listed in the 1N/AC<MANIFEST> but missing from the directory, and by default also 1N/Aoutputs these names to STDERR. 1N/A my @extra_files = filecheck(); 1N/Afinds files below the current directory that are not mentioned in the 1N/AC<MANIFEST> file. An optional file C<MANIFEST.SKIP> will be 1N/Aconsulted. Any file matching a regular expression in such a file will 1N/Anot be reported as missing in the C<MANIFEST> file. The list of any 1N/Aextraneous files found is returned, and by default also reported to 1N/A my($missing, $extra) = fullcheck(); 1N/Adoes both a manicheck() and a filecheck(), returning then as two array 1N/A my @skipped = skipcheck(); 1N/Alists all the files that are skipped due to your C<MANIFEST.SKIP> 1N/A warn "Skipping $file\n";
1N/A warn "Debug: manicheck checking from $MANIFEST $file\n" if $
Debug;
1N/A $
file =~ s=(\.(\w|-)+)=
substr ($
1,
0,
4)=
ge;
1N/A $
file =~ s=((\w|-)+)=
substr ($
1,
0,
8)=
ge;
1N/A warn "No such file: $file\n" unless $
Quiet;
1N/A warn "Debug: manicheck checking from disk $file\n" if $
Debug;
1N/A warn "Not in $MANIFEST: $file$canon\n" unless $
Quiet;
1N/A my $manifest = maniread(); 1N/A my $manifest = maniread($manifest_file); 1N/Areads a named C<MANIFEST> file (defaults to C<MANIFEST> in the current 1N/Adirectory) and returns a HASH reference with files being the keys and 1N/Acomments being the values of the HASH. Blank lines and lines which 1N/Astart with C<#> in the C<MANIFEST> file are discarded. 1N/A $
file =~ s/\\([
0-
3][
0-
7][
0-
7])/
sprintf(
"%c",
oct($
1))/
ge;
1N/A # Resolve illegal file specifications in the same way as tar 1N/A warn "Debug: Illegal name $file changed to $okfile\n" if $
Debug;
1N/A# returns an anonymous sub that decides if an argument matches 1N/A # Make sure each entry is isolated in its own parentheses, in case 1N/A # any of them contain alternations 1N/A manicopy($src, $dest_dir); 1N/A manicopy($src, $dest_dir, $how); 1N/Acopies the files that are the keys in the HASH I<%$src> to the 1N/A$dest_dir. The HASH reference $read is typically returned by the 1N/Amaniread() function. This function is useful for producing a directory 1N/Atree identical to the intended distribution tree. The third parameter 1N/A$how can be used to specify a different methods of "copying". Valid 1N/Avalues are C<cp>, which actually copies the files, C<ln> which creates 1N/Ahard links, and C<best> which mostly links the files but copies any 1N/Asymbolic link to make a tree without any symbolic link. Best is the 1N/A croak "manicopy() called without target argument" unless defined $
target;
1N/A if ($
file =~ m!/!) {
# Ilya, that hurts, I fear, or maybe not? 1N/A -f $
from or carp "$0: $from not found";
1N/A open(F,
"< $from\0")
or die "Can't read $from: $!\n";
1N/A if (
open(T,
"< $to\0")) {
1N/A while (<F>) { $
diff++,
last if $_
ne <T>; }
1N/A unlink($
to)
or confess "unlink $to: $!";
1N/A croak(
"ExtUtils::Manifest::cp_if_diff " .
1N/A "called with illegal how argument [$how]. " .
1N/A "Legal values are 'best', 'cp', and 'ln'.");
1N/A unless ($^O
eq 'MacOS');
1N/A # chmod a+r,go-w+X (except "X" only applies to u=x) 1N/A if (!
chmod( $
mode | ( $
mode &
0100 ?
0111 :
0 ), $_ )) {
1N/A # Really cool fix from Ilya :) 1N/A $
file =~ s|([/ \n])|
sprintf(
"\\%03o",
unpack(
"c", $
1))|
ge;
1N/A maniadd({ $file => $comment, ...}); 1N/AAdds an entry to an existing F<MANIFEST> unless its already there. 1N/A$file will be normalized (ie. Unixified). B<UNIMPLEMENTED> 1N/A die "maniadd() could not open $MANIFEST: $!";
1N/A# Sometimes MANIFESTs are missing a trailing newline. Fix this. 1N/A # Yes, we should be using seek(), but I'd like to avoid loading POSIX 1N/A open MANIFEST,
">>$MANIFEST" or die "Could not open $MANIFEST: $!";
1N/AAnything between white space and an end of line within a C<MANIFEST> 1N/Afile is considered to be a comment. Filenames and comments are 1N/Aseparated by one or more TAB characters in the output. 1N/AThe file MANIFEST.SKIP may contain regular expressions of files that 1N/Ashould be ignored by mkmanifest() and filecheck(). The regular 1N/Aexpressions should appear one on each line. Blank lines and lines 1N/Awhich start with C<#> are skipped. Use C<\#> if you need a regular 1N/Aexpression to start with a sharp character. A typical example: 1N/A # Version control files and dirs. 1N/A # Makemaker generated files and dirs. 1N/A # Temp, old and emacs backup files. 1N/AIf no MANIFEST.SKIP file is found, a default set of skips will be 1N/Aused, similar to the example above. If you want nothing skipped, 1N/Asimply make an empty MANIFEST.SKIP file. 1N/AC<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>, 1N/AC<&maniread>, and C<&manicopy> are exportable. 1N/A=head2 GLOBAL VARIABLES 1N/AC<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it 1N/Aresults in both a different C<MANIFEST> and a different 1N/AC<MANIFEST.SKIP> file. This is useful if you want to maintain 1N/Adifferent distributions for different audiences (say a user version 1N/Aand a developer version including RCS). 1N/AC<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value, 1N/Aall functions act silently. 1N/AC<$ExtUtils::Manifest::Debug> defaults to 0. If set to a true value, 1N/Aor if PERL_MM_MANIFEST_DEBUG is true, debugging output will be 1N/AAll diagnostic output is sent to C<STDERR>. 1N/A=item C<Not in MANIFEST:> I<file> 1N/Ais reported if a file is found which is not in C<MANIFEST>. 1N/A=item C<Skipping> I<file> 1N/Ais reported if a file is skipped due to an entry in C<MANIFEST.SKIP>. 1N/A=item C<No such file:> I<file> 1N/Ais reported if a file mentioned in a C<MANIFEST> file does not 1N/A=item C<MANIFEST:> I<$!> 1N/Ais reported if C<MANIFEST> could not be opened. 1N/A=item C<Added to MANIFEST:> I<file> 1N/Ais reported by mkmanifest() if $Verbose is set and a file is added 1N/Ato MANIFEST. $Verbose is set to 1 by default. 1N/A=item B<PERL_MM_MANIFEST_DEBUG> 1N/AL<ExtUtils::MakeMaker> which has handy targets for most of the functionality. 1N/AAndreas Koenig <F<andreas.koenig@anima.de>>