File Coverage

blib/lib/App/Sqitch/Command.pm
Criterion Covered Total %
statement 155 155 100.0
branch 58 62 93.5
condition 23 29 79.3
subroutine 29 29 100.0
pod 10 10 100.0
total 275 285 96.4


line stmt bran cond sub pod time code
1             package App::Sqitch::Command;
2              
3 50     50   2351 use 5.010;
  50         225  
4 50     50   305 use strict;
  50         144  
  50         1232  
5 50     50   1564 use warnings;
  50         232  
  50         1750  
6 50     50   351 use utf8;
  50         102  
  50         456  
7 50     50   1534 use Try::Tiny;
  50         153  
  50         3238  
8 50     50   364 use Locale::TextDomain qw(App-Sqitch);
  50         114  
  50         620  
9 50     50   11271 use App::Sqitch::X qw(hurl);
  50         129  
  50         624  
10 50     50   18999 use Hash::Merge 'merge';
  50         130  
  50         3216  
11 50     50   378 use File::Path qw(make_path);
  50         105  
  50         2698  
12 50     50   366 use Moo;
  50         140  
  50         527  
13 50     50   23822 use App::Sqitch::Types qw(Sqitch Target);
  50         129  
  50         513  
14              
15             our $VERSION = 'v1.4.0'; # VERSION
16              
17 50         114081 use constant ENGINES => qw(
18             pg
19             sqlite
20             mysql
21             oracle
22             firebird
23             vertica
24             exasol
25             snowflake
26             cockroach
27 50     50   42281 );
  50         122  
