Win32-CommandLine
view release on metacpan or search on metacpan
#!perl -w -- ## emacs -*- tab-width: 4; mode: cperl; indent-tabs-mode: nil; basic-offset: 2 -*- ## (jedit) :tabsize=4:mode=perl: ## (notepad++) vim:ts=4:sw=2:et:sta:sts=2 ## no critic ( CodeLayout::RequireTidyCode Modules::ProhibitExcessMainComplex...
#$Id: Build.PL,v 0.4.1.340 ( r112:594c42f8f73c [mercurial] ) 2013/12/26 05:30:45 rivy $
## no critic ( CodeLayout::ProhibitParensWithBuiltins RequireExtendedFormatting RequireLineBoundaryMatching RequireCarping )
## ToDO: expand upon assert_os to allow or disallow OS subtypes (Win9x, XP, ME, etc)
## TODO?: remove the '_' from the version for output dist files (>> will this cause a problem for PPM or CPAN with some sort of version mismatch between filename and META.yml
## TODO?: .. or just remove VERSION code generating the alpha '_' within the version? does it matter? does the '_' interfere with version comparisons on CPAN?
## ...... these don't seem to be a problem
# ToDO: open a defect ticket about error leakage for checking compiler presence in ExtUtils::CBuilder :: should be done in CBuilder with STDERR redirect
# ToDO: open a defect ticket about error leakage for checking gpg presence in Module::Signature :: should be done in Module::Signature with STDERR redirect
## # EG: #>perl -e "use File::Spec; $n = File::Spec->devnull(); if (qx{gpg --version 2>$n} =~ /GnuPG.*?\s*([0-9.]+)\s*$/m) { $h = $1 } else { $h = qq{NULL}; }; print $h"
## TODO: add an 'upload' action to use cpan_upload... to upload the basic distribution to CPAN
## : depends(testall) without errors
## ToDO: redirect STDERR to STDOUT for skipcheck (currently all output goes to STDERR)
## TODO: flesh out stub documentation for additional custom actions
## TODO: add/check compatibility for use of module PPM when installed (for non-ActiveState perl distributions)
## TODO: bring up to date with most recent META.yml spec and include all fields in DEFAULTS
# refs:
# [META.yml Specification] http://module-build.sourceforge.net/META-spec-current.html
# [Module::Install] http://search.cpan.org/~ADAMK/Module-Install (see README info)
use strict;
use warnings;
use utf8; # script source code is utf8 compatible/encoded ## note: v5.8 syntax per `perlver`
# use 5.008008; # minimum perl version ## v5.8.8 ~ required for decent basic Unicode support
use 5.006001; # v5.6.1: earliest tested version ## v5.5: for AUTHOR and ABSTRACT in Makefile.PL; v5.6: for 'our', three-argument open, indirect filehandles, extended versions for 'use' [ref: http://www.dagolden.com/index.php/369/version-numbers-sho...
use English qw( -no_match_vars ); # enable long-form built-in variable names; '-no_match_vars' avoids regex performance penalty for perl versions <= 5.16
# use lib qw/ inc /;
# use open IN => ":crlf :encoding(utf8)", OUT => ":raw :utf8";
# use open ':std';
# VERSION: major.minor.release[.build]] { minor is ODD => alpha/beta/experimental; minor is EVEN => stable/release }
# generate VERSION from $Version: 0.1.0.198571514 $ SCS tag
# $defaultVERSION :: used to make the VERSION code resilient vs missing keyword expansion
# $generate_alphas :: 0 => generate normal versions; true/non-0 => generate alpha version strings for ODD numbered minor versions
# [NOTE: perl 'Extended Version' (multi-dot) format is preferred and created from any single dotted (major.minor) or non-dotted (major) versions; see 'perldoc version']
use version qw(); our $VERSION; { my $defaultVERSION = '0.4'; my $generate_alphas = 0; $VERSION = ( $defaultVERSION, qw( $Version: 0.4.1.340 $ ))[-2]; if ($VERSION =~ /^\d+([\._]\d+)?$/msx) {$VERSION .= '.0'; if (!defined($1)) {$VERSION .= '.0'}}; if...
use FindBin; () = eval {FindBin::again()}; # FindBin paranoia ## swallow errors for older FindBin without `FindBin::again()`
##- config
my %config;
## config options which are NOT configurable in config file ... ToDO: change to alternate name or use prefix 'ro_...' and logic on read to avoid overwrites
# config must (may?) be done via a local config file [REQUIRED ... ToDO: make OPTIONAL?] ## allows Build.PL to be maintained separately and used without changes between modules
$config{'rc_filename'} = 'Build.PL.config'; ## # configuration file name (in .NET style)
$config{'self_path'} = File::Spec->canonpath( $PROGRAM_NAME );
$config{'self_parent_path'} = File::Spec->canonpath( $FindBin::RealBin );
$config{'dist_path'} = $config{'self_parent_path'};
# Module::Build DEFAULTS [ ** DO NOT CHANGE, use the Build.PL.config to set the values ]
# * required
$config{'dist_name'} = undef;
$config{'dist_abstract'} = undef;
$config{'dist_author'} = undef;
$config{'license'} = undef;
# * optional
$config{'module_name'} = undef; # "primary" module (for construction of README, .packlist, etc); will be calculated/constructed if not defined
$config{'dist_version'} = undef; # will be constructed if not defined
#
$config{'exports_aref'} = undef; # expected symbol table exports (no obvious default; single ARRAY ref for 'default' module, or HASH of ARRAYs to specify multiple modules)
$config{'recommends_href'} = {}; # distribution recommendations (no obvious default)
#return 1 if ((lc($self->{action}) eq 'clean') or (lc($self->{action}) eq 'realclean'));
return $self->SUPER::up_to_date( @_ );
}
};
$code{'ACTION_TRIALaction'} = q{
#[ADD] NEW action = TRIALaction - a trial action for testing purposes
sub ACTION_TRIALaction {
my ($self) = @_;
print "self->dist_name = `$self->dist_name`\n";
print "self->dist_name = `$self->dist_version`\n";
for (sort keys %{$self}) { print "self->{$_} = `$self->{$_}`\n"; }
for (sort keys %{$self->{args}}) {
print "self->{args}{$_} = `$self->{args}{$_}`\n";
};
print "$self->{properties}{tap_harness_args}{formatter_class} = `$self->{properties}{tap_harness_args}{formatter_class}`\n";
for (sort keys %{$self->{properties}}) {
print "self->{properties}{$_} = ". (defined($self->{properties}{$_}) ? (q{`}.$self->{properties}{$_}.q{`}): 'undef' ) . qq{\n};
};
my $n;
my $dist_name = $self->dist_name;
my $dist_version = $self->dist_version;
$n = q{'}.$self->dist_name.q{'};
print "n = $n\n";
$n =~ s/$dist_name/SUB-Dist-Name/g;
print "n = $n\n";
#print "ENVIRONMENT:\n";
#for (sort keys %ENV) { print "$_ = $ENV{$_}\n"; }
}
};
$code{'harness_switches'} = q{
sub harness_switches {
my $self = shift;
my @res = $self->SUPER::harness_switches;
push @res, '-T' if $self->notes('taintcheck');
return @res;
}
};
$code{'ACTION_taint_test'} = q{
#[ADD] NEW action = taint_test - run regression tests (via test) with taint-mode ON
sub ACTION_taint_test {
my $self = shift;
$self->notes('taintcheck' => 1);
$self->ACTION_test( @_ );
}
};
$code{'ACTION_taint_testall'} = q{
#[ADD] NEW action = taint_test - run all regression tests (via testall) with taint-mode ON
sub ACTION_taint_testall {
my $self = shift;
$self->notes('taintcheck' => 1);
$self->ACTION_testall( @_ );
}
};
$code{'ACTION_sign@_sign_dir'} = q{
sub _MY_module_signature_has_gpg {
my $null = File::Spec->devnull();
if (qx{gpg --version 2>$null} =~ /GnuPG.*?\s*([0-9.]+)\s*$/msx) {
return $1
}
else { return; }
}
sub _sign_dir {
my ($self, $dir) = @_;
if (($ENV{AUTOMATED_TESTING} or $ENV{CI}) and (not $ENV{AUTOMATED_SIGNATURE})) {
$self->log_warn("Automated and/or CI testing detected; signing is disabled [to enable: set AUTOMATED_SIGNATURE]\n");
return;
}
unless (eval { require Module::Signature; 1 }) {
$self->log_warn("Missing required Module::Signature; unable to sign the distribution\n");
return;
}
## override Module::Signature (based on VERSION) to quiet _has_gpg()
## : add $Module::Signature::VERSION gating when appropriate (upstream fixed)
## : [2013-12-29] as of v0.69, $Module::Signature has an improved gpg detection routine _which_gpg() which has no error output and detects gpg2, etc
if ( $Module::Signature::VERSION < 0.69 ) {
print "MY_has_gpg\n";
my $codeRef = \&_MY_module_signature_has_gpg;
{no warnings 'redefine';
*Module::Signature::_has_gpg = $codeRef;
}
}
# Add SIGNATURE to the MANIFEST
{
my $manifest = File::Spec->catfile($dir, 'MANIFEST');
die "Signing a distribution requires a MANIFEST file\n" unless -e $manifest;
#$self->_add_to_manifest($manifest, "SIGNATURE Added here by Module::Build");
#[CHANGED] == removed comment to prevent altering MANIFEST, when possible (to preserve correct signatures as long as possible)
$self->_add_to_manifest($manifest, 'SIGNATURE'); # NO comment, just the filename; comments can alter the MANIFEST when/if it is auto-regenerated
$self->_sort_manifest($manifest); # keep MANIFEST sorted (to preserve correct signatures as much as possible)
}
# Would be nice if Module::Signature took a directory argument.
my $ID = $self->notes('config/dist_signature_id') || $self->notes('config/dist_author');
$self->_do_in_dir($dir, sub {local $Module::Signature::Quiet = 1; local $Module::Signature::AUTHOR = $ID; Module::Signature::sign( overwrite => 1 )});
}
};
$code{'ACTION_sign'} = q{
#[ADD] NEW action = sign - sign current module content
sub ACTION_sign {
my ($self) = @_;
if (($ENV{AUTOMATED_TESTING} or $ENV{CI}) and (not $ENV{AUTOMATED_SIGNATURE})) {
$self->log_warn("Automated and/or CI testing detected; signing is disabled [to enable: set AUTOMATED_SIGNATURE]\n");
return;
}
# from: ACTION_distsign
#{
#local $self->{properties}{sign} = 0; # We'll sign it ourselves
#$self->depends_on('distdir') unless -d $self->dist_dir;
#}
#$self->_sign_dir($self->dist_dir);
$self->depends_on('distmeta');
$self->_sign_dir($self->base_dir);
$self->FILES_to_NIX( 'SIGNATURE' );
}
};
$code{'ACTION_dist'} = q{
#[ADD] dist - make ACTION_dist dependent on distmeta
sub ACTION_dist {
my $self = shift;
$self->depends_on('distmeta');
$self->SUPER::ACTION_dist( @_ );
}
};
$code{'ACTION_distdir'} = q{
#[ADD] distdir - make ACTION_distdir dependent on sign (as a HACK to avoid gpg-agent open file handle on distdir)
sub ACTION_distdir {
my $self = shift;
## $self->depends_on('PL_files');
if ( $self->sign ) {
# HACK: avoid gpg-agent leaving an open handle on a directory scheduled for cleanup :: this causes sign events & leaves gpg-agent with a handle open to the main directory (not as bad because we don't clean it up)
# would be better to fix this in _sign_dir or in Module::Signature itself, if possible ([2013-12-29] still not possible); best repair would be a corrected gpg-agent
if ($^O =~ /\AMSWin/i) {
if (not File::Glob::bsd_glob('SIGNATURE',File::Glob::GLOB_NOCASE())) { $self->depends_on('sign'); }
}
}
$self->SUPER::ACTION_distdir( @_ );
}
};
$code{'ACTION_distsign'} = q{
#[ADD] distsign - make ACTION_distsign dependent on sign (as a HACK to avoid gpg-agent open file handle on distdir)
sub ACTION_distsign {
my $self = shift;
# HACK: avoid gpg-agent leaving an open handle on a directory scheduled for cleanup :: this causes sign events & leaves gpg-agent with a handle open to the main directory (not as bad because we don't clean it up)
# would be better to fix this in _sign_dir or in Module::Signature itself, if possible ([2013-12-29] still not possible); best repair would be a corrected gpg-agent
if ($^O =~ /\AMSWin/i) {
if (not File::Glob::bsd_glob('SIGNATURE',File::Glob::GLOB_NOCASE())) { $self->depends_on('sign'); }
}
$self->SUPER::ACTION_distsign( @_ );
}
};
$code{'ACTION_distcheck'} = q{
#[ADD] action = distcheck - custom distcheck ACTION to create MANIFEST (if needed; especially after a "distclean")
sub ACTION_distcheck {
my $self = shift;
# needed prior to ACTION_distcheck to make sure there is a MANIFEST o/w distcheck gripes
#$self->ACTION_manifest( qq{quiet} );
{
local $self->{properties}{quiet} = 1;
require ExtUtils::Manifest; # needed to modify $ExtUtils::Manifest::Verbose and $ExtUtils::Manifest::Quiet prior to manifest building
local ($ExtUtils::Manifest::Verbose, $ExtUtils::Manifest::Quiet) = (0,1);
$self->ACTION_manifest; # [use direct execution of ACTION; depends_on() will cache and execute each ACTION only once per script execution]
}
$self->SUPER::ACTION_distcheck( @_ );
}
};
$code{'ACTION_distall'} = q{
#[ADD] NEW action = distall - makes all distributions
sub ACTION_distall {
my ($self) = @_;
$self->depends_on('distmeta');
$self->depends_on('pardist');
$self->depends_on('ppmdist');
$self->depends_on('dist');
}
};
$code{'ACTION_distppm'} = q{
#[ADD] NEW action = distppm - makes ppm distribution (ALIAS to ppmdist)
sub ACTION_distppm {
shift->depends_on('ppmdist');
}
};
$code{'ACTION_distpar'} = q{
#[ADD] NEW action = distpar - makes par distribution (ALIAS to pardist)
sub ACTION_distpar {
shift->depends_on('pardist');
}
};
$code{'ACTION_disttest'} = q{
#[ADD] SUB action = disttest - run tests on distribution (_without_ resetting the distribution directory 1st)
sub ACTION_disttest {
# FROM Module::Build::ACTION_disttest()
my ($self) = @_;
$self->depends_on('distdir') unless -d $self->dist_dir; # modification: don't reset the dist_dir
$self->_do_in_dir
( $self->dist_dir,
sub {
# XXX could be different names for scripts
$self->run_perl_script('Build.PL') # XXX Should this be run w/ --no-use-rcfile
( run in 0.943 second using v1.01-cache-2.11-cpan-df04353d9ac )