package Mojolicious::Commands; use Mojo::Base 'Mojolicious::Command'; use Mojo::Loader qw(find_modules find_packages load_class); use Mojo::Server; use Mojo::Util qw(getopt tablify); has hint => < sub { shift->extract_usage . "\nCommands:\n" }; has namespaces => sub { ['Mojolicious::Command::Author', 'Mojolicious::Command'] }; sub detect { # 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 undef; } sub run { my ($self, $name, @args) = @_; # Application loader return $self->app if defined $ENV{MOJO_APP_LOADER}; # Try to detect environment if (!$ENV{MOJO_NO_DETECT} && (my $env = $self->detect)) { $name = $env } # Run command if ($name && $name =~ /^\w[\w-]+$/ && ($name ne 'help' || $args[0])) { # Help $name = shift @args if my $help = $name eq 'help'; local $ENV{MOJO_HELP} = $help = $ENV{MOJO_HELP} || $help; $name =~ s/-/_/g; # Remove options shared by all commands before loading the command _args(\@args); 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 $app = $self->app; my $command = $module->new(app => $app); return $command->help(@args) if $help; $app->plugins->emit_hook(before_command => $command, \@args); return $command->run(@args); } elsif ($name && $name ne 'help' && $name ne '--help' && $name ne '-h') { die qq{Invalid command "$name".\n} } # Hide list for tests return 1 if $ENV{HARNESS_ACTIVE}; # Find all available commands my %all; for my $ns (@{$self->namespaces}) { $all{substr $_, length "${ns}::"} //= $_->new->description for grep { _command($_) } find_modules($ns), find_packages($ns); } my @rows; for my $class (sort keys %all) { my $command = $class; $command =~ s/(?message, tablify(\@rows), $self->hint; } sub start_app { shift; Mojo::Server->new->build_app(shift)->start(@_) } # Command line options for MOJO_HELP, MOJO_HOME and MOJO_MODE sub _args { getopt shift, ['pass_through'], 'h|help' => \$ENV{MOJO_HELP}, 'home=s' => \$ENV{MOJO_HOME}, 'm|mode=s' => \$ENV{MOJO_MODE} unless __PACKAGE__->detect; } # Do not remove options from @ARGV BEGIN { _args([@ARGV]) } sub _command { my ($module, $fatal) = @_; return $module->isa('Mojolicious::Command') ? $module : undef unless my $e = load_class $module; $fatal && ref $e ? die $e : return undef; } 1; =encoding utf8 =head1 NAME Mojolicious::Commands - Command line interface =head1 SYNOPSIS Usage: APPLICATION COMMAND [OPTIONS] mojo version mojo generate lite-app ./myapp.pl daemon -m production -l http://*:8080 ./myapp.pl get /foo ./myapp.pl routes -v 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 to home directory of your application, defaults to the value of MOJO_HOME or auto-detection -m, --mode Operating mode for your application, defaults to the value of MOJO_MODE/PLACK_ENV or "development" =head1 DESCRIPTION L is the interactive command line interface for the L framework. It will automatically detect available commands in the C and C namespaces. =head1 COMMANDS These commands are available by default. =head2 cgi $ ./myapp.pl cgi Use L 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 for uploading files to CPAN. =head2 daemon $ ./myapp.pl daemon Use L to start application with standalone HTTP and WebSocket server. =head2 eval $ ./myapp.pl eval 'say app->home' Use L 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 $ ./myapp.pl generate help List available options for generator command with short descriptions. =head2 generate app $ mojo generate app Use L to generate application directory structure for a fully functional L application. =head2 generate dockerfile $ ./myapp.pl generate dockerfile $ ./script/my_app generate dockerfile Use L to generate C for application. =head2 generate lite-app $ mojo generate lite-app Use L to generate a fully functional L application. =head2 generate makefile $ mojo generate makefile $ ./myapp.pl generate makefile Use L to generate C file for application. =head2 generate plugin $ mojo generate plugin Use L to generate directory structure for a fully functional L plugin. =head2 get $ mojo get https://mojolicious.org $ ./myapp.pl get /foo Use L 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 $ ./myapp.pl help List available options for the command with short descriptions. =head2 inflate $ ./myapp.pl inflate Use L to turn templates and static files embedded in the C sections of your application into real files. =head2 prefork $ ./myapp.pl prefork Use L to start application with standalone pre-forking HTTP and WebSocket server. =head2 psgi $ ./myapp.pl psgi Use L to start application with PSGI backend, usually auto detected. =head2 routes $ ./myapp.pl routes Use L to list application routes. =head2 version $ mojo version $ ./myapp.pl version Use L to show version information for available core and optional modules, very useful for debugging. =head1 ATTRIBUTES L inherits all attributes from L 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 and 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 detect my $env = $commands->detect; Try to detect environment, or return C if none could be detected. =head2 run $commands->run; $commands->run(@ARGV); Load and run commands. Automatic deployment environment detection can be disabled with the C environment variable. =head2 start_app Mojolicious::Commands->start_app('MyApp'); Mojolicious::Commands->start_app(MyApp => @ARGV); Load application from class and start the command line interface for it. Note that the options C<-h>/C<--help>, C<--home> and C<-m>/C<--mode>, which are shared by all commands, will be parsed from C<@ARGV> during compile time. # Always start daemon for application Mojolicious::Commands->start_app('MyApp', 'daemon', '-l', 'http://*:8080'); =head1 SEE ALSO L, L, L. =cut