Newer Older
330 lines | 7.679kb
add files
Yuki Kimoto authored on 2014-03-26
1
package Mojolicious::Commands;
2
use Mojo::Base 'Mojolicious::Command';
3

            
4
use Getopt::Long 'GetOptions';
5
use List::Util 'max';
6
use Mojo::Server;
7

            
8
has hint => <<EOF;
9

            
10
These options are available for all commands:
11
    -h, --help          Get more information on a specific command.
12
        --home <path>   Path to your applications home directory, defaults to
13
                        the value of MOJO_HOME or auto detection.
14
    -m, --mode <name>   Operating mode for your application, defaults to the
15
                        value of MOJO_MODE/PLACK_ENV or "development".
16

            
17
See '$0 help COMMAND' for more information on a specific command.
18
EOF
19
has message => <<EOF;
20
usage: $0 COMMAND [OPTIONS]
21

            
22
Tip: CGI and PSGI environments can be automatically detected very often and
23
     work without commands.
24

            
25
These commands are currently available:
26
EOF
27
has namespaces => sub { ['Mojolicious::Command'] };
28

            
29
sub detect {
30
  my ($self, $guess) = @_;
31

            
32
  # PSGI (Plack only for now)
33
  return 'psgi' if defined $ENV{PLACK_ENV};
34

            
35
  # CGI
36
  return 'cgi' if defined $ENV{PATH_INFO} || defined $ENV{GATEWAY_INTERFACE};
37

            
38
  # Nothing
39
  return $guess;
40
}
41

            
42
# Command line options for MOJO_HELP, MOJO_HOME and MOJO_MODE
43
BEGIN {
44
  Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case pass_through));
45
  GetOptions(
46
    'h|help'   => sub { $ENV{MOJO_HELP} = 1 },
47
    'home=s'   => sub { $ENV{MOJO_HOME} = $_[1] },
48
    'm|mode=s' => sub { $ENV{MOJO_MODE} = $_[1] }
49
  ) unless __PACKAGE__->detect;
50
  Getopt::Long::Configure('default');
51
}
52

            
53
sub run {
54
  my ($self, $name, @args) = @_;
55

            
56
  # Application loader
57
  return $self->app if defined $ENV{MOJO_APP_LOADER};
58

            
59
  # Try to detect environment
60
  $name = $self->detect($name) unless $ENV{MOJO_NO_DETECT};
61

            
62
  # Run command
63
  if ($name && $name =~ /^\w+$/ && ($name ne 'help' || $args[0])) {
64

            
65
    # Help
66
    $name = shift @args if my $help = $name eq 'help';
67
    $help = $ENV{MOJO_HELP} = $ENV{MOJO_HELP} ? 1 : $help;
68

            
69
    my $module;
70
    $module = _command("${_}::$name", 1) and last for @{$self->namespaces};
71

            
72
    # Unknown command
73
    die qq{Unknown command "$name", maybe you need to install it?\n}
74
      unless $module;
75

            
76
    # Run command
77
    my $command = $module->new(app => $self->app);
78
    return $help ? $command->help(@args) : $command->run(@args);
79
  }
80

            
81
  # Hide list for tests
82
  return 1 if $ENV{HARNESS_ACTIVE};
83

            
84
  # Find all available commands
85
  my (@commands, %seen);
86
  my $loader = Mojo::Loader->new;
87
  for my $namespace (@{$self->namespaces}) {
88
    for my $module (@{$loader->search($namespace)}) {
89
      next unless my $command = _command($module);
90
      $command =~ s/^${namespace}:://;
91
      push @commands, [$command => $module] unless $seen{$command}++;
92
    }
93
  }
94

            
95
  # Print list of all available commands
96
  my $max = max map { length $_->[0] } @commands;
97
  print $self->message;
98
  for my $command (@commands) {
99
    my $name        = $command->[0];
100
    my $description = $command->[1]->new->description;
101
    print "  $name", (' ' x ($max - length $name)), "   $description";
102
  }
103
  return print $self->hint;
104
}
105

            
106
sub start_app {
107
  my $self = shift;
108
  return Mojo::Server->new->build_app(shift)->start(@_);
109
}
110

            
111
sub _command {
112
  my ($module, $fatal) = @_;
113
  return $module->isa('Mojolicious::Command') ? $module : undef
114
    unless my $e = Mojo::Loader->new->load($module);
115
  $fatal && ref $e ? die $e : return undef;
116
}
117

            
118
1;
119

            
120
=encoding utf8
121

            
122
=head1 NAME
123

            
124
Mojolicious::Commands - Command line interface
125

            
126
=head1 SYNOPSIS
127

            
128
  use Mojolicious::Commands;
129

            
130
  my $commands = Mojolicious::Commands->new;
131
  push @{$commands->namespaces}, 'MyApp::Command';
132
  $commands->run('daemon');
133

            
134
=head1 DESCRIPTION
135

            
136
L<Mojolicious::Commands> is the interactive command line interface to the
137
L<Mojolicious> framework. It will automatically detect available commands in
138
the C<Mojolicious::Command> namespace.
139

            
140
=head1 COMMANDS
141

            
142
These commands are available by default.
143

            
144
=head2 help
145

            
146
  $ mojo
