Instantly share code, notes, and snippets.

Embed
What would you like to do?
A small framework for executing the command for a maintenance etc. under the same environment as Web (Mojolicious)
#!/usr/bin/env perl
use strict;
use warnings;
use feature ':5.10';
use Encode::Argv;
use File::Basename 'dirname';
use File::Spec;
use lib join '/', File::Spec->splitdir(dirname(__FILE__)), 'lib';
use lib join '/', File::Spec->splitdir(dirname(__FILE__)), '..', 'lib';
$ENV{MOJO_HOME} = File::Spec->catfile(File::Spec->splitdir(dirname(__FILE__)), '..')
unless $ENV{MOJO_HOME};
use Mojolicious::Commands;
my $comm = Mojolicious::Commands->new;
$comm->namespaces(['MyApp::Commands']);
$comm->run(@ARGV);
1;
__END__
$ cd /where/is/your/myapp
$ ./bin/myapp.pl dump_config --file=/path/to/file arg1 arg2
$VAR1 = [
{
'verbose' => 1,
'file' => '/path/to/file'
},
[
'arg1',
'arg2'
]
];
mode: development
home: /where/is/your/myapp
$
package MyApp::Commands;
use Mojo::Base 'Mojolicious::Commands';
use Getopt::Long qw(:config no_permute no_ignore_case no_pass_through);
use MyApp;
# Although 'app' returns the instance of Mojolicious::Lite (why?),
# I would like to use the subclass MyApp which extended Mojolicious.
has app => sub { MyApp->new };
# Parsed command line options
has options => sub { {} };
# Parsed command line arguments
has arguments => sub { [] };
# By each command, specify spec_options()
# that return defaults and specification for Getopt::Long
sub spec_options {
my $self = shift;
my %defaults = ();
my @spec = ();
return (\%defaults, \@spec);
}
# Initialize and run
sub run {
my $self = shift;
local @ARGV = @_;
my ($defaults,$spec) = $self->spec_options;
my @spec = @$spec;
my %options = %$defaults;
do {
local $SIG{__WARN__} = sub { die "@_" };
Getopt::Long::GetOptions(\%options, @spec);
};
$self->options(\%options);
$self->arguments([@ARGV]);
exit( $self->process || 0 );
}
# Concrete process called from run()
sub process {
my $self = shift;
my $app = $self->app; # MyApp
my $options = $self->options; # hash
my $args = $self->arguments; # array
# write your stuff here
return 0; # exit status
}
1;
__END__
package MyApp::Commands::dump_config;
use Mojo::Base 'MyApp::Commands';
use Data::Dumper;
$Data::Dumper::Indent = 1;
sub spec_options {
return ({
'verbose' => 1,
}, [qw{
verbose
file=s
}]);
}
sub process {
my $self = shift;
my $app = $self->app;
my $options = $self->options;
my $args = $self->arguments;
say Data::Dumper::Dumper([$options,$args]);
say "mode: ".$app->mode;
say "home: ".$app->home;
my $exit_status = 0;
return $exit_status;
}
1;
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment