Applify
view release on metacpan or search on metacpan
lib/Applify.pm view on Meta::CPAN
# Check if we should abort running the app based on user argv
if (!$got_valid_options) {
$self->_exit(1);
}
elsif ($argv{help}) {
$self->print_help;
$self->_exit('help');
}
elsif ($argv{man}) {
system $PERLDOC => $self->documentation;
$self->_exit($? >> 8);
}
elsif ($argv{version}) {
$self->print_version;
$self->_exit('version');
}
# Create the application and run (or return) it
local $INSTANTIATING = 1;
local $@;
my $app = eval {
$self->{application_class} ||= $self->_generate_application_class;
$self->{application_class}->new(\%argv);
} or do {
$@ =~ s!\sat\s.*!!s unless $ENV{APPLIFY_VERBOSE};
$self->print_help;
local $! = 1; # exit value
die "\nInvalid input:\n\n$@\n";
};
return $app if defined wantarray; # $app = do $script_file;
$self->_exit($app->run(@ARGV));
}
sub documentation {
return $_[0]->{documentation} if @_ == 1;
$_[0]->{documentation} = $_[1] or die 'Usage: documentation $file|$module_name;';
return $_[0];
}
sub extends {
my $self = shift;
$self->{extends} = [@_];
return $self;
}
sub hook {
my ($self, $name, $cb) = @_;
push @{$self->{hook}{$name}}, $cb;
return $self;
}
sub import {
my ($class, %args) = @_;
my @caller = caller;
my $self = $class->new({caller => \@caller});
my $ns = $caller[0] . '::';
my %export;
strict->import;
warnings->import;
no strict 'refs';
$self->{skip_subs}{$_} = 1 for keys %$ns;
for my $k (qw(app extends hook option version documentation subcommand)) {
$self->{skip_subs}{$k} = 1;
my $name = $args{$k} // $k;
next unless $name;
$export{$k} = $name =~ /::/ ? $name : "$caller[0]\::$name";
}
no warnings 'redefine'; # need to allow redefine when loading a new app
*{$export{app}} = sub (&) { $self->app(@_) };
*{$export{hook}} = sub { $self->hook(@_) };
*{$export{option}} = sub { $self->option(@_) };
*{$export{version}} = sub { $self->version(@_) };
*{$export{documentation}} = sub { $self->documentation(@_) };
*{$export{extends}} = sub { $self->extends(@_) };
*{$export{subcommand}} = sub { $self->subcommand(@_) };
}
sub new {
my $class = shift;
my $self = bless @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {}, ref $class || $class;
$self->{options} ||= [];
$self->{caller} or die 'Usage: $self->new({ caller => [...], ... })';
return $self;
}
sub option {
my $self = shift;
my $type = shift or die 'Usage: option $type => ...';
my $name = shift or die 'Usage: option $type => $name => ...';
my $documentation = shift or die 'Usage: option $type => $name => $documentation, ...';
my %option = @_ % 2 ? (default => @_) : @_;
$option{alias} = [$option{alias}] if $option{alias} and !ref $option{alias};
$option{arg} = do { local $_ = $name; s!_!-!g; $_ } unless $option{arg};
$option{default} //= !!0 if $type eq 'bool';
push @{$self->options}, {%option, type => $type, name => $name, documentation => $documentation};
return $self;
}
sub option_parser {
my $self = shift;
return do { $self->{option_parser} = shift; $self } if @_;
my @config = qw(no_auto_help no_auto_version pass_through);
push @config, 'debug' if $ENV{APPLIFY_DEBUG};
return $self->{option_parser} ||= do {
require Getopt::Long;
Getopt::Long::Parser->new(config => \@config);
};
}
( run in 1.053 second using v1.01-cache-2.11-cpan-e93a5daba3e )