147
  $ mojo help
148
  $ ./myapp.pl help
149

            
150
List available commands with short descriptions.
151

            
152
  $ mojo help <command>
153
  $ ./myapp.pl help <command>
154

            
155
List available options for the command with short descriptions.
156

            
157
=head2 cgi
158

            
159
  $ ./myapp.pl cgi
160

            
161
Start application with CGI backend, usually auto detected.
162

            
163
=head2 cpanify
164

            
165
  $ mojo cpanify -u sri -p secr3t Mojolicious-Plugin-Fun-0.1.tar.gz
166

            
167
Upload files to CPAN.
168

            
169
=head2 daemon
170

            
171
  $ ./myapp.pl daemon
172

            
173
Start application with standalone HTTP and WebSocket server.
174

            
175
=head2 eval
176

            
177
  $ ./myapp.pl eval 'say app->home'
178

            
179
Run code against application.
180

            
181
=head2 generate
182

            
183
  $ mojo generate
184
  $ mojo generate help
185
  $ ./myapp.pl generate help
186

            
187
List available generator commands with short descriptions.
188

            
189
  $ mojo generate help <generator>
190
  $ ./myapp.pl generate help <generator>
191

            
192
List available options for generator command with short descriptions.
193

            
194
=head2 generate app
195

            
196
  $ mojo generate app <AppName>
197

            
198
Generate application directory structure for a fully functional L<Mojolicious>
199
application.
200

            
201
=head2 generate lite_app
202

            
203
  $ mojo generate lite_app
204

            
205
Generate a fully functional L<Mojolicious::Lite> application.
206

            
207
=head2 generate makefile
208

            
209
  $ mojo generate makefile
210
  $ ./myapp.pl generate makefile
211

            
212
Generate C<Makefile.PL> file for application.
213

            
214
=head2 generate plugin
215

            
216
  $ mojo generate plugin <PluginName>
217

            
218
Generate directory structure for a fully functional L<Mojolicious> plugin.
219

            
220
=head2 get
221

            
222
  $ mojo get http://mojolicio.us
223
  $ ./myapp.pl get /foo
224

            
225
Perform requests to remote host or local application.
226

            
227
=head2 inflate
228

            
229
  $ ./myapp.pl inflate
230

            
231
Turn templates and static files embedded in the C<DATA> sections of your
232
application into real files.
233

            
234
=head2 prefork
235

            
236
  $ ./myapp.pl prefork
237

            
238
Start application with standalone preforking HTTP and WebSocket server.
239

            
240
=head2 psgi
241

            
242
  $ ./myapp.pl psgi
243

            
244
Start application with PSGI backend, usually auto detected.
245

            
246
=head2 routes
247

            
248
  $ ./myapp.pl routes
249

            
250
List application routes.
251

            
252
=head2 test
253

            
254
  $ ./myapp.pl test
255
  $ ./myapp.pl test t/fun.t
256

            
257
Runs application tests from the C<t> directory.
258

            
259
=head2 version
260

            
261
  $ mojo version
262
  $ ./myapp.pl version
263

            
264
Show version information for installed core and optional modules, very useful
265
for debugging.
266

            
267
=head1 ATTRIBUTES
268

            
269
L<Mojolicious::Commands> inherits all attributes from L<Mojolicious::Command>
270
and implements the following new ones.
271

            
272
=head2 hint
273

            
274
  my $hint  = $commands->hint;
275
  $commands = $commands->hint('Foo!');
276

            
277
Short hint shown after listing available commands.
278

            
279
=head2 message
280

            
281
  my $msg   = $commands->message;
282
  $commands = $commands->message('Hello World!');
283

            
284
Short usage message shown before listing available commands.
285

            
286
=head2 namespaces
287

            
288
  my $namespaces = $commands->namespaces;
289
  $commands      = $commands->namespaces(['MyApp::Command']);
290

            
291
Namespaces to load commands from, defaults to C<Mojolicious::Command>.
292

            
293
  # Add another namespace to load commands from
294
  push @{$commands->namespaces}, 'MyApp::Command';
295

            
296
=head1 METHODS
297

            
298
L<Mojolicious::Commands> inherits all methods from L<Mojolicious::Command> and
299
implements the following new ones.
300

            
301
=head2 detect
302

            
303
  my $env = $commands->detect;
304
  my $env = $commands->detect($guess);
305

            
306
Try to detect environment.
307

            
308
=head2 run
309

            
310
  $commands->run;
311
  $commands->run(@ARGV);
312

            
313
Load and run commands. Automatic deployment environment detection can be
314
disabled with the MOJO_NO_DETECT environment variable.
315

            
316
=head2 start_app
317

            
318
  Mojolicious::Commands->start_app('MyApp');
319
  Mojolicious::Commands->start_app(MyApp => @ARGV);
320

            
321
Load application and start the command line interface for it.
322

            
323
  # Always start daemon for application and ignore @ARGV
324
  Mojolicious::Commands->start_app('MyApp', 'daemon', '-l', 'http://*:8080');
325

            
326
=head1 SEE ALSO
327

            
328
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
329

            
330
=cut