Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 391 lines (301 sloc) 7.41 KB
#!/usr/bin/perl
require 5.006;
use strict;
use Cwd;
use Getopt::Long;
my %Opts;
Getopt::Long::Configure('auto_abbrev');
GetOptions(\%Opts, qw(help fulldist clean dist install make test
quiet silent continue install-only)) or Usage();
Usage() if($Opts{'help'});
foreach my $opt (qw(clean dist install install-only make test))
{
if($Opts{$opt})
{
Usage() if(exists $Opts{'task'});
$Opts{'task'} = $opt;
}
}
$Opts{'task'} ||= 'make';
my $Silent = $Opts{'silent'};
my $Quiet = $Opts{'quiet'} || $Silent;
my $CWD = cwd();
sub Usage
{
die<<"EOF";
Usage: build [--clean | --dist | --install | --make | --test]
[--help] [--quiet | --silent]
[module1, module2, ...] |
[--fulldist]
--help Show this help screen.
--quiet Print very few status messages.
--silent Do not print any status messages except errors.
--continue Continue task even if one or more modules fail.
Choose only *one* of the following options:
--fulldist Make a full distribution suitable for remote installs.
--clean Clean module distributions of temporary files.
--dist Create module distributions.
--install Install module distributions.
--install-only Install without first running tests.
--make Make module distributions in-place (Default)
--test Test module distributions.
EOF
}
my $DEFAULT_DIR = 'modules';
my $DIST_NAME = 'rose';
my($PERL, $MAKE, $FIND, $RM, $MV, $TAR, $GZIP, $ROOT_DIR, %Tasks);
use FindBin qw($Bin);
$ENV{'COPY_EXTENDED_ATTRIBUTES_DISABLE'} = 1; # Avoid ._ files on Mac OS X
MAIN:
{
($ROOT_DIR = $Bin) =~ s{/$}{};
$Quiet || print "Changing directory to $ROOT_DIR\n";
chdir($ROOT_DIR) || die "ERROR: Could not chdir($ROOT_DIR): $!\n";
Init_Commands();
Init_Lib_Dirs();
if($Opts{'fulldist'})
{
$Opts{'task'} = 'clean';
}
my @modules = Module_List();
Init_Tasks();
my $task = $Tasks{$Opts{'task'}} || Usage();
$SIG{'INT'} = sub
{
print "Exiting via interrupt...\n";
exit;
};
MODULE: foreach my $module (@modules)
{
my $desc = $task->{'DESC'};
my $mod_name = $module;
for($mod_name)
{
s{.*/}{};
s/-/::/g;
}
$desc =~ s/%module/$mod_name/g;
$Silent || print<<"EOF";
##
## $desc
##
EOF
$Silent || print "Changing directory to $module\n";
chdir("$ROOT_DIR/$module") ||
die "Could not chdir($ROOT_DIR/$module): $!\n";
my @cmds = @{$task->{'COMMANDS'}};
foreach my $cmd (@cmds)
{
unless(Run_Command($cmd))
{
$Silent || print "\n## $desc: FAILED\n";
next MODULE if($Opts{'continue'});
last MODULE;
}
}
$Silent || print "\n## $desc: SUCCESS\n";
}
if($Opts{'fulldist'})
{
Full_Distribution();
exit(0);
}
}
sub Init_Lib_Dirs
{
opendir(DIR, $DEFAULT_DIR) || die "Could not opendir($$DEFAULT_DIR): $!";
my @libdirs;
while(my $file = readdir(DIR))
{
next if($file =~ /^\.\.?$/);
if(-d "$DEFAULT_DIR/$file")
{
push(@libdirs, "$ROOT_DIR/$DEFAULT_DIR/$file/lib");
}
}
if(length $ENV{'PERL5LIB'} && $ENV{'PERL5LIB'} !~ /:$/)
{
$ENV{'PERL5LIB'} .= ':';
}
$ENV{'PERL5LIB'} .= join(':', @libdirs);
}
sub Init_Commands
{
$RM = Find_Command('rm', '/bin/rm');
$MV = Find_Command('mv', '/bin/mv');
$FIND = Find_Command('find',qw(/usr/local/bin/find /usr/bin/find /bin/find));
$MAKE = Find_Command('make',qw(/usr/local/bin/make /usr/bin/make /bin/make));
$TAR = Find_Command('tar', qw(/usr/local/bin/gtar /usr/local/bin/tar /usr/bin/tar /bin/tar));
$PERL = Find_Command('perl',qw(/usr/local/bin/perl /usr/bin/perl));
$GZIP = Find_Command('gzip',qw(/usr/local/bin/gzip /usr/bin/gzip /bin/gzip));
}
sub Find_Command
{
my($cmd, @choices) = @_;
foreach my $choice (@choices)
{
return $choice if(-x $choice);
}
die "Could not find '$cmd' command (looked in: ", join(', ', @choices), "\n";
}
sub Init_Tasks
{
%Tasks =
(
clean =>
{
DESC => 'Clean module distribution %module',
COMMANDS =>
[
[ $PERL, 'Makefile.PL' ],
[ $MAKE ,'distclean' ],
[ "$FIND . -name '*~' -print | $PERL -lne unlink" ],
[ "$FIND . -name '.DS_Store' -print | $PERL -lne unlink" ],
[ "$FIND . -name '._*' -print | $PERL -lne unlink" ],
]
},
dist =>
{
DESC => 'Create distribution for %module',
COMMANDS =>
[
[ $PERL, 'Makefile.PL' ],
[ $MAKE ,'distclean' ],
[ "$FIND . -name '*~' -print | $PERL -lne unlink" ],
[ "$FIND . -name '.DS_Store' -print | $PERL -lne unlink" ],
[ "$FIND . -name '._*' -print | $PERL -lne unlink" ],
#[ "$FIND . -type f -exec SetFile -t '' -c '' {} \\;" ],
[ $PERL, 'Makefile.PL' ],
[ "$RM -f *.tar.gz" ],
[ $MAKE, 'dist' ],
[ "$MV *.tar.gz $ROOT_DIR" ],
]
},
install =>
{
DESC => 'Install %module',
COMMANDS =>
[
[ $PERL, 'Makefile.PL' ],
[ $MAKE ],
[ $MAKE, 'test' ],
[ $MAKE, 'install' ],
]
},
'install-only' =>
{
DESC => 'Install %module',
COMMANDS =>
[
[ $MAKE, 'install' ],
]
},
make =>
{
DESC => 'Make %module',
COMMANDS =>
[
[ $PERL, 'Makefile.PL' ],
[ $MAKE ],
#[ $MAKE, 'test' ],
]
},
test =>
{
DESC => 'Test module distribution %module',
COMMANDS =>
[
[ $PERL, 'Makefile.PL' ],
[ $MAKE, 'test' ],
]
},
);
}
sub Run_Command
{
my($cmd) = shift;
my $cmd_text = join(' ', @$cmd);
$Silent || print "Running '$cmd_text'\n";
my $ret;
if($Quiet)
{
$ret = system($cmd_text . '> /dev/null 2>&1');
}
else
{
$ret = system(@$cmd);
}
$ret /= 256;
return 1 if($ret == 0);
warn "ERROR: Command '$cmd_text' failed and returned $ret\n";
return;
}
sub Module_List
{
my(@modules);
if(@ARGV)
{
foreach my $arg (@ARGV)
{
my $found;
$arg =~ s/::/-/g;
foreach my $path ($arg, "$DEFAULT_DIR/$arg", Cwd::abs_path("$CWD/$arg"))
{
if(-d $path && -e "$path/Makefile.PL")
{
$path =~ s{^$Bin/}{}o;
push(@modules, $path);
$found = $path;
last;
}
}
unless($found)
{
warn qq(WARNING: Could not find module distribution "$arg"\n);
}
}
}
else
{
opendir(DIR, $DEFAULT_DIR) || die "Could not opendir($DEFAULT_DIR): $!\n";
while(my $file = readdir(DIR))
{
next unless(-e "$DEFAULT_DIR/$file/Makefile.PL");
push(@modules, "$DEFAULT_DIR/$file");
}
}
return @modules;
}
sub Full_Distribution
{
chdir($ROOT_DIR) or die "Could not chdir $ROOT_DIR - $!\n";
$Silent || print<<"EOF";
##
## Make full distribution
##
EOF
my $tar_file = "$DIST_NAME.tar";
foreach my $file ($tar_file, "$tar_file.gz")
{
if(-e $file)
{
unlink($file) || die "ERROR: could not delete $ROOT_DIR/$file: $!\n";
}
}
my($tar_root, $tar_dir) = ($ROOT_DIR =~ m{(.*?)/([^/]+)$});
my @cmds =
(
[ $TAR, '-cf', $tar_file, '-C', $tar_root,
"$tar_dir/build", "$tar_dir/$DEFAULT_DIR" ],
[ $GZIP, $tar_file ],
);
foreach my $cmd (@cmds)
{
unless(Run_Command($cmd))
{
$Silent || print "\n## Make full distribution: FAILED\n";
exit(1);
}
}
$Silent || print "\n## Make full distribution: SUCCESS\n";
}