Newer Older
261 lines | 5.872kb
add files
Yuki Kimoto authored on 2014-03-26
1
package Mojolicious::Command;
2
use Mojo::Base -base;
3

            
4
use Carp 'croak';
5
use Cwd 'getcwd';
6
use File::Basename 'dirname';
7
use File::Path 'mkpath';
8
use File::Spec::Functions qw(catdir catfile);
9
use Mojo::Loader;
10
use Mojo::Server;
11
use Mojo::Template;
12
use Mojo::Util 'spurt';
13

            
14
has app => sub { Mojo::Server->new->build_app('Mojo::HelloWorld') };
15
has description => 'No description.';
16
has quiet       => 0;
17
has usage       => "usage: $0\n";
18

            
19
sub chmod_file {
20
  my ($self, $path, $mod) = @_;
21
  chmod $mod, $path or croak qq{Can't chmod file "$path": $!};
22
  $mod = sprintf '%lo', $mod;
23
  say "  [chmod] $path $mod" unless $self->quiet;
24
  return $self;
25
}
26

            
27
sub chmod_rel_file {
28
  my ($self, $path, $mod) = @_;
29
  $self->chmod_file($self->rel_file($path), $mod);
30
}
31

            
32
sub create_dir {
33
  my ($self, $path) = @_;
34

            
35
  if (-d $path) { say "  [exist] $path" unless $self->quiet }
36
  else {
37
    mkpath $path or croak qq{Can't make directory "$path": $!};
38
    say "  [mkdir] $path" unless $self->quiet;
39
  }
40

            
41
  return $self;
42
}
43

            
44
sub create_rel_dir {
45
  my ($self, $path) = @_;
46
  $self->create_dir($self->rel_dir($path));
47
}
48

            
49
sub help {
50
  print shift->usage;
51
  exit 0;
52
}
53

            
54
sub rel_dir { catdir(getcwd(), split /\//, pop) }
55

            
56
sub rel_file { catfile(getcwd(), split /\//, pop) }
57

            
58
sub render_data {
59
  my ($self, $name) = (shift, shift);
60
  Mojo::Template->new->name("template $name from DATA section")
61
    ->render(Mojo::Loader->new->data(ref $self, $name), @_);
62
}
63

            
64
sub render_to_file {
65
  my ($self, $data, $path) = (shift, shift, shift);
66
  return $self->write_file($path, $self->render_data($data, @_));
67
}
68

            
69
sub render_to_rel_file {
70
  my $self = shift;
71
  $self->render_to_file(shift, $self->rel_dir(shift), @_);
72
}
73

            
74
sub run { croak 'Method "run" not implemented by subclass' }
75

            
76
sub write_file {
77
  my ($self, $path, $data) = @_;
78
  $self->create_dir(dirname $path);
79
  spurt $data, $path;
80
  say "  [write] $path" unless $self->quiet;
81
  return $self;
82
}
83

            
84
sub write_rel_file {
85
  my ($self, $path, $data) = @_;
86
  $self->write_file($self->rel_file($path), $data);
87
}
88

            
89
1;
90

            
91
=encoding utf8
92

            
93
=head1 NAME
94

            
95
Mojolicious::Command - Command base class
96

            
97
=head1 SYNOPSIS
98

            
99
  # Lowercase command name
100
  package Mojolicious::Command::mycommand;
101
  use Mojo::Base 'Mojolicious::Command';
102

            
103
  # Short description
104
  has description => "My first Mojo command.\n";
105

            
106
  # Short usage message
107
  has usage => <<EOF;
108
  usage: $0 mycommand [OPTIONS]
109

            
110
  These options are available:
111
    -s, --something   Does something.
112
  EOF
113

            
114
  sub run {
115
    my ($self, @args) = @_;
116

            
117
    # Magic here! :)
118
  }
119

            
120
=head1 DESCRIPTION
121

            
122
L<Mojolicious::Command> is an abstract base class for L<Mojolicious> commands.
123

            
124
See L<Mojolicious::Commands> for a list of commands that are available by
125
default.
126

            
127
=head1 ATTRIBUTES
128

            
129
L<Mojolicious::Command> implements the following attributes.
130

            
131
=head2 app
132

            
133
  my $app  = $command->app;
134
  $command = $command->app(MyApp->new);
135

            
136
Application for command, defaults to a L<Mojo::HelloWorld> object.
137

            
138
  # Introspect
139
  say "Template path: $_" for @{$command->app->renderer->paths};
140

            
141
=head2 description
142

            
143
  my $description = $command->description;
144
  $command        = $command->description('Foo!');
145

            
146
Short description of command, used for the command list.
147

            
148
=head2 quiet
149

            
150
  my $bool = $command->quiet;
151
  $command = $command->quiet($bool);
152

            
153
Limited command output.
154

            
155
=head2 usage
156

            
157
  my $usage = $command->usage;
158
  $command  = $command->usage('Foo!');
159

            
160
Usage information for command, used for the help screen.
161

            
162
=head1 METHODS
163

            
164
L<Mojolicious::Command> inherits all methods from L<Mojo::Base> and implements
165
the following new ones.
166

            
167
=head2 chmod_file
168

            
169
  $command = $command->chmod_file('/home/sri/foo.txt', 0644);
170

            
171
Change mode of a file.
172

            
173
=head2 chmod_rel_file
174

            
175
  $command = $command->chmod_rel_file('foo/foo.txt', 0644);
176

            
177
Portably change mode of a file relative to the current working directory.
178

            
179
=head2 create_dir
180

            
181
  $command = $command->create_dir('/home/sri/foo/bar');
182

            
183
Create a directory.
184

            
185
=head2 create_rel_dir
186

            
187
  $command = $command->create_rel_dir('foo/bar/baz');
188

            
189
Portably create a directory relative to the current working directory.
190

            
191
=head2 help
192

            
193
  $command->help;
194

            
195
Print usage information for command.
196

            
197
=head2 rel_dir
198

            
199
  my $path = $command->rel_dir('foo/bar');
200

            
201
Portably generate an absolute path for a directory relative to the current
202
working directory.
203

            
204
=head2 rel_file
205

            
206
  my $path = $command->rel_file('foo/bar.txt');
207

            
208
Portably generate an absolute path for a file relative to the current working
209
directory.
210

            
211
=head2 render_data
212

            
213

            
214
  my $data = $command->render_data('foo_bar');
215
  my $data = $command->render_data('foo_bar', @args);
216

            
217
Render a template from the C<DATA> section of the command class with
218
L<Mojo::Template>.
219

            
220
=head2 render_to_file
221

            
222
  $command = $command->render_to_file('foo_bar', '/home/sri/foo.txt');
223
  $command = $command->render_to_file('foo_bar', '/home/sri/foo.txt', @args);
224

            
225
Render a template from the C<DATA> section of the command class with
226
L<Mojo::Template> to a file and create directory if necessary.
227

            
228
=head2 render_to_rel_file
229

            
230
  $command = $command->render_to_rel_file('foo_bar', 'foo/bar.txt');
231
  $command = $command->render_to_rel_file('foo_bar', 'foo/bar.txt', @args);
232

            
233
Portably render a template from the C<DATA> section of the command class with
234
L<Mojo::Template> to a file relative to the current working directory and
235
create directory if necessary.
236

            
237
=head2 run
238

            
239
  $command->run;
240
  $command->run(@ARGV);
241

            
242
Run command. Meant to be overloaded in a subclass.
243

            
244
=head2 write_file
245

            
246
  $command = $command->write_file('/home/sri/foo.txt', 'Hello World!');
247

            
248
Write text to a file and create directory if necessary.
249

            
250
=head2 write_rel_file
251

            
252
  $command = $command->write_rel_file('foo/bar.txt', 'Hello World!');
253

            
254
Portably write text to a file relative to the current working directory and
255
create directory if necessary.
256

            
257
=head1 SEE ALSO
258

            
259
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
260

            
261
=cut