File Coverage

blib/lib/Mojolicious/Command/Author/webpack.pm
Criterion Covered Total %
statement 33 37 89.1
branch 12 18 66.6
condition 8 13 61.5
subroutine 7 8 87.5
pod 1 1 100.0
total 61 77 79.2


line stmt bran cond sub pod time code
1             package Mojolicious::Command::Author::webpack;
2 1     1   216844 use Mojo::Base 'Mojolicious::Command';
  1         16  
  1         6  
3              
4 1     1   63378 use Mojo::File 'path';
  1         4  
  1         73  
5 1     1   7 use Mojo::Util 'getopt';
  1         2  
  1         66  
6              
7             # Less noisy test runs
8 1   33 1   7 use constant SILENT => $ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_IS_VERBOSE};
  1         2  
  1         897  
9              
10             # Ugly hack to prevent Mojo::Server::Morbo from exiting
11             our $WORKER_PID = -1;
12 0 0 0 0   0 *CORE::GLOBAL::exit = sub { $WORKER_PID == $$ ? $_[0] : CORE::exit($_[0] // $!) };
13              
14             has description => 'Start application with HTTP, WebSocket and Webpack development server';
15             has usage => sub { shift->extract_usage };
16             has _morbo => sub { require Mojo::Server::Morbo; Mojo::Server::Morbo->new };
17              
18             sub run {
19 15     15 1 33146 my ($self, @argv) = @_;
20              
21             # Need to run "mojo webpack" and not "./myapp.pl webpack" to have a clean environment
22 15 100       77 return $self->_exec_mojo_webpack($0, @argv) unless path($0)->basename eq 'mojo';
23              
24             # Parse command line options
25             getopt \@argv,
26             'b|backend=s' => \$ENV{MOJO_MORBO_BACKEND},
27             'h|help' => \my $help,
28             'l|listen=s' => \my @listen,
29             'm|mode=s' => \$ENV{MOJO_MODE},
30             'v|verbose' => \$ENV{MORBO_VERBOSE},
31 14         884 'w|watch=s' => \my @watch;
32              
33 14 100 100     9554 die join "\n\n", $self->description, $self->usage if $help or !(my $app = shift @argv);
34              
35             # Start rollup/webpack
36 11         42 my $builder_pid = $self->_start_builder($app);
37 11 50 100     503 say "Bundler started with pid $builder_pid." if +($ENV{MORBO_VERBOSE} // 1) == 1;
38              
39             # Set up and start morbo - Mojo::Server::Morbo::run() will block until the the app is killed
40 11         142 local $ENV{MOJO_WEBPACK_BUILD} = ''; # Silence initial "Sure ... has been run ..." warning
41 11         40 local $WORKER_PID = $$;
42 11 100       59 $self->_morbo->backend->watch(\@watch) if @watch;
43 11 100       2924 $self->_morbo->daemon->listen(\@listen) if @listen;
44 11         168 $self->_morbo->run($app);
45              
46             # Stop rollup/webpack after the app is killed
47 11 50 100     151 warn "[Webpack] [$$] Reaping builder with pid $builder_pid...\n" if $ENV{MORBO_VERBOSE} and !SILENT;
48 11         43 1 while kill $builder_pid;
49             }
50              
51             sub _exec_mojo_webpack {
52 1     1   138 my ($self, @argv) = @_;
53 1         3 warn "Switching to `mojo webpack @argv` ...\n" unless SILENT;
54 1         3 { exec qw(mojo webpack), @argv };
  1         7  
55 1         59 die "exec mojo @argv: $!";
56             }
57              
58             sub _start_builder {
59 11     11   32 my ($self, $app) = @_;
60 11 50       43 die "Can't fork: $!" unless defined(my $pid = fork);
61 11 50       676 return $pid if $pid;
62 0           local $ENV{MOJO_WEBPACK_BUILD} = 'watch';
63 0           Mojo::Server->new->load_app($app);
64 0           exit $!;
65             }
66              
67             1;
68              
69             =encoding utf8
70              
71             =head1 NAME
72              
73             Mojolicious::Command::Author::webpack - Mojolicious HTTP, WebSocket and Webpack development server
74              
75             =head1 SYNOPSIS
76              
77             Usage: mojo webpack [OPTIONS] [APPLICATION]
78              
79             mojo webpack ./script/my_app
80             mojo webpack ./myapp.pl
81             mojo webpack -m production -l https://*:443 -l http://[::]:3000 ./myapp.pl
82             mojo webpack -l 'https://*:443?cert=./server.crt&key=./server.key' ./myapp.pl
83             mojo webpack -w /usr/local/lib -w public -w myapp.conf ./myapp.pl
84              
85             Options:
86             -b, --backend Morbo backend to use for reloading, defaults
87             to "Poll"
88             -h, --help Show this message
89             -l, --listen One or more locations you want to listen on,
90             defaults to the value of MOJO_LISTEN or
91             "http://*:3000"
92             -m, --mode Operating mode for your application,
93             defaults to the value of
94             MOJO_MODE/PLACK_ENV or "development"
95             -v, --verbose Print details about what files changed to
96             STDOUT
97             -w, --watch One or more directories and files to watch
98             for changes, defaults to the application
99             script as well as the "lib" and "templates"
100             directories in the current working
101             directory
102              
103             =head1 DESCRIPTION
104              
105             Start L and L applications with the
106             L web server.
107              
108             =head1 ATTRIBUTES
109              
110             =head2 description
111              
112             my $description = $daemon->description;
113             $daemon = $daemon->description('Foo');
114              
115             Short description of this command, used for the command list.
116              
117             =head2 usage
118              
119             my $usage = $daemon->usage;
120             $daemon = $daemon->usage('Foo');
121              
122             Usage information for this command, used for the help screen.
123              
124             =head1 METHODS
125              
126             =head2 run
127              
128             $daemon->run(@ARGV);
129              
130             Run this command.
131              
132             =head1 SEE ALSO
133              
134             L, L
135              
136             =cut