#!/usr/bin/perl our $ID = q$Id: check-dist,v 1.6 2015/04/27 00:34:25 eagle Exp $; # # check-dist -- Compare two directories for distribution completeness. # # With Automake make dist, all of the files to include in the distribution # that aren't installed or source files have to be explicitly listed. This # tends to be quite a lot, so this script compares a build tree to the # unpacked distribution tarball to see if everything was included. # # Having something present in the distribution that isn't in the build tree is # fine; that can happen if one is comparing with a fresh checkout. # # If the source tree isn't given on the command line, the current directory is # used. # # Written by Russ Allbery # Copyright 2009, 2011, 2013 # The Board of Trustees of the Leland Stanford Junior University # # This program is free software; you may redistribute it and/or modify it # under the same terms as Perl itself. ############################################################################## # Modules and configuration ############################################################################## require 5.006; use Archive::Tar (); use File::Find qw(find); use Getopt::Long qw(GetOptions); # The list of files in the source tree to ignore (in other words, we don't # care whether they're included in the distribution). This is a list of # regular expressions that match the file name (not the full file path). our @IGNORE = (qr/^config\.h\.in~\z/, qr/\.tar\.gz\z/, qr/^\.travis\.yml\z/); # The list of files in the source tree to prune. This means that if this # matches a directory name, both that directory and everything below it will # be ignored. These match the full file path relative to the top diretory, # not just the file name. our @PRUNE = (qr/^\.git\z/, qr/^autom4te\.cache\z/, qr,^tests/config\z,); ############################################################################## # Implementation ############################################################################## # Check for command-line options. my ($help, $version); Getopt::Long::config ('bundling', 'no_ignore_case'); GetOptions ('h|help' => \$help, 'v|version' => \$version) or exit 1; if ($help) { print "Feeding myself to perldoc, please wait....\n"; exec ('perldoc', '-t', $0); } elsif ($version) { my $version = join (' ', (split (' ', $ID))[1..3]); $version =~ s/,v\b//; $version =~ s/(\S+)$/($1)/; $version =~ tr%/%-%; print $version, "\n"; exit; } unless (@ARGV) { die "Usage: check-dist []\n"; } my ($tar, $source) = @ARGV; $source = '.' unless $source; # Build a hash of all files in the source tree except directories and those # we're ignoring. my %files; my $wanted = sub { return if ($_ eq '.' or $_ eq '..'); my $file = $_; my $name = $File::Find::name; $name =~ s,^\Q$source/,,; return unless $name; if (grep { $name =~ /$_/ } @PRUNE) { $File::Find::prune = 1; return; } return if -d $file; return if grep { $file =~ /$_/ } @IGNORE; $files{$name} = 1; }; find ($wanted, $source); # Walk through the list of all files in the tarball and remove those files # from the hash of files in the source tree. When we're done, what will be # left in the hash is only those files present in the source tree but not in # the tarball. my $archive = Archive::Tar->new ($tar); for my $file ($archive->list_files) { $file =~ s,^[^/]*/,,; delete $files{$file}; } # Report all of the missing files. my $seen = 0; for my $file (sort keys %files) { unless ($seen) { print "Files found in local tree but not in distribution:\n"; $seen = 1; } print " $file\n"; } ############################################################################## # Documentation ############################################################################## =head1 NAME check-dist - Check a dist tarball for completeness =head1 SYNOPSIS B [B<-hv>] I [I] =head1 REQUIREMENTS Perl 5.006 or later and the Archive::Tar module, which is included with Perl as of 5.10 or is available separately from CPAN. Under most circumstances, the tarball will be compressed with gzip, which will additionally requires the IO::Zlib module, also included in Perl as of 5.10 or available separately from CPAN. =head1 DESCRIPTION With Automake make dist, all of the files to include in the distribution that aren't installed or source files have to be explicitly listed. It's easy to miss documentation or parts of test cases. This script compares a source directory to the unpacked distribution tarball to see if everything was included. Any files found in the source directory but not in the tarball are reported except for those excluded by the configuration at the top of this script. Normally, one wants to run C or the equivalent in the source directory before running this script. Having something present in the distribution that isn't in the build tree is fine; that can happen if one is comparing with a fresh checkout. If the source tree isn't given on the command line, the current directory is used. F<.git> and F and anything beneath them are ignored when looking for files not present in the distribution. =head1 OPTIONS =over 4 =item B<-h>, B<--help> Print out this documentation (which is done simply by feeding the script to C). =item B<-v>, B<--version> Print out the version of B and exit. =back =head1 SEE ALSO The current version of this script is available from Russ Allbery's script page at L. =head1 AUTHOR Russ Allbery =head1 COPYRIGHT AND LICENSE Copyright 2009, 2011 The Board of Trustees of the Leland Stanford Junior University. This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. =cut