1package ExtUtils::Manifest; # git description: 1.71-18-g17b7919 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.72'; 14our @ISA = ('Exporter'); 15our @EXPORT_OK = qw(mkmanifest 16 manicheck filecheck fullcheck skipcheck 17 manifind maniread manicopy maniadd 18 maniskip 19 ); 20 21our $Is_MacOS = $^O eq 'MacOS'; 22our $Is_VMS = $^O eq 'VMS'; 23our $Is_VMS_mode = 0; 24our $Is_VMS_lc = 0; 25our $Is_VMS_nodot = 0; # No dots in dir names or double dots in files 26 27if ($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 53our $Debug = $ENV{PERL_MM_MANIFEST_DEBUG} || 0; 54our $Verbose = defined $ENV{PERL_MM_MANIFEST_VERBOSE} ? 55 $ENV{PERL_MM_MANIFEST_VERBOSE} : 1; 56our $Quiet = 0; 57our $MANIFEST = 'MANIFEST'; 58 59our $DEFAULT_MSKIP = File::Spec->catfile( dirname(__FILE__), "$MANIFEST.SKIP" ); 60 61 62=head1 NAME 63 64ExtUtils::Manifest - Utilities to write and check a MANIFEST file 65 66=head1 VERSION 67 68version 1.72 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 96ExtUtils::Manifest exports no functions by default. The following are 97exported on request: 98 99=head2 mkmanifest 100 101 mkmanifest(); 102 103Writes all files in and below the current directory to your F<MANIFEST>. 104It works similar to the result of the Unix command 105 106 find . > MANIFEST 107 108All files that match any regular expression in a file F<MANIFEST.SKIP> 109(if it exists) are ignored. 110 111Any existing F<MANIFEST> file will be saved as F<MANIFEST.bak>. 112 113=cut 114 115sub _sort { 116 return sort { lc $a cmp lc $b } @_; 117} 118 119sub 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? 162sub 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 182returns a hash reference. The keys of the hash are the files found 183below the current directory. 184 185=cut 186 187sub 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 213checks if all the files within a C<MANIFEST> in the current directory 214really do exist. If C<MANIFEST> and the tree below the current 215directory are in sync it silently returns an empty list. 216Otherwise it returns a list of files which are listed in the 217C<MANIFEST> but missing from the directory, and by default also 218outputs these names to STDERR. 219 220=cut 221 222sub manicheck { 223 return _check_files(); 224} 225 226 227=head2 filecheck 228 229 my @extra_files = filecheck(); 230 231finds files below the current directory that are not mentioned in the 232C<MANIFEST> file. An optional file C<MANIFEST.SKIP> will be 233consulted. Any file matching a regular expression in such a file will 234not be reported as missing in the C<MANIFEST> file. The list of any 235extraneous files found is returned, and by default also reported to 236STDERR. 237 238=cut 239 240sub filecheck { 241 return _check_manifest(); 242} 243 244 245=head2 fullcheck 246 247 my($missing, $extra) = fullcheck(); 248 249does both a manicheck() and a filecheck(), returning then as two array 250refs. 251 252=cut 253 254sub fullcheck { 255 return [_check_files()], [_check_manifest()]; 256} 257 258 259=head2 skipcheck 260 261 my @skipped = skipcheck(); 262 263lists all the files that are skipped due to your C<MANIFEST.SKIP> 264file. 265 266=cut 267 268sub 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 286sub _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 310sub _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 336reads a named C<MANIFEST> file (defaults to C<MANIFEST> in the current 337directory) and returns a HASH reference with files being the keys and 338comments being the values of the HASH. Blank lines and lines which 339start with C<#> in the C<MANIFEST> file are discarded. 340 341=cut 342 343sub 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 405reads a named C<MANIFEST.SKIP> file (defaults to C<MANIFEST.SKIP> in 406the current directory) and returns a CODE reference that tests whether 407a given filename should be skipped. 408 409=cut 410 411# returns an anonymous sub that decides if an argument matches 412sub 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 449sub _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 496sub _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 520Copies the files that are the keys in %src to the $dest_dir. %src is 521typically returned by the maniread() function. 522 523 manicopy( maniread(), $dest_dir ); 524 525This function is useful for producing a directory tree identical to the 526intended distribution tree. 527 528$how can be used to specify a different methods of "copying". Valid 529values are C<cp>, which actually copies the files, C<ln> which creates 530hard links, and C<best> which mostly links the files but copies any 531symbolic link to make a tree without any symbolic link. C<cp> is the 532default. 533 534=cut 535 536sub 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 565sub 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 597sub 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 607sub 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. 623sub _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. 631my @Exceptions = qw(MANIFEST META.yml SIGNATURE); 632sub 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 643sub _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 657sub _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 667sub _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 684Adds 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 690sub 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. 720sub _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 754sub _normalize { 755 return; 756} 757 758=head2 MANIFEST 759 760A list of files in the distribution, one file per line. The MANIFEST 761always uses Unix filepath conventions even if you're not on Unix. This 762means F<foo/bar> style not F<foo\bar>. 763 764Anything between white space and an end of line within a C<MANIFEST> 765file is considered to be a comment. Any line beginning with # is also 766a comment. Beginning with ExtUtils::Manifest 1.52, a filename may 767contain whitespace characters if it is enclosed in single quotes; single 768quotes 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 778The file MANIFEST.SKIP may contain regular expressions of files that 779should be ignored by mkmanifest() and filecheck(). The regular 780expressions should appear one on each line. Blank lines and lines 781which start with C<#> are skipped. Use C<\#> if you need a regular 782expression to start with a C<#>. 783 784For 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 804If no MANIFEST.SKIP file is found, a default set of skips will be 805used, similar to the example above. If you want nothing skipped, 806simply make an empty MANIFEST.SKIP file. 807 808In one's own MANIFEST.SKIP file, certain directives 809can be used to include the contents of other MANIFEST.SKIP 810files. At present two such directives are recognized. 811 812=over 4 813 814=item #!include_default 815 816This inserts the contents of the default MANIFEST.SKIP file 817 818=item #!include /Path/to/another/manifest.skip 819 820This inserts the contents of the specified external file 821 822=back 823 824The included contents will be inserted into the MANIFEST.SKIP 825file in between I<#!start included /path/to/manifest.skip> 826and I<#!end included /path/to/manifest.skip> markers. 827The original MANIFEST.SKIP is saved as MANIFEST.SKIP.bak. 828 829=head2 EXPORT_OK 830 831C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>, 832C<&maniread>, and C<&manicopy> are exportable. 833 834=head2 GLOBAL VARIABLES 835 836C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it 837results in both a different C<MANIFEST> and a different 838C<MANIFEST.SKIP> file. This is useful if you want to maintain 839different distributions for different audiences (say a user version 840and a developer version including RCS). 841 842C<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value, 843all functions act silently. 844 845C<$ExtUtils::Manifest::Debug> defaults to 0. If set to a true value, 846or if PERL_MM_MANIFEST_DEBUG is true, debugging output will be 847produced. 848 849=head1 DIAGNOSTICS 850 851All diagnostic output is sent to C<STDERR>. 852 853=over 4 854 855=item C<Not in MANIFEST:> I<file> 856 857is reported if a file is found which is not in C<MANIFEST>. 858 859=item C<Skipping> I<file> 860 861is reported if a file is skipped due to an entry in C<MANIFEST.SKIP>. 862 863=item C<No such file:> I<file> 864 865is reported if a file mentioned in a C<MANIFEST> file does not 866exist. 867 868=item C<MANIFEST:> I<$!> 869 870is reported if C<MANIFEST> could not be opened. 871 872=item C<Added to MANIFEST:> I<file> 873 874is reported by mkmanifest() if $Verbose is set and a file is added 875to 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 885Turns on debugging 886 887=back 888 889=head1 SEE ALSO 890 891L<ExtUtils::MakeMaker> which has handy targets for most of the functionality. 892 893=head1 AUTHOR 894 895Andreas Koenig C<andreas.koenig@anima.de> 896 897Currently maintained by the Perl Toolchain Gang. 898 899=head1 COPYRIGHT AND LICENSE 900 901This software is copyright (c) 1996- by Andreas Koenig. 902 903This is free software; you can redistribute it and/or modify it under 904the same terms as the Perl 5 programming language system itself. 905 906=cut 907 9081; 909