App-makedist
view release on metacpan or search on metacpan
bin/makedist view on Meta::CPAN
#!/usr/bin/perl
# vim: ft=perl:fdm=marker:fmr=#<,#>:fen:et:sw=2:
package App::makedist;
use strict;
use warnings FATAL => 'all';
use vars qw($VERSION);
use autodie qw(:all);
#< init
$VERSION = '0.026';
sub usage {
pod2usage(
msg => "makedist v$VERSION\n",
verbose => 1,
exitval => 0,
);
}
use Cwd;
use Pod::Usage;
use File::Basename qw(basename);
use File::Copy::Recursive qw(rcopy);
use File::Path qw(rmtree);
use File::LsColor qw(ls_color);
use Term::ExtendedColor qw(fg bg bold);
use Getopt::Long;
use Module::Extract::VERSION;
use File::Find::Rule;
my $opt_verbose = 0;
my $opt_noconfig = 0;
GetOptions(
'noconfig' => \$opt_noconfig,
'v|verbose' => \$opt_verbose,
'h|help' => \&usage,
);
#>
my $MANIFEST = './MANIFEST';
my @files_in_dist;
# load config file
our $command_on_success;
our $finished_product;
config_init() unless $opt_noconfig;
# First we need to make sure that all files that's listed in the MANIFEST
# actually exists.
verify_manifest();
makedist();
sub makedist {
# App-makedist-0.020.tar.gz
my $dist_tar = build_filename();
# App-makedist-0.020
my ($dist_dir) = $dist_tar =~ m/^([a-z0-9.-]+)[.]tar[.]gz$/i;
mkdir $dist_dir or die "Can't mkdir '$dist_dir': $!\n";
# copy all files in the MANIFEST to dist dir, i.e App-makedist-0.020
for my $file(@files_in_dist) {
# make sure to honor the dir structure
if($file =~ m{^(.+)/}) {
if(-d $1) {
rcopy($file, "$dist_dir/$file");
next;
}
}
rcopy($file, $dist_dir) or die "Copy failed: '$file' -> '$dist_dir\n";
}
system('tar', 'czf', $dist_tar, $dist_dir);
if($? == 0) {
printf("- Distribution created: %s\n", ls_color($dist_tar)) if $opt_verbose;
# remove the created dist dir
rmtree($dist_dir) or die "Can't remove '$dist_dir': $!\n";
# all good, execute code from config if defined
# let the config have the value of $dist_tar as a variable
$finished_product = $dist_tar;
if(defined($command_on_success)) {
$command_on_success->();
}
}
}
sub build_filename { #<
my $file;
my $rule = File::Find::Rule->new;
$rule->file;
$rule->name(qr/[.]pm$/);
# try to get $VERSION from a perl module if it exists
$file = ($rule->in(getcwd()))[0];
# and resort to anything in bin/ directory if it fails
if(!$file) {
$file = (glob('./bin/*'))[0];
}
# no lib/**/*.pm and no bin/*, rip :(
die "Can not find any suitable files!\n" if not defined $file;
printf("- Getting \$VERSION from %s...\n",ls_color(basename($file))) if $opt_verbose;
my $dist = get_package_name($file);
printf("- Getting distribution name from %s...\n", ls_color(basename($file))) if $opt_verbose;
my $version = scalar Module::Extract::VERSION->parse_version_safely($file);
printf(" Looks like %s %s\n", bold(fg(214, $dist)), bold($version)) if $opt_verbose;
my $dist_name = sprintf("%s-%s.tar.gz", $dist, $version);
return $dist_name;
}
#>
sub get_package_name { #<
my $file = shift;
my $package;
open(my $fh, '<', $file) or die "Can't open '$file': $!\n";
while(<$fh>) {
chomp;
# package File::LsColor;
# XXX Fix regex, this isn't good
if($_ =~ m/^package\s+(.+);/) {
$package = $1;
$package =~ s/::/-/g;
last;
}
}
# if we can't figure out a package name, the dist probably isn't a perl
# module, so we use the basename of the current working directory and apply the
# App- prefix
# File-LsColor-0.132.tar.gz
# App-makedist-0.012.tar.gz
return (defined $package ? $package : 'App-' . basename(getcwd()));
}
#>
sub verify_manifest { #<
open(my $fh, '<', $MANIFEST) or die "Can't open '$MANIFEST': aborting\n";
print "- Checking file integrity...\n" if $opt_verbose;
while(<$fh>) {
chomp;
# sometimes the MANIFEST contains things like
# MANIFEST\t\t\t this list of files
s/MANIFEST.+$/MANIFEST/;
if(-e $_) {
print ' ' . ok($_) if $opt_verbose;
push(@files_in_dist, $_);
}
else {
printf("%s %s from MANIFEST. Aborting.\n", bold($_), bg('red1', 'MISSING'));
exit;
}
}
if($opt_verbose) {
print " All files in MANIFEST present!\n";
printf(" %d files to be added to distribution.\n", scalar @files_in_dist);
}
}
#>
sub config_init { #< config
my $config;
if(-f "$ENV{XDG_CONFIG_HOME}/makedist/makedist.conf") {
$config = "$ENV{XDG_CONFIG_HOME}/makedist/makedist.conf";
}
elsif(-f "$ENV{HOME}/.makedist.conf") {
$config = "$ENV{HOME}/.makedist.conf";
}
else {
print "makedist: no configuratino file found.\n";
}
require($config);
warn "$@" if $@;
}
#>
sub ok {
my $str = shift;
return sprintf("%4s %s\n", fg('greenyellow', 'OK'), ls_color($str));
}
__END__
=pod
=head1 NAME
makedist - make cpan distribution
=head1 USAGE
makedist [OPTIONS]
=head1 DESCRIPTION
makedist automates the process of creating a distribution to be
uploaded to CPAN.
The MANIFEST file is inspected for files to be included.
We make an attempt to extract the package name from any perl module
file found, and the package name must follow this convention:
( run in 0.563 second using v1.01-cache-2.11-cpan-751830e7986 )