diff options
author | Nicholas Clark <nick@ccl4.org> | 2009-09-10 13:26:22 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2009-09-10 13:26:46 +0100 |
commit | 135277f1a6d67eb1f41aaec95616f52cb016cba1 (patch) | |
tree | 6df9707f8b8ecb18ff838e597deeab51f8e2e50a /lib/ExtUtils | |
parent | 640c21e43164b2e0d3d20d4a5b3168d54f8b6e57 (diff) | |
download | perl-135277f1a6d67eb1f41aaec95616f52cb016cba1.tar.gz |
Move ExtUtils::Manifest from lib to ext.
Diffstat (limited to 'lib/ExtUtils')
-rw-r--r-- | lib/ExtUtils/MANIFEST.SKIP | 32 | ||||
-rw-r--r-- | lib/ExtUtils/Manifest.pm | 877 | ||||
-rw-r--r-- | lib/ExtUtils/t/Manifest.t | 417 |
3 files changed, 0 insertions, 1326 deletions
diff --git a/lib/ExtUtils/MANIFEST.SKIP b/lib/ExtUtils/MANIFEST.SKIP deleted file mode 100644 index 885fedcedb..0000000000 --- a/lib/ExtUtils/MANIFEST.SKIP +++ /dev/null @@ -1,32 +0,0 @@ -# Avoid version control files. -\bRCS\b -\bCVS\b -\bSCCS\b -,v$ -\B\.svn\b -\B\.git\b -\B\.gitignore\b -\b_darcs\b - -# Avoid Makemaker generated and utility files. -\bMANIFEST\.bak -\bMakefile$ -\bblib/ -\bMakeMaker-\d -\bpm_to_blib\.ts$ -\bpm_to_blib$ -\bblibdirs\.ts$ # 6.18 through 6.25 generated this - -# Avoid Module::Build generated and utility files. -\bBuild$ -\b_build/ - -# Avoid temp and backup files. -~$ -\.old$ -\#$ -\b\.# -\.bak$ - -# Avoid Devel::Cover files. -\bcover_db\b diff --git a/lib/ExtUtils/Manifest.pm b/lib/ExtUtils/Manifest.pm deleted file mode 100644 index 7281421cc5..0000000000 --- a/lib/ExtUtils/Manifest.pm +++ /dev/null @@ -1,877 +0,0 @@ -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 $Is_VMS_mode $Is_VMS_lc $Is_VMS_nodot - $Debug $Verbose $Quiet $MANIFEST $DEFAULT_MSKIP); - -$VERSION = '1.56'; -@ISA=('Exporter'); -@EXPORT_OK = qw(mkmanifest - manicheck filecheck fullcheck skipcheck - manifind maniread manicopy maniadd - maniskip - ); - -$Is_MacOS = $^O eq 'MacOS'; -$Is_VMS = $^O eq 'VMS'; -$Is_VMS_mode = 0; -$Is_VMS_lc = 0; -$Is_VMS_nodot = 0; # No dots in dir names or double dots in files - -if ($Is_VMS) { - require VMS::Filespec if $Is_VMS; - my $vms_unix_rpt; - my $vms_efs; - my $vms_case; - - $Is_VMS_mode = 1; - $Is_VMS_lc = 1; - $Is_VMS_nodot = 1; - if (eval { local $SIG{__DIE__}; require VMS::Feature; }) { - $vms_unix_rpt = VMS::Feature::current("filename_unix_report"); - $vms_efs = VMS::Feature::current("efs_charset"); - $vms_case = VMS::Feature::current("efs_case_preserve"); - } else { - my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || ''; - my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || ''; - my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || ''; - $vms_unix_rpt = $unix_rpt =~ /^[ET1]/i; - $vms_efs = $efs_charset =~ /^[ET1]/i; - $vms_case = $efs_case =~ /^[ET1]/i; - } - $Is_VMS_lc = 0 if ($vms_case); - $Is_VMS_mode = 0 if ($vms_unix_rpt); - $Is_VMS_nodot = 0 if ($vms_efs); -} - -$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 - - use ExtUtils::Manifest qw(...funcs to import...); - - mkmanifest(); - - my @missing_files = manicheck; - my @skipped = skipcheck; - my @extra_files = filecheck; - my($missing, $extra) = fullcheck; - - my $found = manifind(); - - my $manifest = maniread(); - - manicopy($read,$target); - - maniadd({$file => $comment, ...}); - - -=head1 DESCRIPTION - -=head2 Functions - -ExtUtils::Manifest exports no functions by default. The following are -exported on request - -=over 4 - -=item mkmanifest - - mkmanifest(); - -Writes all files in and below the current directory to your F<MANIFEST>. -It works similar to the result of the Unix command - - find . > MANIFEST - -All files that match any regular expression in a file F<MANIFEST.SKIP> -(if it exists) are ignored. - -Any existing F<MANIFEST> file will be saved as F<MANIFEST.bak>. - -=cut - -sub _sort { - return sort { lc $a cmp lc $b } @_; -} - -sub mkmanifest { - my $manimiss = 0; - my $read = (-r 'MANIFEST' && maniread()) or $manimiss++; - $read = {} if $manimiss; - local *M; - my $bakbase = $MANIFEST; - $bakbase =~ s/\./_/g if $Is_VMS_nodot; # avoid double dots - rename $MANIFEST, "$bakbase.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_mode ? "$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 = _unmacify($file); - my $tabs = (5 - (length($file)+1)/8); - $tabs = 1 if $tabs < 1; - $tabs = 0 unless $text; - if ($file =~ /\s/) { - $file =~ s/([\\'])/\\$1/g; - $file = "'$file'"; - } - print M $file, "\t" x $tabs, $text, "\n"; - } - close M; -} - -# 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; -} - - -=item manifind - - my $found = manifind(); - -returns a hash reference. The keys of the hash are the files found -below the current directory. - -=cut - -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_lc ) { - $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; -} - - -=item manicheck - - my @missing_files = manicheck(); - -checks if all the files within a C<MANIFEST> in the current directory -really do exist. If C<MANIFEST> 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<MANIFEST> but missing from the directory, and by default also -outputs these names to STDERR. - -=cut - -sub manicheck { - return _check_files(); -} - - -=item filecheck - - my @extra_files = filecheck(); - -finds files below the current directory that are not mentioned in the -C<MANIFEST> file. An optional file C<MANIFEST.SKIP> will be -consulted. Any file matching a regular expression in such a file will -not be reported as missing in the C<MANIFEST> file. The list of any -extraneous files found is returned, and by default also reported to -STDERR. - -=cut - -sub filecheck { - return _check_manifest(); -} - - -=item fullcheck - - my($missing, $extra) = fullcheck(); - -does both a manicheck() and a filecheck(), returning then as two array -refs. - -=cut - -sub fullcheck { - return [_check_files()], [_check_manifest()]; -} - - -=item skipcheck - - my @skipped = skipcheck(); - -lists all the files that are skipped due to your C<MANIFEST.SKIP> -file. - -=cut - -sub skipcheck { - 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 _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; - } - } - - 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; - } - } - - return @missentry; -} - - -=item maniread - - my $manifest = maniread(); - my $manifest = maniread($manifest_file); - -reads a named C<MANIFEST> file (defaults to C<MANIFEST> 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<MANIFEST> file are discarded. - -=cut - -sub maniread { - my ($mfile) = @_; - $mfile ||= $MANIFEST; - my $read = {}; - local *M; - unless (open M, "< $mfile"){ - warn "Problem opening $mfile: $!"; - return $read; - } - local $_; - while (<M>){ - chomp; - next if /^\s*#/; - - my($file, $comment); - - # filename may contain spaces if enclosed in '' - # (in which case, \\ and \' are escapes) - if (($file, $comment) = /^'(\\[\\']|.+)+'\s*(.*)/) { - $file =~ s/\\([\\'])/$1/g; - } - else { - ($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_mode) { - require File::Basename; - my($base,$dir) = File::Basename::fileparse($file); - # Resolve illegal file specifications in the same way as tar - if ($Is_VMS_nodot) { - $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 $Is_VMS_lc &&($file =~ /^MANIFEST(\.SKIP)?$/); - } - - $read->{$file} = $comment; - } - close M; - $read; -} - -=item maniskip - - my $skipchk = maniskip(); - my $skipchk = maniskip($manifest_skip_file); - - if ($skipchk->($file)) { .. } - -reads a named C<MANIFEST.SKIP> file (defaults to C<MANIFEST.SKIP> in -the current directory) and returns a CODE reference that tests whether -a given filename should be skipped. - -=cut - -# returns an anonymous sub that decides if an argument matches -sub maniskip { - my @skip ; - my $mfile = shift || "$MANIFEST.SKIP"; - _check_mskip_directives($mfile) if -f $mfile; - local(*M, $_); - open M, "< $mfile" or open M, "< $DEFAULT_MSKIP" or return sub {0}; - while (<M>){ - chomp; - s/\r//; - next if /^#/; - next if /^\s*$/; - s/^'//; - s/'$//; - push @skip, _macify($_); - } - close M; - return sub {0} unless (scalar @skip > 0); - - my $opts = $Is_VMS_mode ? '(?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} }; -} - -# checks for the special directives -# #!include_default -# #!include /path/to/some/manifest.skip -# in a custom MANIFEST.SKIP for, for including -# the content of, respectively, the default MANIFEST.SKIP -# and an external manifest.skip file -sub _check_mskip_directives { - my $mfile = shift; - local (*M, $_); - my @lines = (); - my $flag = 0; - unless (open M, "< $mfile") { - warn "Problem opening $mfile: $!"; - return; - } - while (<M>) { - if (/^#!include_default\s*$/) { - if (my @default = _include_mskip_file()) { - push @lines, @default; - warn "Debug: Including default MANIFEST.SKIP\n" if $Debug; - $flag++; - } - next; - } - if (/^#!include\s+(.*)\s*$/) { - my $external_file = $1; - if (my @external = _include_mskip_file($external_file)) { - push @lines, @external; - warn "Debug: Including external $external_file\n" if $Debug; - $flag++; - } - next; - } - push @lines, $_; - } - close M; - return unless $flag; - my $bakbase = $mfile; - $bakbase =~ s/\./_/g if $Is_VMS_nodot; # avoid double dots - rename $mfile, "$bakbase.bak"; - warn "Debug: Saving original $mfile as $bakbase.bak\n" if $Debug; - unless (open M, "> $mfile") { - warn "Problem opening $mfile: $!"; - return; - } - print M $_ for (@lines); - close M; - return; -} - -# returns an array containing the lines of an external -# manifest.skip file, if given, or $DEFAULT_MSKIP -sub _include_mskip_file { - my $mskip = shift || $DEFAULT_MSKIP; - unless (-f $mskip) { - warn qq{Included file "$mskip" not found - skipping}; - return; - } - local (*M, $_); - unless (open M, "< $mskip") { - warn "Problem opening $mskip: $!"; - return; - } - my @lines = (); - push @lines, "\n#!start included $mskip\n"; - push @lines, $_ while <M>; - close M; - push @lines, "#!end included $mskip\n\n"; - return @lines; -} - -=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<cp>, which actually copies the files, C<ln> which creates -hard links, and C<best> which mostly links the files but copies any -symbolic link to make a tree without any symbolic link. C<cp> is the -default. - -=cut - -sub manicopy { - my($read,$target,$how)=@_; - croak "manicopy() called without target argument" unless defined $target; - $how ||= 'cp'; - require File::Path; - require File::Basename; - - $target = VMS::Filespec::unixify($target) if $Is_VMS_mode; - 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_mode; - 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_mode; - 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)=@_; - if (! -f $from) { - carp "$from not found"; - return; - } - my($diff) = 0; - local(*F,*T); - open(F,"< $from\0") or die "Can't read $from: $!\n"; - if (open(T,"< $to\0")) { - local $_; - while (<F>) { $diff++,last if $_ ne <T>; } - $diff++ unless eof(T); - close T; - } - else { $diff++; } - close F; - if ($diff) { - if (-e $to) { - unlink($to) or confess "unlink $to: $!"; - } - 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 ($access,$mod) = (stat $srcFile)[8,9]; - - copy($srcFile,$dstFile); - utime $access, $mod + ($Is_VMS ? 1 : 0), $dstFile; - _manicopy_chmod($srcFile, $dstFile); -} - - -sub ln { - my ($srcFile, $dstFile) = @_; - # Fix-me - VMS can support links. - return &cp if $Is_VMS or ($^O eq 'MSWin32' and Win32::IsWin95()); - link($srcFile, $dstFile); - - unless( _manicopy_chmod($srcFile, $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($srcFile, $dstFile) = @_; - - my $perm = 0444 | (stat $srcFile)[2] & 0700; - chmod( $perm | ( $perm & 0100 ? 0111 : 0 ), $dstFile ); -} - -# Files that are often modified in the distdir. Don't hard link them. -my @Exceptions = qw(MANIFEST META.yml SIGNATURE); -sub best { - my ($srcFile, $dstFile) = @_; - - my $is_exception = grep $srcFile =~ /$_/, @Exceptions; - if ($is_exception or !$Config{d_link} or -l $srcFile) { - cp($srcFile, $dstFile); - } else { - 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<MANIFEST> unless its already there. - -$file will be normalized (ie. Unixified). B<UNIMPLEMENTED> - -=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} || ''; - if ($file =~ /\s/) { - $file =~ s/([\\'])/\\$1/g; - $file = "'$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 = <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<foo/bar> style not F<foo\bar>. - -Anything between white space and an end of line within a C<MANIFEST> -file is considered to be a comment. Any line beginning with # is also -a comment. Beginning with ExtUtils::Manifest 1.52, a filename may -contain whitespace characters if it is enclosed in single quotes; single -quotes or backslashes in that filename must be backslash-escaped. - - # this a comment - some/file - some/other/file comment about some/file - 'some/third file' comment - - -=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. - -In one's own MANIFEST.SKIP file, certain directives -can be used to include the contents of other MANIFEST.SKIP -files. At present two such directives are recognized. - -=over 4 - -=item #!include_default - -This inserts the contents of the default MANIFEST.SKIP file - -=item #!include /Path/to/another/manifest.skip - -This inserts the contents of the specified external file - -=back - -The included contents will be inserted into the MANIFEST.SKIP -file in between I<#!start included /path/to/manifest.skip> -and I<#!end included /path/to/manifest.skip> markers. -The original MANIFEST.SKIP is saved as MANIFEST.SKIP.bak. - -=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<MANIFEST>. Changing it -results in both a different C<MANIFEST> and a different -C<MANIFEST.SKIP> 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<STDERR>. - -=over 4 - -=item C<Not in MANIFEST:> I<file> - -is reported if a file is found which is not in C<MANIFEST>. - -=item C<Skipping> I<file> - -is reported if a file is skipped due to an entry in C<MANIFEST.SKIP>. - -=item C<No such file:> I<file> - -is reported if a file mentioned in a C<MANIFEST> file does not -exist. - -=item C<MANIFEST:> I<$!> - -is reported if C<MANIFEST> could not be opened. - -=item C<Added to MANIFEST:> I<file> - -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<PERL_MM_MANIFEST_DEBUG> - -Turns on debugging - -=back - -=head1 SEE ALSO - -L<ExtUtils::MakeMaker> which has handy targets for most of the functionality. - -=head1 AUTHOR - -Andreas Koenig C<andreas.koenig@anima.de> - -Maintained by Michael G Schwern C<schwern@pobox.com> within the -ExtUtils-MakeMaker package and, as a separate CPAN package, by -Randy Kobes C<r.kobes@uwinnipeg.ca>. - -=cut - -1; diff --git a/lib/ExtUtils/t/Manifest.t b/lib/ExtUtils/t/Manifest.t deleted file mode 100644 index 3aca61dfbf..0000000000 --- a/lib/ExtUtils/t/Manifest.t +++ /dev/null @@ -1,417 +0,0 @@ -#!/usr/bin/perl -w - -BEGIN { - if( $ENV{PERL_CORE} ) { - chdir 't' if -d 't'; - unshift @INC, '../lib'; - } - else { - unshift @INC, 't/lib'; - } -} -chdir 't'; - -use strict; - -use Test::More tests => 94; -use Cwd; - -use File::Spec; -use File::Path; -use File::Find; -use Config; - -my $Is_VMS = $^O eq 'VMS'; -my $Is_VMS_noefs = $Is_VMS; -if ($Is_VMS) { - my $vms_efs = 0; - if (eval 'require VMS::Feature') { - $vms_efs = VMS::Feature::current("efs_charset"); - } else { - my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || ''; - $vms_efs = $efs_charset =~ /^[ET1]/i; - } - $Is_VMS_noefs = 0 if $vms_efs; -} - - -# We're going to be chdir'ing and modules are sometimes loaded on the -# fly in this test, so we need an absolute @INC. -@INC = map { File::Spec->rel2abs($_) } @INC; - -# keep track of everything added so it can all be deleted -my %Files; -sub add_file { - my ($file, $data) = @_; - $data ||= 'foo'; - 1 while unlink $file; # or else we'll get multiple versions on VMS - open( T, '> '.$file) or return; - print T $data; - close T; - return 0 unless -e $file; # exists under the name we gave it ? - ++$Files{$file}; -} - -sub read_manifest { - open( M, 'MANIFEST' ) or return; - chomp( my @files = <M> ); - close M; - return @files; -} - -sub catch_warning { - my $warn = ''; - local $SIG{__WARN__} = sub { $warn .= $_[0] }; - return join('', $_[0]->() ), $warn; -} - -sub remove_dir { - ok( rmdir( $_ ), "remove $_ directory" ) for @_; -} - -# use module, import functions -BEGIN { - use_ok( 'ExtUtils::Manifest', - qw( mkmanifest manicheck filecheck fullcheck - maniread manicopy skipcheck maniadd maniskip) ); -} - -my $cwd = Cwd::getcwd(); - -# Just in case any old files were lying around. -rmtree('mantest'); - -ok( mkdir( 'mantest', 0777 ), 'make mantest directory' ); -ok( chdir( 'mantest' ), 'chdir() to mantest' ); -ok( add_file('foo'), 'add a temporary file' ); - -# This ensures the -x check for manicopy means something -# Some platforms don't have chmod or an executable bit, in which case -# this call will do nothing or fail, but on the platforms where chmod() -# works, we test the executable bit is copied -chmod( 0744, 'foo') if $Config{'chmod'}; - -# there shouldn't be a MANIFEST there -my ($res, $warn) = catch_warning( \&mkmanifest ); -# Canonize the order. -$warn = join("", map { "$_|" } - sort { lc($a) cmp lc($b) } split /\r?\n/, $warn); -is( $warn, "Added to MANIFEST: foo|Added to MANIFEST: MANIFEST|", - "mkmanifest() displayed its additions" ); - -# and now you see it -ok( -e 'MANIFEST', 'create MANIFEST file' ); - -my @list = read_manifest(); -is( @list, 2, 'check files in MANIFEST' ); -ok( ! ExtUtils::Manifest::filecheck(), 'no additional files in directory' ); - -# after adding bar, the MANIFEST is out of date -ok( add_file( 'bar' ), 'add another file' ); -ok( ! manicheck(), 'MANIFEST now out of sync' ); - -# it reports that bar has been added and throws a warning -($res, $warn) = catch_warning( \&filecheck ); - -like( $warn, qr/^Not in MANIFEST: bar/, 'warning that bar has been added' ); -is( $res, 'bar', 'bar reported as new' ); - -# now quiet the warning that bar was added and test again -($res, $warn) = do { local $ExtUtils::Manifest::Quiet = 1; - catch_warning( \&skipcheck ) - }; -is( $warn, '', 'disabled warnings' ); - -# add a skip file with a rule to skip itself (and the nonexistent glob '*baz*') -add_file( 'MANIFEST.SKIP', "baz\n.SKIP" ); - -# this'll skip the new file -($res, $warn) = catch_warning( \&skipcheck ); -like( $warn, qr/^Skipping MANIFEST\.SKIP/i, 'got skipping warning' ); - -my @skipped; -catch_warning( sub { - @skipped = skipcheck() -}); - -is( join( ' ', @skipped ), 'MANIFEST.SKIP', 'listed skipped files' ); - -{ - local $ExtUtils::Manifest::Quiet = 1; - is( join(' ', filecheck() ), 'bar', 'listing skipped with filecheck()' ); -} - -# add a subdirectory and a file there that should be found -ok( mkdir( 'moretest', 0777 ), 'created moretest directory' ); -add_file( File::Spec->catfile('moretest', 'quux'), 'quux' ); -ok( exists( ExtUtils::Manifest::manifind()->{'moretest/quux'} ), - "manifind found moretest/quux" ); - -# only MANIFEST and foo are in the manifest -$_ = 'foo'; -my $files = maniread(); -is( keys %$files, 2, 'two files found' ); -is( join(' ', sort { lc($a) cmp lc($b) } keys %$files), 'foo MANIFEST', - 'both files found' ); -is( $_, 'foo', q{maniread() doesn't clobber $_} ); - -ok( mkdir( 'copy', 0777 ), 'made copy directory' ); - -# Check that manicopy copies files. -manicopy( $files, 'copy', 'cp' ); -my @copies = (); -find( sub { push @copies, $_ if -f }, 'copy' ); -@copies = map { s/\.$//; $_ } @copies if $Is_VMS; # VMS likes to put dots on - # the end of files. -# Have to compare insensitively for non-case preserving VMS -is_deeply( [sort map { lc } @copies], [sort map { lc } keys %$files] ); - -# cp would leave files readonly, so check permissions. -foreach my $orig (@copies) { - my $copy = "copy/$orig"; - ok( -r $copy, "$copy: must be readable" ); - is( -w $copy, -w $orig, " writable if original was" ); - is( -x $copy, -x $orig, " executable if original was" ); -} -rmtree('copy'); - - -# poison the manifest, and add a comment that should be reported -add_file( 'MANIFEST', 'none #none' ); -is( ExtUtils::Manifest::maniread()->{none}, '#none', - 'maniread found comment' ); - -ok( mkdir( 'copy', 0777 ), 'made copy directory' ); -$files = maniread(); -eval { (undef, $warn) = catch_warning( sub { - manicopy( $files, 'copy', 'cp' ) }) -}; - -# a newline comes through, so get rid of it -chomp($warn); -# the copy should have given a warning -like($warn, qr/^none not found/, 'carped about none' ); -($res, $warn) = catch_warning( \&skipcheck ); -like($warn, qr/^Skipping MANIFEST.SKIP/i, 'warned about MANIFEST.SKIP' ); - -# tell ExtUtils::Manifest to use a different file -{ - local $ExtUtils::Manifest::MANIFEST = 'albatross'; - ($res, $warn) = catch_warning( \&mkmanifest ); - like( $warn, qr/Added to albatross: /, 'using a new manifest file' ); - - # add the new file to the list of files to be deleted - $Files{'albatross'}++; -} - - -# Make sure MANIFEST.SKIP is using complete relative paths -add_file( 'MANIFEST.SKIP' => "^moretest/q\n" ); - -# This'll skip moretest/quux -($res, $warn) = catch_warning( \&skipcheck ); -like( $warn, qr{^Skipping moretest/quux$}i, 'got skipping warning again' ); - - -# There was a bug where entries in MANIFEST would be blotted out -# by MANIFEST.SKIP rules. -add_file( 'MANIFEST.SKIP' => 'foo' ); -add_file( 'MANIFEST' => "foobar\n" ); -add_file( 'foobar' => '123' ); -($res, $warn) = catch_warning( \&manicheck ); -is( $res, '', 'MANIFEST overrides MANIFEST.SKIP' ); -is( $warn, '', 'MANIFEST overrides MANIFEST.SKIP, no warnings' ); - -$files = maniread; -ok( !$files->{wibble}, 'MANIFEST in good state' ); -maniadd({ wibble => undef }); -maniadd({ yarrow => "hock" }); -$files = maniread; -is( $files->{wibble}, '', 'maniadd() with undef comment' ); -is( $files->{yarrow}, 'hock',' with comment' ); -is( $files->{foobar}, '', ' preserved old entries' ); - -my %funky_files; -# test including a filename with a space -SKIP: { - add_file( 'foo bar' => "space" ) - or skip "couldn't create spaced test file", 2; - local $ExtUtils::Manifest::MANIFEST = "albatross"; - maniadd({ 'foo bar' => "contains space"}); - is( maniread()->{'foo bar'}, "contains space", - 'spaced manifest filename' ); - add_file( 'albatross.bak', '' ); - ($res, $warn) = catch_warning( \&mkmanifest ); - like( $warn, qr/\A(Added to.*\n)+\z/m, - 'no warnings about funky filename' ); - $funky_files{'space'} = 'foo bar'; -} - -# test including a filename with a space and a quote -SKIP: { - add_file( 'foo\' baz\'quux' => "quote" ) - or skip "couldn't create quoted test file", 1; - local $ExtUtils::Manifest::MANIFEST = "albatross"; - maniadd({ 'foo\' baz\'quux' => "contains quote"}); - is( maniread()->{'foo\' baz\'quux'}, "contains quote", - 'quoted manifest filename' ); - $funky_files{'space_quote'} = 'foo\' baz\'quux'; -} - -# test including a filename with a space and a backslash -SKIP: { - add_file( 'foo bar\\baz' => "backslash" ) - or skip "couldn't create backslash test file", 1; - local $ExtUtils::Manifest::MANIFEST = "albatross"; - maniadd({ 'foo bar\\baz' => "contains backslash"}); - is( maniread()->{'foo bar\\baz'}, "contains backslash", - 'backslashed manifest filename' ); - $funky_files{'space_backslash'} = 'foo bar\\baz'; -} - -# test including a filename with a space, quote, and a backslash -SKIP: { - add_file( 'foo bar\\baz\'quux' => "backslash/quote" ) - or skip "couldn't create backslash/quote test file", 1; - local $ExtUtils::Manifest::MANIFEST = "albatross"; - maniadd({ 'foo bar\\baz\'quux' => "backslash and quote"}); - is( maniread()->{'foo bar\\baz\'quux'}, "backslash and quote", - 'backslashed and quoted manifest filename' ); - $funky_files{'space_quote_backslash'} = 'foo bar\\baz\'quux'; -} - -my @funky_keys = qw(space space_quote space_backslash space_quote_backslash); -# test including an external manifest.skip file in MANIFEST.SKIP -{ - maniadd({ foo => undef , albatross => undef, - 'mymanifest.skip' => undef, 'mydefault.skip' => undef}); - for (@funky_keys) { - maniadd( {$funky_files{$_} => $_} ) if defined $funky_files{$_}; - } - - add_file('mymanifest.skip' => "^foo\n"); - add_file('mydefault.skip' => "^my\n"); - local $ExtUtils::Manifest::DEFAULT_MSKIP = - File::Spec->catfile($cwd, qw(mantest mydefault.skip)); - my $skip = File::Spec->catfile($cwd, qw(mantest mymanifest.skip)); - add_file('MANIFEST.SKIP' => - "albatross\n#!include $skip\n#!include_default"); - my ($res, $warn) = catch_warning( \&skipcheck ); - for (qw(albatross foo foobar mymanifest.skip mydefault.skip)) { - like( $warn, qr/Skipping \b$_\b/, - "Skipping $_" ); - } - for my $funky_key (@funky_keys) { - SKIP: { - my $funky_file = $funky_files{$funky_key}; - skip "'$funky_key' not created", 1 unless $funky_file; - like( $warn, qr/Skipping \b\Q$funky_file\E\b/, - "Skipping $funky_file"); - } - } - ($res, $warn) = catch_warning( \&mkmanifest ); - for (qw(albatross foo foobar mymanifest.skip mydefault.skip)) { - like( $warn, qr/Removed from MANIFEST: \b$_\b/, - "Removed $_ from MANIFEST" ); - } - for my $funky_key (@funky_keys) { - SKIP: { - my $funky_file = $funky_files{$funky_key}; - skip "'$funky_key' not created", 1 unless $funky_file; - like( $warn, qr/Removed from MANIFEST: \b\Q$funky_file\E\b/, - "Removed $funky_file from MANIFEST"); - } - } - my $files = maniread; - ok( ! exists $files->{albatross}, 'albatross excluded via MANIFEST.SKIP' ); - ok( exists $files->{yarrow}, 'yarrow included in MANIFEST' ); - ok( exists $files->{bar}, 'bar included in MANIFEST' ); - ok( ! exists $files->{foobar}, 'foobar excluded via mymanifest.skip' ); - ok( ! exists $files->{foo}, 'foo excluded via mymanifest.skip' ); - ok( ! exists $files->{'mymanifest.skip'}, - 'mymanifest.skip excluded via mydefault.skip' ); - ok( ! exists $files->{'mydefault.skip'}, - 'mydefault.skip excluded via mydefault.skip' ); - - # test exclusion of funky files - for my $funky_key (@funky_keys) { - SKIP: { - my $funky_file = $funky_files{$funky_key}; - skip "'$funky_key' not created", 1 unless $funky_file; - ok( ! exists $files->{$funky_file}, - "'$funky_file' excluded via mymanifest.skip" ); - } - } - - # tests for maniskip - my $skipchk = maniskip(); - is ( $skipchk->('albatross'), 1, - 'albatross excluded via MANIFEST.SKIP' ); - is( $skipchk->('yarrow'), '', - 'yarrow included in MANIFEST' ); - is( $skipchk->('bar'), '', - 'bar included in MANIFEST' ); - $skipchk = maniskip('mymanifest.skip'); - is( $skipchk->('foobar'), 1, - 'foobar excluded via mymanifest.skip' ); - is( $skipchk->('foo'), 1, - 'foo excluded via mymanifest.skip' ); - is( $skipchk->('mymanifest.skip'), '', - 'mymanifest.skip included via mydefault.skip' ); - is( $skipchk->('mydefault.skip'), '', - 'mydefault.skip included via mydefault.skip' ); - $skipchk = maniskip('mydefault.skip'); - is( $skipchk->('foobar'), '', - 'foobar included via mydefault.skip' ); - is( $skipchk->('foo'), '', - 'foo included via mydefault.skip' ); - is( $skipchk->('mymanifest.skip'), 1, - 'mymanifest.skip excluded via mydefault.skip' ); - is( $skipchk->('mydefault.skip'), 1, - 'mydefault.skip excluded via mydefault.skip' ); - - my $extsep = $Is_VMS_noefs ? '_' : '.'; - $Files{"$_.bak"}++ for ('MANIFEST', "MANIFEST${extsep}SKIP"); -} - -add_file('MANIFEST' => 'Makefile.PL'); -maniadd({ foo => 'bar' }); -$files = maniread; -# VMS downcases the MANIFEST. We normalize it here to match. -%$files = map { (lc $_ => $files->{$_}) } keys %$files; -my %expect = ( 'makefile.pl' => '', - 'foo' => 'bar' - ); -is_deeply( $files, \%expect, 'maniadd() vs MANIFEST without trailing newline'); - -#add_file('MANIFEST' => 'Makefile.PL'); -#maniadd({ foo => 'bar' }); - -SKIP: { - chmod( 0400, 'MANIFEST' ); - skip "Can't make MANIFEST read-only", 2 if -w 'MANIFEST'; - - eval { - maniadd({ 'foo' => 'bar' }); - }; - is( $@, '', "maniadd() won't open MANIFEST if it doesn't need to" ); - - eval { - maniadd({ 'grrrwoof' => 'yippie' }); - }; - like( $@, qr/^\Qmaniadd() could not open MANIFEST:\E/, - "maniadd() dies if it can't open the MANIFEST" ); - - chmod( 0600, 'MANIFEST' ); -} - - -END { - is( unlink( keys %Files ), keys %Files, 'remove all added files' ); - remove_dir( 'moretest', 'copy' ); - - # now get rid of the parent directory - ok( chdir( $cwd ), 'return to parent directory' ); - remove_dir( 'mantest' ); -} - |