28              
29             has sqitch => (
30             is => 'ro',
31             isa => Sqitch,
32             required => 1,
33             handles => [qw(
34             run
35             shell
36             quote_shell
37             capture
38             probe
39             verbosity
40             trace
41             trace_literal
42             debug
43             debug_literal
44             info
45             info_literal
46             comment
47             comment_literal
48             emit
49             emit_literal
50             vent
51             vent_literal
52             warn
53             warn_literal
54             page
55             page_literal
56             prompt
57             ask_y_n
58             )],
59             );
60              
61             has default_target => (
62             is => 'ro',
63             isa => Target,
64             lazy => 1,
65             default => sub {
66             my $self = shift;
67             my $sqitch = $self->sqitch;
68             my @params = $self->target_params;
69             unless (
70             $sqitch->config->get(key => 'core.engine')
71             || $sqitch->config->get(key => 'core.target')
72             ) {
73             # No specified engine, so specify an engineless URI.
74             require URI::db;
75             unshift @params, uri => URI::db->new('db:');
76             }
77             require App::Sqitch::Target;
78             return App::Sqitch::Target->new(@params);
79             },
80             );
81              
82             sub command {
83 264   66 264 1 26373 my $class = ref $_[0] || shift;
84 264 100       904 return '' if $class eq __PACKAGE__;
85 261         582 my $pkg = quotemeta __PACKAGE__;
86 261         2243 $class =~ s/^$pkg\:://;
87 261         885 $class =~ s/_/-/g;
88 261         1514 return $class;
89             }
90              
91             sub class_for {
92 65     65 1 1879 my ( $class, $sqitch, $cmd ) = @_;
93              
94 65         271 $cmd =~ s/-/_/g;
95              
96             # Load the command class.
97 65         254 my $pkg = __PACKAGE__ . "::$cmd";
98 65 100       4859 eval "require $pkg; 1" or do {
99             # Emit the original error for debugging.
100 9         460 $sqitch->debug($@);
101 4         362 return undef;
102             };
103 56         441 return $pkg;
104             }
105              
106             sub load {
107 39     39 1 69664 my ( $class, $p ) = @_;
108             # We should have a command.
109 39 100       279 my $cmd = delete $p->{command} or $class->usage;
110 38 100       223 my $pkg = $class->class_for($p->{sqitch}, $cmd) or hurl {
111             ident => 'command',
112             exitval => 1,
113             message => __x(
114             '"{command}" is not a valid command',
115             command => $cmd,
116             ),
117             };
118 35         282 $pkg->create($p);
119             }
120              
121             sub create {
122 44     44 1 1701 my ( $class, $p ) = @_;
123              
124             # Merge the command-line options and configuration parameters
125             my $params = $class->configure(
126             $p->{config},
127             $class->_parse_opts( $p->{args} )
128 44         341 );
129              
130             # Instantiate and return the command.
131 44         2601 $params->{sqitch} = $p->{sqitch};
132 44         879 return $class->new($params);
133             }
134              
135             sub configure {
136 93     93 1 24502 my ( $class, $config, $options ) = @_;
137              
138 93         738 return Hash::Merge->new->merge(
139             $options,
140             $config->get_section( section => $class->command ),
141             );
142             }
143              
144             sub options {
145 7     7 1 55 return;
146             }
147              
148             sub _parse_opts {
149 49     49   4274 my ( $class, $args ) = @_;
150 49 100 100     688 return {} unless $args && @{$args};
  20         97  
151              
152 16         33 my %opts;
153 16         121 Getopt::Long::Configure(qw(bundling no_pass_through));
154 16 100       1052 Getopt::Long::GetOptionsFromArray( $args, \%opts, $class->options )
155             or $class->usage;
156              
157             # Convert dashes to underscores.
158 16         7534 for my $k (keys %opts) {
159 10 100       60 next unless ( my $nk = $k ) =~ s/-/_/g;
160 2         6 $opts{$nk} = delete $opts{$k};
161             }
162              
163 16         187 return \%opts;
164             }
165              
166             sub _bn {
167 11     11   35 require File::Basename;
168 11         430 File::Basename::basename($0);
169             }
170              
171             sub _pod2usage {
172 8     8   49449 my ( $self, %params ) = @_;
173 8         30 my $command = $self->command;
174 8         46 require Pod::Find;
175 8         28 require Pod::Usage;
176 8         25 my $bn = _bn;
177             my $find_pod = sub {
178 26     26   22853 Pod::Find::pod_where({ '-inc' => 1, '-script' => 1 }, shift );
179 8         48 };
180 8   33     59 $params{'-input'} ||= $find_pod->("$bn-$command")
      66        
181             || $find_pod->("sqitch-$command")
182             || $find_pod->($bn)
183             || $find_pod->('sqitch')
184             || $find_pod->(ref $self || $self)
185             || $find_pod->(__PACKAGE__);
186 8         72 Pod::Usage::pod2usage(
187             '-verbose' => 99,
188             '-sections' => '(?i:(Usage|Synopsis|Options))',
189             '-exitval' => 2,
190             %params,
191             );
192             }
193              
194             sub execute {
195 2     2 1 107 my $self = shift;
196 2 100       12 hurl(
197             'The execute() method must be called from a subclass of '
198             . __PACKAGE__
199             ) if ref $self eq __PACKAGE__;
200              
201 1         8 hurl 'The execute() method has not been overridden in ' . ref $self;
202             }
203              
204             sub usage {
205 3     3 1 99414 my $self = shift;
206 3         26 require Pod::Find;
207 3         13 my $upod = _bn . '-' . $self->command . '-usage';
208 3   50     3273 $self->_pod2usage(
209             '-input' => Pod::Find::pod_where( { '-inc' => 1 }, $upod ) || undef,
210             '-message' => join '', @_
211             );
212             }
213              
214             sub target_params {
215 256     256 1 2864 return (sqitch => shift->sqitch);
216             }
217              
218             sub parse_args {
219 180     180 1 56310 my ($self, %p) = @_;
220 180         5111 my $config = $self->sqitch->config;
221 180         4875 my @params = $self->target_params;
222              
223             # Load the specified or default target.
224 180         1881 require App::Sqitch::Target;
225 180         408 my $deftarget_err;
226             my $target = try {
227             App::Sqitch::Target->new( @params, name => $p{target} )
228 180     180   14276 } catch {
229             # Die if a target was specified; otherwise keep the error for later.
230 4 100   4   6367 die $_ if $p{target};
231 3         5 $deftarget_err = $_;
232 3         11 undef;
233 180         1847 };
234              
235             # Set up the default results.
236 179         19039 my (%seen, %target_for);
237 179         541 my %rec = map { $_ => [] } qw(targets unknown);
  358         1262  
238 179 100       888 $rec{changes} = [] unless $p{no_changes};
239 179 100       622 if ($p{target}) {
240 46         98 push @{ $rec{targets} } => $target;
  46         129  
241 46         223 $seen{$target->name}++;
242             }
243              
244             # Iterate over the args to look for changes, engines, plans, or targets.
245 179         590 my %engines = map { $_ => 1 } ENGINES;
  1611         3824  
246 179         408 for my $arg (@{ $p{args} }) {
  179         764  
247 194 100 100     4760 if ( !$p{no_changes} && $target && -e $target->plan_file && $target->plan->contains($arg) ) {
    100 100        
    100 100        
    100 100        
248             # A change.
249 49         101 push @{ $rec{changes} } => $arg;
  49         250  
250             } elsif ($config->get( key => "target.$arg.uri") || URI->new($arg)->isa('URI::db')) {
251             # A target. Instantiate and keep for subsequente change searches.
252 39         12014 $target = App::Sqitch::Target->new( @params, name => $arg );
253 38 50       3905 push @{ $rec{targets} } => $target unless $seen{$target->name}++;
  38         733  
254             } elsif ($engines{$arg}) {
255             # An engine. Add its target.
256 21   66     4947 my $name = $config->get(key => "engine.$arg.target") || "db:$arg:";
257 21         3400 $target = App::Sqitch::Target->new( @params, name => $name );
258 21 50       2188 push @{ $rec{targets} } => $target unless $seen{$target->name}++;
  21         524  
259             } elsif (-e $arg) {
260             # Maybe it's a plan file?
261             %target_for = map {
262 7 50       2008 $_->plan_file => $_
  14         2727  
263             } reverse App::Sqitch::Target->all_targets(@params) unless %target_for;
264 7 100       2885 if ($target_for{$arg}) {
265             # It *is* a plan file.
266 6         132 $target = $target_for{$arg};
267 6 50       156 push @{ $rec{targets} } => $target unless $seen{$target->name}++;
  6         249  
268             } else {
269             # Nah, who knows.
270 1         2 push @{ $rec{unknown} } => $arg;
  1         6  
271             }
272             } else {
273             # Who knows?
274 78         17534 push @{ $rec{unknown} } => $arg;
  78         639  
275             }
276             }
277              
278             # Replace missing names with unknown values.
279 178 100       929 my @names = map { $_ || shift @{ $rec{unknown} } } @{ $p{names} || [] };
  66 100       271  
  59         277  
  178         1141  
280              
281             # Die on unknowns.
282 178 100       405 if (my @unknown = @{ $rec{unknown} } ) {
  178         664  
283 21         150 hurl $self->command => __nx(
284             'Unknown argument "{arg}"',
285             'Unknown arguments: {arg}',
286             scalar @unknown,
287             arg => join ', ', @unknown
288             );
289             }
290              
291             # Figure out what targets to access. Use default unless --all.
292 157         292 my @targets = @{ $rec{targets} };
  157         385  
293 157 100       644 if ($p{all}) {
    100          
294             # Got --all.
295 12 100       113 hurl $self->command => __(
296             'Cannot specify both --all and engine, target, or plan arugments'
297             ) if @targets;
298 8         69 @targets = App::Sqitch::Target->all_targets(@params );
299             } elsif (!@targets) {
300             # Use all if tag.all is set, otherwise just the default.
301 65         369 my $key = $self->command . '.all';
302             @targets = $self->sqitch->config->get(key => $key, as => 'bool')
303             ? App::Sqitch::Target->all_targets(@params )
304 65 100       1840 : do {
305             # Fall back on the default unless it's invalid.
306 61 100       8892 die $deftarget_err if $deftarget_err;
307 60         201 ($target)
308             }
309             }
310              
311 152         1419 return (@names, \@targets, $rec{changes});
312             }
313              
314             sub _mkpath {
315 210     210   107231 my ( $self, $dir ) = @_;
316 210 100       12418 $self->debug( ' ', __x 'Created {file}', file => $dir )
317             if make_path $dir, { error => \my $err };
318              
319 210 100       43544 my $diag = shift @{ $err } or return $self;
  210         1038  
320              
321 2         5 my ( $path, $msg ) = %{ $diag };
  2         10  
322 2 100       12 hurl $self->command => __x(
323             'Error creating {path}: {error}',
324             path => $path,
325             error => $msg,
326             ) if $path;
327 1         5 hurl $self->command => $msg;
328             }
329              
330             1;
331              
332             __END__
333              
334             =head1 Name
335              
336             App::Sqitch::Command - Sqitch Command support
337              
338             =head1 Synopsis
339              
340             my $cmd = App::Sqitch::Command->load( deploy => \%params );
341             $cmd->run;
342              
343             =head1 Description
344              
345             App::Sqitch::Command is the base class for all Sqitch commands.
346              
347             =head1 Interface
348              
349             =head2 Constants
350              
351             =head3 C<ENGINES>
352              
353             Returns the list of supported engines, currently:
354              
355             =over
356              
357             =item * C<firebird>
358              
359             =item * C<mysql>
360              
361             =item * C<oracle>
362              
363             =item * C<pg>
364              
365             =item * C<sqlite>
366              
367             =item * C<vertica>
368              
369             =item * C<exasol>
370              
371             =item * C<snowflake>
372              
373             =item * C<cockroach>
374              
375             =back
376              
377             =head2 Class Methods
378              
379             =head3 C<options>
380              
381             my @spec = App::Sqitch::Command->options;
382              
383             Returns a list of L<Getopt::Long> options specifications. When C<load> loads
384             the class, any options passed to the command will be parsed using these
385             values. The keys in the resulting hash will be the first part of each option,
386             with dashes converted to underscores. This hash will be passed to C<configure>
387             along with a L<App::Sqitch::Config> object for munging into parameters to be
388             passed to the constructor.
389              
390             Here's an example excerpted from the C<config> command:
391              
392             sub options {
393             return qw(
394             get
395             unset
396             list
397             global
398             system
399             config-file=s
400             );
401             }
402              
403             This will result in hash keys with the same names as each option except for
404             C<config-file=s>, which will be named C<config_file>.
405              
406             =head3 C<configure>
407              
408             my $params = App::Sqitch::Command->configure($config, $options);
409              
410             Takes two arguments, an L<App::Sqitch::Config> object and the hash of
411             command-line options as specified by C<options>. The returned hash should be
412             the result of munging these two objects into a hash reference of parameters to
413             be passed to the command subclass constructor.
414              
415             By default, this method converts dashes to underscores in command-line options
416             keys, and then merges the configuration values with the options, with the
417             command-line options taking priority. You may wish to override this method to
418             do something different.
419              
420             =head3 C<class_for>
421              
422             my $subclass = App::Sqitch::Command->subclass_for($sqitch, $cmd_name);
423              
424             This method attempts to load the subclass of App::Sqitch::Commmand that
425             corresponds to the command name. Returns C<undef> and sends errors to the
426             C<debug> method of the <$sqitch> object if no such subclass can
427             be loaded.
428              
429             =head2 Constructors
430              
431             =head3 C<load>
432              
433             my $cmd = App::Sqitch::Command->load( \%params );
434              
435             A factory method for instantiating Sqitch commands. It loads the subclass for
436             the specified command and calls C<create> to instantiate and return an
437             instance of the subclass. Sends error messages to the C<debug> method of the
438             C<sqitch> parameter and throws an exception if the subclass does not exist or
439             cannot be loaded. Supported parameters are:
440              
441             =over
442              
443             =item C<sqitch>
444              
445             The App::Sqitch object driving the whole thing.
446              
447             =item C<config>
448              
449             An L<App::Sqitch::Config> representing the current application configuration
450             state.
451              
452             =item C<command>
453              
454             The name of the command to be executed.
455              
456             =item C<args>
457              
458             An array reference of command-line arguments passed to the command.
459              
460             =back
461              
462             =head3 C<create>
463              
464             my $pkg = App::Sqitch::Command->class_for( $sqitch, $cmd_name )
465             or die "No such command $cmd_name";
466             my $cmd = $pkg->create({
467             sqitch => $sqitch,
468             config => $config,
469             args => \@ARGV,
470             });
471              
472             Creates and returns a new object for a subclass of App::Sqitch::Command. It
473             parses options from the C<args> parameter, calls C<configure> to merge
474             configuration with the options, and finally calls C<new> with the resulting
475             hash. Supported parameters are the same as for C<load> except for the
476             C<command> parameter, which will be ignored.
477              
478             =head3 C<new>
479              
480             my $cmd = App::Sqitch::Command->new(%params);
481              
482             Instantiates and returns a App::Sqitch::Command object. This method is not
483             designed to be overridden by subclasses; they should implement
484             L<C<BUILDARGS>|Moo::Manual::Construction/BUILDARGS> or
485             L<C<BUILD>|Moo::Manual::Construction/BUILD>, instead.
486              
487             =head2 Accessors
488              
489             =head3 C<sqitch>
490              
491             my $sqitch = $cmd->sqitch;
492              
493             Returns the L<App::Sqitch> object that instantiated the command. Commands may
494             access its properties in order to manage global state.
495              
496             =head2 Overridable Instance Methods
497              
498             These methods should be overridden by all subclasses.
499              
500             =head3 C<execute>
501              
502             $cmd->execute;
503              
504             Executes the command. This is the method that does the work of the command.
505             Must be overridden in all subclasses. Dies if the method is not overridden for
506             the object on which it is called, or if it is called against a base
507             App::Sqitch::Command object.
508              
509             =head3 C<command>
510              
511             my $command = $cmd->command;
512              
513             The name of the command. Defaults to the last part of the package name, so as
514             a rule you should not need to override it, since it is that string that Sqitch
515             uses to find the command class.
516              
517             =head2 Utility Instance Methods
518              
519             These methods are mainly provided as utilities for the command subclasses to
520             use.
521              
522             =head3 C<default_target>
523              
524             my $target = $cmd->default_target;
525              
526             This method returns the default target. It should only be used by commands
527             that don't use a C<parse_args()> to find and load a target.
528              
529             This method should always return a target option, never C<undef>. If the
530             C<core.engine> configuration option has been set, then the target will support
531             that engine. In the latter case, if C<engine.$engine.target> is set, that
532             value will be used. Otherwise, the returned target will have a URI of C<db:>
533             and no associated engine; the C<engine> method will throw an exception. This
534             behavior should be fine for commands that don't need to load the engine.
535              
536             =head3 C<parse_args>
537              
538             my ($name1, $name2, $targets, $changes) = $cmd->parse_args(
539             names => \@names,
540             target => $target_name,
541             args => \@args
542             );
543              
544             Examines each argument to determine whether it's a known change spec or
545             identifies a target or engine. Unrecognized arguments will replace false
546             values in the C<names> array reference. Any remaining unknown arguments will
547             trigger an error.
548              
549             Returns a list consisting all the desired names, followed by an array
550             reference of target objects and an array reference of change specs.
551              
552             This method is useful for commands that take a number of arguments where the
553             order may be mixed.
554              
555             The supported parameters are:
556              
557             =over
558              
559             =item C<args>
560              
561             An array reference of the command arguments.
562              
563             =item C<target>
564              
565             The name of a target, if any. Useful for commands that offer their own
566             C<--target> option. This target will be the default target, and the first
567             returned in the targets array.
568              
569             =item C<names>
570              
571             An array reference of names. If any is false, its place will be taken by an
572             otherwise unrecognized argument. The number of values in this array reference
573             determines the number of values returned as names in the return values. Such
574             values may still be false or undefined; it's up to the caller to decide what
575             to do about that.
576              
577             =item C<all>
578              
579             In the event that no targets are recognized (or changes that implicitly
580             recognize the default target), if this parameter is true, then all known
581             targets from the configuration will be returned.
582              
583             =item C<no_changes>
584              
585             If true, the parser will not check to see if any argument corresponds to a
586             change. The last value returned will be C<undef> instead of the usual array
587             reference. Any argument that might have been recognized as a change will
588             instead be included in either the C<targets> array -- if it's recognized as a
589             target -- or used to set names to return. Any remaining are considered
590             unknown arguments and will result in an exception.
591              
592             =back
593              
594             If a target parameter is passed, it will always be instantiated and returned
595             as the first item in the "target" array, and arguments recognized as changes
596             in the plan associated with that target will be returned as changes.
597              
598             If no target is passed or appears in the arguments, a default target will be
599             instantiated based on the command-line options and configuration. Unlike the
600             target returned by C<default_target>, this target B<must> have an associated
601             engine specified by the configuration. This is on the assumption that it will
602             be used by commands that require an engine to do their work. Of course, any
603             changes must be recognized from the plan associated with this target.
604              
605             Changes are only recognized if they're found in the plan of the target that
606             precedes them. If no target precedes them, the target specified by the
607             C<target> parameter or the default target will be searched. Such changes can
608             be specified in any way documented in L<sqitchchanges>.
609              
610             Targets may be recognized by any one of these types of arguments:
611              
612             =over
613              
614             =item * Target Name
615              
616             =item * Database URI
617              
618             =item * Engine Name
619              
620             =item * Plan File
621              
622             =back
623              
624             In the case of plan files, C<parse_args()> will return the first target it
625             finds for that plan file, even if multiple targets use the same plan file. The
626             order of precedence for this determination is the default project target,
627             followed by named targets, then engine targets.
628              
629             =head3 C<target_params>
630              
631             my $target = App::Sqitch::Target->new( $cmd->target_params );
632              
633             Returns a list of parameters suitable for passing to the C<new> or
634             C<all_targets> constructors of App::Sqitch::Target.
635              
636             =head3 C<run>
637              
638             $cmd->run('echo hello');
639              
640             Runs a system command and waits for it to finish. Throws an exception on
641             error.
642              
643             =head3 C<capture>
644              
645             my @files = $cmd->capture(qw(ls -lah));
646              
647             Runs a system command and captures its output to C<STDOUT>. Returns the output
648             lines in list context and the concatenation of the lines in scalar context.
649             Throws an exception on error.
650              
651             =head3 C<probe>
652              
653             my $git_version = $cmd->capture(qw(git --version));
654              
655             Like C<capture>, but returns just the C<chomp>ed first line of output.
656              
657             =head3 C<verbosity>
658              
659             my $verbosity = $cmd->verbosity;
660              
661             Returns the verbosity level.
662              
663             =head3 C<trace>
664              
665             Send trace information to C<STDOUT> if the verbosity level is 3 or higher.
666             Trace messages will have C<trace: > prefixed to every line. If it's lower than
667             3, nothing will be output.
668              
669             =head3 C<debug>
670              
671             $cmd->debug('Found snuggle in the crib.');
672              
673             Send debug information to C<STDOUT> if the verbosity level is 2 or higher.
674             Debug messages will have C<debug: > prefixed to every line. If it's lower than
675             2, nothing will be output.
676              
677             =head3 C<info>
678              
679             $cmd->info('Nothing to deploy (up-to-date)');
680              
681             Send informational message to C<STDOUT> if the verbosity level is 1 or higher,
682             which, by default, it is. Should be used for normal messages the user would
683             normally want to see. If verbosity is lower than 1, nothing will be output.
684              
685             =head3 C<comment>
686              
687             $cmd->comment('On database flipr_test');
688              
689             Send comments to C<STDOUT> if the verbosity level is 1 or higher, which, by
690             default, it is. Comments have C<# > prefixed to every line. If verbosity is
691             lower than 1, nothing will be output.
692              
693             =head3 C<emit>
694              
695             $cmd->emit('core.editor=emacs');
696              
697             Send a message to C<STDOUT>, without regard to the verbosity. Should be used
698             only if the user explicitly asks for output, such as for
699             C<sqitch config --get core.editor>.
700              
701             =head3 C<vent>
702              
703             $cmd->vent('That was a misage.');
704              
705             Send a message to C<STDERR>, without regard to the verbosity. Should be used
706             only for error messages to be printed before exiting with an error, such as
707             when reverting failed changes.
708              
709             =head3 C<page>
710              
711             $sqitch->page('Search results:');
712              
713             Like C<emit()>, but sends the output to a pager handle rather than C<STDOUT>.
714             Unless there is no TTY (such as when output is being piped elsewhere), in
715             which case it I<is> sent to C<STDOUT>. Meant to be used to send a lot of data
716             to the user at once, such as when display the results of searching the event
717             log:
718              
719             $iter = $engine->search_events;
720             while ( my $change = $iter->() ) {
721             $cmd->page(join ' - ', @{ $change }{ qw(change_id event change) });
722             }
723              
724             =head3 C<warn>
725              
726             $cmd->warn('Could not find nerble; using nobble instead.');
727              
728             Send a warning messages to C<STDERR>. Warnings will have C<warning: > prefixed
729             to every line. Use if something unexpected happened but you can recover from
730             it.
731              
732             =head3 C<usage>
733              
734             $cmd->usage('Missing "value" argument');
735              
736             Sends the specified message to C<STDERR>, followed by the usage sections of
737             the command's documentation. Those sections may be named "Name", "Synopsis",
738             or "Options". Any or all of these will be shown. The doc used to display them
739             will be the first found of:
740              
741             =over
742              
743             =item C<sqitch-$command-usage>
744              
745             =item C<sqitch-$command>
746              
747             =item C<sqitch>
748              
749             =item C<App::Sqitch::Command::$command>
750              
751             =item C<App::Sqitch::Command>
752              
753             =back
754              
755             For an ideal usage messages, C<sqitch-$command-usage.pod> should be created by
756             all command subclasses.
757              
758             =head1 See Also
759              
760             =over
761              
762             =item L<sqitch>
763              
764             The Sqitch command-line client.
765              
766             =back
767              
768             =head1 Author
769              
770             David E. Wheeler <david@justatheory.com>
771              
772             =head1 License
773              
774             Copyright (c) 2012-2023 iovation Inc., David E. Wheeler
775              
776             Permission is hereby granted, free of charge, to any person obtaining a copy
777             of this software and associated documentation files (the "Software"), to deal
778             in the Software without restriction, including without limitation the rights
779             to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
780             copies of the Software, and to permit persons to whom the Software is
781             furnished to do so, subject to the following conditions:
782              
783             The above copyright notice and this permission notice shall be included in all
784             copies or substantial portions of the Software.
785              
786             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
787             IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
788             FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
789             AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
790             LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
791             OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
792             SOFTWARE.
793              
794             =cut