package Mojolicious::Commands; use Mojo::Base 'Mojolicious::Command'; use Getopt::Long qw(GetOptions :config no_auto_abbrev no_ignore_case pass_through); use Mojo::Server; has hint => <<"EOF"; These options are available for all commands: -h, --help Get more information on a specific command. --home Path to your applications home directory, defaults to the value of MOJO_HOME or auto detection. -m, --mode Run mode of your application, defaults to the value of MOJO_MODE or "development". See '$0 help COMMAND' for more information on a specific command. EOF has message => <<"EOF"; usage: $0 COMMAND [OPTIONS] Tip: CGI and PSGI environments can be automatically detected very often and work without commands. These commands are currently available: EOF has namespaces => sub { ['Mojolicious::Command'] }; sub detect { my ($self, $guess) = @_; # PSGI (Plack only for now) return 'psgi' if defined $ENV{PLACK_ENV}; # CGI return 'cgi' if defined $ENV{PATH_INFO} || defined $ENV{GATEWAY_INTERFACE}; # Nothing return $guess; } # Command line options for MOJO_HELP, MOJO_HOME and MOJO_MODE BEGIN { GetOptions( 'h|help' => sub { $ENV{MOJO_HELP} = 1 }, 'home=s' => sub { $ENV{MOJO_HOME} = $_[1] }, 'm|mode=s' => sub { $ENV{MOJO_MODE} = $_[1] } ) unless __PACKAGE__->detect; } sub run { my ($self, $name, @args) = @_; # Application loader return $self->app if defined $ENV{MOJO_APP_LOADER}; # Try to detect environment $name = $self->detect($name) unless $ENV{MOJO_NO_DETECT}; # Run command if ($name && $name =~ /^\w+$/ && ($name ne 'help' || $args[0])) { # Help $name = shift @args if my $help = $name eq 'help'; $help = $ENV{MOJO_HELP} = $ENV{MOJO_HELP} ? 1 : $help; # Try all namespaces my $module; $module = _command("${_}::$name", 1) and last for @{$self->namespaces}; # Unknown command die qq{Unknown command "$name", maybe you need to install it?\n} unless $module; # Run my $command = $module->new(app => $self->app); return $help ? $command->help(@args) : $command->run(@args); } # Test return 1 if $ENV{HARNESS_ACTIVE}; # Try all namespaces my (@commands, %seen); my $loader = Mojo::Loader->new; for my $namespace (@{$self->namespaces}) { for my $module (@{$loader->search($namespace)}) { next unless my $command = _command($module); $command =~ s/^${namespace}:://; push @commands, [$command => $module] unless $seen{$command}++; } } # Make list my @list; my $max = 0; for my $command (@commands) { my $len = length $command->[0]; $max = $len if $len > $max; push @list, [$command->[0], $command->[1]->new->description]; } # Print list print $self->message; for my $command (@list) { my ($name, $description) = @$command; print " $name" . (' ' x ($max - length $name)) . " $description"; } return print $self->hint; } sub start { my $self = shift; return $self->start_app($ENV{MOJO_APP} => @_) if $ENV{MOJO_APP}; return $self->new->app->start(@_); } sub start_app { my $self = shift; return Mojo::Server->new->build_app(shift)->start(@_); } sub _command { my ($module, $fatal) = @_; return $module->isa('Mojolicious::Command') ? $module : undef unless my $e = Mojo::Loader->new->load($module); $fatal && ref $e ? die $e : return undef; } 1; =head1 NAME Mojolicious::Commands - Command line interface =head1 SYNOPSIS use Mojolicious::Commands; my $commands = Mojolicious::Commands->new; push @{$commands->namespaces}, 'MyApp::Command'; $commands->run('daemon'); =head1 DESCRIPTION L is the interactive command line interface to the L framework. It will automatically detect available commands in the C namespace. =head1 COMMANDS These commands are available by default. =head2 C $ mojo $ mojo help $ ./myapp.pl help List available commands with short descriptions. $ mojo help $ ./myapp.pl help List available options for the command with short descriptions. =head2 C $ ./myapp.pl cgi Start application with CGI backend, usually auto detected. =head2 C $ mojo cpanify -u sri -p secr3t Mojolicious-Plugin-Fun-0.1.tar.gz Upload files to CPAN. =head2 C $ ./myapp.pl daemon Start application with standalone HTTP server backend. =head2 C $ ./myapp.pl eval 'say app->home' Run code against application. =head2 C $ mojo generate $ mojo generate help $ ./myapp.pl generate help List available generator commands with short descriptions. $ mojo generate help $ ./myapp.pl generate help List available options for generator command with short descriptions. =head2 C $ mojo generate app Generate application directory structure for a fully functional L application. =head2 C $ mojo generate lite_app Generate a fully functional L application. =head2 C $ mojo generate makefile $ ./myapp.pl generate makefile Generate C file for application. =head2 C $ mojo generate plugin Generate directory structure for a fully functional L plugin. =head2 C $ mojo get http://mojolicio.us $ ./myapp.pl get /foo Perform requests to remote host or local application. =head2 C $ ./myapp.pl inflate Turn templates and static files embedded in the C sections of your application into real files. =head2 C $ ./myapp.pl psgi Start application with PSGI backend, usually auto detected. =head2 C $ ./myapp.pl routes List application routes. =head2 C $ mojo test $ ./myapp.pl test $ ./myapp.pl test t/fun.t Runs application tests from the C directory. =head2 C $ mojo version $ ./myapp.pl version Show version information for installed core and optional modules, very useful for debugging. =head1 ATTRIBUTES L inherits all attributes from L and implements the following new ones. =head2 C my $hint = $commands->hint; $commands = $commands->hint('Foo!'); Short hint shown after listing available commands. =head2 C my $msg = $commands->message; $commands = $commands->message('Hello World!'); Short usage message shown before listing available commands. =head2 C my $namespaces = $commands->namespaces; $commands = $commands->namespaces(['MyApp::Command']); Namespaces to load commands from, defaults to C. # Add another namespace to load commands from push @{$commands->namespaces}, 'MyApp::Command'; =head1 METHODS L inherits all methods from L and implements the following new ones. =head2 C my $env = $commands->detect; my $env = $commands->detect($guess); Try to detect environment. =head2 C $commands->run; $commands->run(@ARGV); Load and run commands. Automatic deployment environment detection can be disabled with the C environment variable. =head2 C Mojolicious::Commands->start; Mojolicious::Commands->start(@ARGV); Start the command line interface for application from the value of the C environment variable or L. # Always start daemon and ignore @ARGV Mojolicious::Commands->start('daemon', '-l', 'http://*:8080'); =head2 C Mojolicious::Commands->start_app('MyApp'); Mojolicious::Commands->start_app(MyApp => @ARGV); Load application and start the command line interface for it. # Always start daemon for application and ignore @ARGV Mojolicious::Commands->start_app('MyApp', 'daemon', '-l', 'http://*:8080'); =head1 SEE ALSO L, L, L. =cut