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