ADAMK-Release
view release on metacpan or search on metacpan
lib/ADAMK/Release.pm view on Meta::CPAN
package ADAMK::Release;
use 5.10.0;
use strict;
use warnings;
use Carp ();
use CPAN::Uploader 0.103003 ();
use Devel::PPPort 3.21 ();
use File::Spec::Functions 0.80 ':ALL';
use File::Slurp 9999.19 ();
use File::Find::Rule 0.32 ();
use File::Flat 1.04 ();
use File::ShareDir 1.03 ();
use File::LocalizeNewlines 1.12 ();
use GitHub::Extract 0.02 ();
use IO::Prompt::Tiny 0.002 ();
use Module::Extract::VERSION 1.01 ();
use Params::Util 1.00 ':ALL';
use Term::ReadKey 2.14 ();
use YAML::Tiny 1.51 ();
our $VERSION = '0.02';
use constant TOOLS => qw{
cat
chmod
make
touch
sudo
bash
};
use Object::Tiny 1.01 qw{
module
github
verbose
release
no_rt
no_changes
no_copyright
no_test
}, map { "bin_$_" } TOOLS;
######################################################################
# Constructor
sub new {
my $self = shift->SUPER::new(@_);
# Check module
unless ( _CLASS($self->module) ) {
$self->error("Missing or invalid module");
}
# Inflate and check the github object
if ( Params::Util::_HASH($self->github) ) {
$self->{github} = GitHub::Extract->new( %{$self->github} );
}
unless ( Params::Util::_INSTANCE($self->github, 'GitHub::Extract')) {
$self->error("Missing or invalid GitHub specification");
}
# Release options
$self->{release} = !!$self->{release};
# Find all of the command line tools
foreach my $tool ( TOOLS ) {
$self->{ "bin_" . $tool } = $self->which($tool);
}
return $self;
}
######################################################################
# Command Methods
sub run {
my $self = shift;
# Export from GitHub and change to the directory
my $pushd = $self->github->pushd;
unless ( $pushd ) {
$self->error(
"Failed to download and extract %s: %s",
$self->github->url,
$self->github->error,
);
}
# This is total bulldozer coding, there is no reason whatsoever why
# this stuff should be in seperate methods except that it provides
lib/ADAMK/Release.pm view on Meta::CPAN
}
unless ( $self->makefile_pl =~ /(?:use|require) \d/ ) {
$self->error("Makefile.PL does not declare a minimum Perl version");
}
}
}
# Check file permissions
foreach my $file ( sort $self->find_0644->in( $self->dist_dir ) ) {
my $mode = (stat($file))[2] & 07777;
next if $mode == 0644;
$self->shell(
$self->bin_chmod,
'0644',
$file,
"Error setting $file to 0644 permissions",
);
}
# Make sure exe files are marked with executable permissions
if ( $self->find_executable->in( $self->dist_dir ) ) {
$self->error("Found at least one .exe file without -x unix permissions");
}
# Check the Changes file
unless ( $self->no_changes ) {
# Read in the Changes file
unless ( -f $self->dist_changes ) {
$self->error("Distribution does not have a Changes file");
}
unless ( open( CHANGES, $self->dist_changes ) ) {
$self->error("Failed to open Changes file");
}
my @lines = <CHANGES>;
close CHANGES;
unless ( @lines >= 3 ) {
$self->error("Changes file is empty or too small");
}
# The Changes version should be the first thing on the third line
my $current = $lines[2];
my ($version) = split /\s+/, $current;
unless ( $version =~ /[\d\._]{3}/ ) {
$self->error(
"Failed to find current version, or too short, in '%2'",
$current,
);
}
# Does it match the version in the main module
unless ( $version eq $self->dist_version ) {
$self->error(
"Version in Changes file (%s) does not match module version (%s)",
$version,
$self->dist_version,
);
}
}
# Check that the main module documentation Copyright is the current year
unless ( $self->no_copyright ) {
# Read the file
unless ( open( MODULE, $self->module_doc ) ) {
$self->error(
"Failed to open '%s'",
$self->module_doc,
);
}
my @lines = <MODULE>;
close MODULE;
# Look for the current year
my $year = 1900 + (localtime time)[5];
unless ( grep { /copyright/i and /$year/ } @lines ) {
$self->error("Missing Copyright, or does not refer to current year");
}
# Merge the module to a single string
my $merged = join "\n", @lines;
unless ( $self->no_rt ) {
my $dist_name = $self->dist;
unless ( $merged =~ /L\<http\:\/\/rt\.cpan\.org\/.+?=([\w-]+)\>/ ) {
$self->error("Failed to find a link to the public RT queue");
}
unless ( $dist_name eq $1 ) {
$self->error("Expected a public link to $dist_name RT queue, but found a link to the $1 queue");
}
}
}
# Touch all files to correct any potential time skews
foreach my $file ( $self->find_files->in( $self->dist_dir ) ) {
$self->shell(
$self->bin_touch,
$file,
"Error while touching $file to prevent clock skew",
);
}
return;
}
sub build {
my $self = shift;
# Prevent environment variables from outside this script
# infecting the way we build things inside here.
local $ENV{AUTOMATED_TESTING} = '';
local $ENV{RELEASE_TESTING} = '';
# Run either of the build protocols
if ( $self->makefile_pl ) {
$self->build_make;
} elsif ( $self->build_pl ) {
$self->build_perl;
} else {
$self->error("Module does not have a Makefile.PL or Build.PL");
}
# Double check that the build produced a tarball where we expect it to be
unless ( -f $self->dist_tardist ) {
$self->error(
"Failed to create tardist at '%s'",
$self->dist_tardist,
);
}
return;
}
sub build_make {
my $self = shift;
( run in 0.897 second using v1.01-cache-2.11-cpan-2398b32b56e )