summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <rra@cpan.org>2022-01-16 22:02:11 -0800
committerRuss Allbery <rra@cpan.org>2022-01-16 22:02:11 -0800
commit306dd37d3c86b903f34f7db188819d5db3bd1f5b (patch)
tree5492fb8f248470ab030cd70a3e8ea054d9710edd
parent6505e90ea753952f08d8c116e8a328b45096e120 (diff)
Convert App::DocKnot::Dist to Path::Tiny
Use latest_tarball from App::DocKnot::Util instead of rolling its own version of the same logic. It's a bit less efficient due to the extra stat calls, but it shouldn't matter.
-rw-r--r--lib/App/DocKnot/Dist.pm105
1 files changed, 45 insertions, 60 deletions
diff --git a/lib/App/DocKnot/Dist.pm b/lib/App/DocKnot/Dist.pm
index ccbeff4..5d1c684 100644
--- a/lib/App/DocKnot/Dist.pm
+++ b/lib/App/DocKnot/Dist.pm
@@ -17,12 +17,10 @@ use autodie;
use warnings;
use App::DocKnot::Config;
+use App::DocKnot::Util qw(latest_tarball print_checked);
use Archive::Tar ();
use Carp qw(croak);
-use Cwd qw(getcwd);
-use File::Copy qw(move);
use File::Find qw(find);
-use File::Path qw(remove_tree);
use Git::Repository ();
use IO::Compress::Xz ();
use IO::Uncompress::Gunzip ();
@@ -30,6 +28,7 @@ use IPC::Run qw(run);
use IPC::System::Simple qw(systemx);
use List::SomeUtils qw(lastval);
use List::Util qw(any first);
+use Path::Tiny qw(path);
# Base commands to run for various types of distributions. Additional
# variations may be added depending on additional configuration parameters.
@@ -113,6 +112,11 @@ sub _expected_dist_files {
# Find all files in the source directory, stripping its path from the file
# name and excluding (and pruning) anything matching @DIST_IGNORE or in
# the distribution/ignore key of the package configuration.
+ #
+ # This uses File::Find rather than Path::Iterator::Rule like other parts
+ # of DocKnot because the ignore patterns are based on the whole path
+ # relative to the top of the distribution, and that's more annoying to do
+ # with Path::Iterator::Rule.
my $wanted = sub {
my $name = $File::Find::name;
$name =~ s{ \A \Q$path\E / }{}xms;
@@ -126,7 +130,7 @@ sub _expected_dist_files {
};
# Generate and return the list of files.
- find($wanted, $path);
+ find($wanted, "$path");
return @files;
}
@@ -135,31 +139,16 @@ sub _expected_dist_files {
# $path - The directory path
# $prefix - The tarball file prefix
#
-# Returns: The full path to the gzip tarball
+# Returns: The path to the gzip tarball
# Throws: Text exception if no gzip tarball was found
sub _find_gzip_tarball {
my ($self, $path, $prefix) = @_;
- my @files = $self->_find_matching_tarballs($path, $prefix);
- my $gzip_file = lastval { m{ [.]tar [.]gz \z }xms } @files;
+ my $files_ref = latest_tarball($path, $prefix)->{files};
+ my $gzip_file = lastval { m{ [.]tar [.]gz \z }xms } $files_ref->@*;
if (!defined($gzip_file)) {
die "cannot find gzip tarball for $prefix in $path\n";
}
- return File::Spec->catfile($path, $gzip_file);
-}
-
-# Find matching tarballs given a directory and a prefix.
-#
-# $path - The directory path
-# $prefix - The tarball file prefix
-#
-# Returns: All matching files, without the directory name, as a list
-sub _find_matching_tarballs {
- my ($self, $path, $prefix) = @_;
- my $pattern = qr{ \A \Q$prefix\E - \d.* [.]tar [.][xg]z \z }xms;
- opendir(my $source, $path);
- my @files = grep { $_ =~ $pattern } readdir($source);
- closedir($source);
- return @files;
+ return $path->child($gzip_file);
}
# Given a directory and a prefix for tarballs in that directory, ensure that
@@ -172,17 +161,15 @@ sub _find_matching_tarballs {
# Throws: Text exception on failure to read or write compressed files.
sub _generate_compression_formats {
my ($self, $path, $prefix) = @_;
- my @files = $self->_find_matching_tarballs($path, $prefix);
- if (!any { m{ [.]tar [.]xz \z }xms } @files) {
- my $gzip_file = lastval { m{ [.]tar [.]gz \z }xms } @files;
- my $xz_file = $gzip_file;
- $xz_file =~ s{ [.]gz \z }{.xz}xms;
- my $gzip_path = File::Spec->catfile($path, $gzip_file);
- my $xz_path = File::Spec->catfile($path, $xz_file);
+ my $files_ref = latest_tarball($path, $prefix)->{files};
+ if (!any { m{ [.]tar [.]xz \z }xms } $files_ref->@*) {
+ my $gzip_file = lastval { m{ [.]tar [.]gz \z }xms } $files_ref->@*;
+ my $gzip_path = $path->child($gzip_file);
+ my $xz_path = $path->child($gzip_path->basename('.gz') . '.xz');
# Open the input and output files.
- my $gzip_fh = IO::Uncompress::Gunzip->new($gzip_path);
- my $xz_fh = IO::Compress::Xz->new($xz_path);
+ my $gzip_fh = IO::Uncompress::Gunzip->new("$gzip_path");
+ my $xz_fh = IO::Compress::Xz->new("$xz_path");
# Read from the gzip file and write to the xz-compressed file.
my $buffer;
@@ -207,11 +194,9 @@ sub _generate_compression_formats {
# Text exception on failure to move a file
sub _move_tarballs {
my ($self, $source_path, $prefix, $dest_path) = @_;
- my @files = $self->_find_matching_tarballs($source_path, $prefix);
- for my $file (@files) {
- my $source_file = File::Spec->catfile($source_path, $file);
- move($source_file, $dest_path)
- or die "cannot move $source_file to $dest_path: $!\n";
+ my $files_ref = latest_tarball($source_path, $prefix)->{files};
+ for my $file ($files_ref->@*) {
+ $source_path->child($file)->move($dest_path->child($file));
}
return;
}
@@ -244,9 +229,9 @@ sub _replace_perl_path {
# Throws: Text exception on failure to sign the file
sub _sign_tarballs {
my ($self, $path, $prefix) = @_;
- my @files = $self->_find_matching_tarballs($path, $prefix);
- for my $file (@files) {
- my $tarball_path = File::Spec->catdir($path, $file);
+ my $files_ref = latest_tarball($path, $prefix)->{files};
+ for my $file (grep { m{ [.]tar [.][xg]z }xms } $files_ref->@*) {
+ my $tarball_path = $path->child($file);
systemx(
$self->{gpg}, '--detach-sign', '--armor', '-u',
$self->{pgp_key}, $tarball_path,
@@ -296,7 +281,7 @@ sub new {
#<<<
my $self = {
config => $config_reader->config(),
- distdir => $distdir,
+ distdir => path($distdir),
gpg => $args_ref->{gpg} // 'gpg',
perl => $args_ref->{perl},
pgp_key => $args_ref->{pgp_key} // $global_config_ref->{pgp_key},
@@ -318,8 +303,8 @@ sub new {
# means all expected files were found)
sub check_dist {
my ($self, $source, $tarball) = @_;
- my @expected = $self->_expected_dist_files(getcwd());
- my %expected = map { $_ => 1 } @expected;
+ my @expected = $self->_expected_dist_files(path(q{.}));
+ my %expected = map { ("$_", 1) } @expected;
my $archive = Archive::Tar->new($tarball);
for my $file ($archive->list_files()) {
$file =~ s{ \A [^/]* / }{}xms;
@@ -380,20 +365,21 @@ sub make_distribution {
my ($self) = @_;
# Determine the source directory and the distribution directory name.
- my $source = getcwd() or die "cannot get current directory: $!\n";
+ my $source = path(q{.})->realpath();
my $prefix = $self->{config}{distribution}{tarname};
# If the distribution directory name already exists, remove it. Automake
# may have made parts of it read-only, so be forceful in the removal.
- # Note that this does not pass the safe parameter and therefore should not
- # be called on attacker-controlled directories.
+ # Note that this disables safe mode and therefore should not be called on
+ # attacker-controlled directories.
chdir($self->{distdir});
- if (-d $prefix) {
- remove_tree($prefix);
+ my $workdir = path($prefix);
+ if ($workdir->is_dir()) {
+ $workdir->remove_tree({ safe => 0 });
}
# Export the Git repository into a new directory.
- my $repo = Git::Repository->new(work_tree => $source);
+ my $repo = Git::Repository->new(work_tree => "$source");
my @branches = $repo->run(
'for-each-ref' => '--format=%(refname:short)', 'refs/heads/',
);
@@ -408,31 +394,29 @@ sub make_distribution {
}
# Change to that directory and run the configured commands.
- chdir($prefix);
+ chdir($workdir);
for my $command_ref ($self->commands()) {
systemx($command_ref->@*);
}
# Move the generated tarball to the parent directory.
- $self->_move_tarballs(File::Spec->curdir(), $prefix, File::Spec->updir());
+ $self->_move_tarballs(path(q{.}), $prefix, $self->{distdir});
# Remove the working tree.
- chdir(File::Spec->updir());
- remove_tree($prefix, { safe => 1 });
+ chdir($self->{distdir});
+ $workdir->remove_tree();
# Generate additional compression formats if needed.
- $self->_generate_compression_formats(getcwd(), $prefix);
+ $self->_generate_compression_formats($self->{distdir}, $prefix);
# Check the distribution for any missing files. If there are any, report
# them and then fail with an error.
- my $tarball = $self->_find_gzip_tarball(getcwd(), $prefix);
+ my $tarball = $self->_find_gzip_tarball($self->{distdir}, $prefix);
chdir($source);
my @missing = $self->check_dist($source, $tarball);
if (@missing) {
- print "Files found in local tree but not in distribution:\n"
- or die "cannot print to stdout: $!\n";
- print q{ } . join(qq{\n }, @missing) . "\n"
- or die "cannot print to stdout: $!\n";
+ print_checked("Files found in local tree but not in distribution:\n");
+ print_checked(q{ }, join(qq{\n }, @missing), "\n");
my $count = scalar(@missing);
my $files = ($count == 1) ? '1 file' : "$count files";
die "$files missing from distribution\n";
@@ -472,7 +456,8 @@ App::DocKnot::Dist - Prepare a distribution tarball
Git, Perl 5.24 or later, and the modules File::BaseDir, File::ShareDir,
Git::Repository, IO::Compress::Xz (part of IO-Compress-Lzma),
IO::Uncompress::Gunzip (part of IO-Compress), IPC::Run, IPC::System::Simple,
-Kwalify, List::SomeUtils, and YAML::XS, all of which are available from CPAN.
+Kwalify, List::SomeUtils, Path::Tiny, and YAML::XS, all of which are available
+from CPAN.
The tools to build whatever type of software distribution is being prepared
are also required, since the distribution is built and tested as part of