App-DocKnot
view release on metacpan or search on metacpan
lib/App/DocKnot/Util.pm view on Meta::CPAN
# Shared utility functions for other DocKnot modules.
#
# A collection of random utility functions that are used by more than one
# DocKnot module but don't make sense as App::DocKnot methods.
#
# SPDX-License-Identifier: MIT
##############################################################################
# Modules and declarations
##############################################################################
package App::DocKnot::Util v8.0.1;
use 5.024;
use autodie;
use warnings FATAL => 'utf8';
use Carp qw(croak);
use Exporter qw(import);
use List::SomeUtils qw(all);
use Path::Tiny qw(path);
use Sort::Versions qw(versioncmp);
our @EXPORT_OK = qw(is_newer latest_tarball print_checked print_fh);
##############################################################################
# Public interface
##############################################################################
# Check if a file, which may not exist, is newer than another list of files.
#
# $file - File whose timestamp to compare
# @others - Other files to compare against
#
# Returns: True if $file exists and is newer than @others, false otherwise
sub is_newer {
my ($file, @others) = @_;
return if !$file->exists();
my $file_mtime = $file->stat()->[9];
my @others_mtimes = map { $_->stat()->[9] } @others;
return all { $file_mtime >= $_ } @others_mtimes;
}
# Find the files for a given package with the latest version and return them
# along with some associated metadata.
#
# $path - Path::Tiny path to directory
# $tarname - Name of the tarball before the version component
#
# Returns: Anonymous hash with the following keys:
# version - Latest version found
# files - Array of files for that version
# or undef if no matching files were found
# Throws: Text exception on any error
sub latest_tarball {
my ($path, $tarname) = @_;
# Collect the list of matching files and extract their version numbers.
return if !$path->is_dir();
my $regex = qr{ \A \Q$tarname\E - (v?[\d.]+) [.] }xms;
my @files = map { $_->basename() } $path->children($regex);
my @versions = map { m{ $regex }xms ? [$1, $_] : () } @files;
return if !@versions;
# Find the latest version and filter the list of files down to only that
# version. This will sort versions starting with v later than any version
# that doesn't start with v. This is fine for my purposes right now,
# since the conversion of Perl modules to semantic versions starting with
# v is one-way, but is not generally correct.
@versions = reverse(sort { versioncmp($a->[0], $b->[0]) } @versions);
my $latest = $versions[0][0];
@files = map { $_->[1] } grep { $_->[0] eq $latest } @versions;
# Return the results.
return {
version => $latest,
files => \@files,
};
}
# print with error checking. autodie unfortunately can't help us because
# print can't be prototyped and hence can't be overridden.
#
# @args - Arguments to print to stdout
#
# Returns: undef
# Throws: Text exception on output failure
sub print_checked {
my (@args) = @_;
print @args or croak('print failed');
return;
}
# print with error checking and an explicit file handle. autodie
# unfortunately can't help us because print can't be prototyped and
# hence can't be overridden.
#
# $fh - Output file handle
# $file - File name for error reporting
# @args - Remaining arguments to print
( run in 0.367 second using v1.01-cache-2.11-cpan-39bf76dae61 )