package Mojolicious::Commands; use Mojo::Base 'Mojolicious::Command'; use Getopt::Long 'GetOptions'; use Mojo::Server; use Mojo::Util 'tablify'; has hint => <<EOF; See 'APPLICATION help COMMAND' for more information on a specific command. EOF has message => sub { shift->extract_usage . "\nCommands:\n" }; 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 { Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case pass_through)); 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; Getopt::Long::Configure('default'); } 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; 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 command my $command = $module->new(app => $self->app); return $help ? $command->help(@args) : $command->run(@args); } # Hide list for tests return 1 if $ENV{HARNESS_ACTIVE}; # Find all available commands my (@rows, %seen); my $loader = Mojo::Loader->new; for my $ns (@{$self->namespaces}) { for my $module (@{$loader->search($ns)}) { next unless my $command = _command($module); $command =~ s/^\Q$ns\E:://; next if $seen{$command}++; push @rows, [" $command", $module->new->description]; } } @rows = sort { $a->[0] cmp $b->[0] } @rows; return print $self->message, tablify(\@rows), $self->hint; } 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; =encoding utf8 =head1 NAME Mojolicious::Commands - Command line interface =head1 SYNOPSIS Usage: APPLICATION COMMAND [OPTIONS] Tip: CGI and PSGI environments can be automatically detected very often and work without commands. Options (for all commands): -h, --help Get more information on a specific command. --home <path> Path to your applications home directory, defaults to the value of MOJO_HOME or auto detection. -m, --mode <name> Operating mode for your application, defaults to the value of MOJO_MODE/PLACK_ENV or "development". =head1 DESCRIPTION L<Mojolicious::Commands> is the interactive command line interface for the L<Mojolicious> framework. It will automatically detect available commands in the C<Mojolicious::Command> namespace. =head1 COMMANDS These commands are available by default. =head2 cgi $ ./myapp.pl cgi Use L<Mojolicious::Command::cgi> to start application with CGI backend, usually auto detected. =head2 cpanify $ mojo cpanify -u sri -p secr3t Mojolicious-Plugin-Fun-0.1.tar.gz Use L<Mojolicious::Command::cpanify> for uploading files to CPAN. =head2 daemon $ ./myapp.pl daemon Use L<Mojolicious::Command::daemon> to start application with standalone HTTP and WebSocket server. =head2 eval $ ./myapp.pl eval 'say app->home' Use L<Mojolicious::Command::eval> to run code against application. =head2 generate $ mojo generate $ mojo generate help $ ./myapp.pl generate help List available generator commands with short descriptions. $ mojo generate help <generator> $ ./myapp.pl generate help <generator> List available options for generator command with short descriptions. =head2 generate app $ mojo generate app <AppName> Use L<Mojolicious::Command::generate::app> to generate application directory structure for a fully functional L<Mojolicious> application. =head2 generate lite_app $ mojo generate lite_app Use L<Mojolicious::Command::generate::lite_app> to generate a fully functional L<Mojolicious::Lite> application. =head2 generate makefile $ mojo generate makefile $ ./myapp.pl generate makefile Use L<Mojolicious::Command::generate::makefile> to generate C<Makefile.PL> file for application. =head2 generate plugin $ mojo generate plugin <PluginName> Use L<Mojolicious::Command::generate::plugin> to generate directory structure for a fully functional L<Mojolicious> plugin. =head2 get $ mojo get http://mojolicio.us $ ./myapp.pl get /foo Use L<Mojolicious::Command::get> to perform requests to remote host or local application. =head2 help $ mojo $ mojo help $ ./myapp.pl help List available commands with short descriptions. $ mojo help <command> $ ./myapp.pl help <command> List available options for the command with short descriptions. =head2 inflate $ ./myapp.pl inflate Use L<Mojolicious::Command::inflate> to turn templates and static files embedded in the C<DATA> sections of your application into real files. =head2 prefork $ ./myapp.pl prefork Use L<Mojolicious::Command::prefork> to start application with standalone preforking HTTP and WebSocket server. =head2 psgi $ ./myapp.pl psgi Use L<Mojolicious::Command::psgi> to start application with PSGI backend, usually auto detected. =head2 routes $ ./myapp.pl routes Use L<Mojolicious::Command::routes> to list application routes. =head2 test $ ./myapp.pl test $ ./myapp.pl test t/fun.t Use L<Mojolicious::Command::test> to run application tests from the C<t> directory. =head2 version $ mojo version $ ./myapp.pl version Use L<Mojolicious::Command::version> to show version information for installed core and optional modules, very useful for debugging. =head1 ATTRIBUTES L<Mojolicious::Commands> inherits all attributes from L<Mojolicious::Command> and implements the following new ones. =head2 hint my $hint = $commands->hint; $commands = $commands->hint('Foo!'); Short hint shown after listing available commands. =head2 message my $msg = $commands->message; $commands = $commands->message('Hello World!'); Short usage message shown before listing available commands. =head2 namespaces my $namespaces = $commands->namespaces; $commands = $commands->namespaces(['MyApp::Command']); Namespaces to load commands from, defaults to C<Mojolicious::Command>. # Add another namespace to load commands from push @{$commands->namespaces}, 'MyApp::Command'; =head1 METHODS L<Mojolicious::Commands> inherits all methods from L<Mojolicious::Command> and implements the following new ones. =head2 detect my $env = $commands->detect; my $env = $commands->detect($guess); Try to detect environment. =head2 run $commands->run; $commands->run(@ARGV); Load and run commands. Automatic deployment environment detection can be disabled with the C<MOJO_NO_DETECT> environment variable. =head2 start_app 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<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>. =cut