#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;
use Amon2::Setup::Flavor::Basic;
use Amon2::Setup::VC::Git;
use Cwd ();
use Plack::Util;
use File::Find ();
use File::Spec ();
my @flavors;
my $vc = 'Git';
GetOptions(
'help' => \my $help,
'list-flavors|l' => \my $list_flavors,
'flavor=s@' => \@flavors,
'vc=s' => \$vc,
'version' => \my $version,
) or pod2usage(0);
if ($version) {
require Amon2;
print "Amon2: $Amon2::VERSION\n";
exit(0);
}
list_flavors() if $list_flavors;
pod2usage(1) if $help;
push @flavors, 'Basic' if @flavors == 0;
@flavors = map { split /,/, $_ } @flavors;
&main;exit;
sub main {
my $module = shift @ARGV or pod2usage(0);
$module =~ s!-!::!g;
# $module = "Foo::Bar"
# $dist = "Foo-Bar"
# $path = "Foo/Bar"
my @pkg = split /::/, $module;
my $dist = join "-", @pkg;
my $path = join "/", @pkg;
mkdir $dist or die "Cannot mkdir '$dist': $!";
chdir $dist or die $!;
my @flavor_classes;
for my $flavor (@flavors) {
my $flavor_class = load_flavor($flavor);
push @flavor_classes, $flavor_class;
print "-- Running flavor: $flavor --\n";
my $cwd = Cwd::getcwd(); # save cwd
{
my $flavor = $flavor_class->new(module => $module);
$flavor->run;
}
chdir($cwd);
}
{
$vc = Plack::Util::load_class($vc, 'Amon2::Setup::VC');
$vc = $vc->new();
$vc->do_import();
}
for my $flavor_class (@flavor_classes) {
if ($flavor_class->can('call_trigger')) {
$flavor_class->call_trigger('AFTER_VC');
}
}
}
sub load_flavor {
my $flavor_name = shift;
my $flavor_class = $flavor_name =~ s/^\+// ? $flavor_name : "Amon2::Setup::Flavor::$flavor_name";
eval "use $flavor_class; 1" or die "Cannot load $flavor_class: $@";
return $flavor_class;
}
sub list_flavors {
my $prefix = "Amon2::Setup::Flavor";
my $dir = File::Spec->catdir(split /::/, $prefix);
my @results;
my %seen;
foreach my $base(map { File::Spec->catdir($_, $dir) } @INC) {
next unless -d $base;
File::Find::find({
wanted => sub {
return unless -r;
my $name = File::Spec->abs2rel($_, $base);
$name =~ s/\.pm$// or return;
$seen{$name}++ and return;
push @results, join '::', File::Spec->splitdir($name);
},
no_chdir => 1,
}, $base);
}
for my $moniker (sort @results) {
my $module = eval {
Plack::Util::load_class($moniker, $prefix);
};
# extract short description
my $content = do {
open my $fh, "<", $INC{join("/", split "::", $module).".pm"};
local $/;
<$fh>;
};
my($description) = $content =~ m{
^=head1 \s+ NAME
\s+
\Q$module\E \s+ - \s+ ([^\n]+)
}xms;
if (defined $description) {
print $moniker, " - ", $description, "\n";
}
else {
print $moniker, "\n";
}
}
exit;
}
__END__
=head1 NAME
amon2-setup.pl - setup script for amon2
=head1 SYNOPSIS
% amon2-setup.pl MyApp
--flavor=Basic basic flavour (default)
--flavor=Lite Amon2::Lite flavour (need to install)
--flavor=Minimum minimalistic flavour for benchmarking
--vc=Git setup the git repository (default)
--list-flavors (or -l) Shows the list of flavors installed
--help Show this help
=head1 DESCRIPTION
This is a setup script for Amon2.
amon2-setup.pl is highly extensible. You can write your own flavor.
=head1 HINTS
You can specify C<< --flavor >> option multiple times. For example, you can
type like following:
% amon2-setup.pl --flavor=Basic --flavor=Teng MyApp
% amon2-setup.pl --flavor=Teng,Basic MyApp
Second flavor can overwrite files generated by first flavor.
=head1 AUTHOR
Tokuhiro Matsuno
=cut