App::Sqitch::Command - Sqitch Command support
my $cmd = App::Sqitch::Command->load( deploy => \%params );
$cmd->run;
App::Sqitch::Command is the base class for all Sqitch commands.
"ENGINES"
Returns the list of supported engines, currently:
- •
- "firebird"
- •
- "mysql"
- •
- "oracle"
- •
- "pg"
- •
- "sqlite"
- •
- "vertica"
- •
- "exasol"
- •
- "snowflake"
"options"
my @spec = App::Sqitch::Command->options;
Returns a list of Getopt::Long options specifications. When "load"
loads the class, any options passed to the command will be parsed using these
values. The keys in the resulting hash will be the first part of each option,
with dashes converted to underscores. This hash will be passed to
"configure" along with a App::Sqitch::Config object for munging into
parameters to be passed to the constructor.
Here's an example excerpted from the "config" command:
sub options {
return qw(
get
unset
list
global
system
config-file=s
);
}
This will result in hash keys with the same names as each option except for
"config-file=s", which will be named "config_file".
"configure"
my $params = App::Sqitch::Command->configure($config, $options);
Takes two arguments, an App::Sqitch::Config object and the hash of command-line
options as specified by "options". The returned hash should be the
result of munging these two objects into a hash reference of parameters to be
passed to the command subclass constructor.
By default, this method converts dashes to underscores in command-line options
keys, and then merges the configuration values with the options, with the
command-line options taking priority. You may wish to override this method to
do something different.
"class_for"
my $subclass = App::Sqitch::Command->subclass_for($sqitch, $cmd_name);
This method attempts to load the subclass of App::Sqitch::Commmand that
corresponds to the command name. Returns "undef" and sends errors to
the "debug" method of the <$sqitch> object if no such subclass
can be loaded.
"load"
my $cmd = App::Sqitch::Command->load( \%params );
A factory method for instantiating Sqitch commands. It loads the subclass for
the specified command and calls "create" to instantiate and return
an instance of the subclass. Sends error messages to the "debug"
method of the "sqitch" parameter and throws an exception if the
subclass does not exist or cannot be loaded. Supported parameters are:
- "sqitch"
- The App::Sqitch object driving the whole thing.
- "config"
- An App::Sqitch::Config representing the current application
configuration state.
- "command"
- The name of the command to be executed.
- "args"
- An array reference of command-line arguments passed to the
command.
"create"
my $pkg = App::Sqitch::Command->class_for( $sqitch, $cmd_name )
or die "No such command $cmd_name";
my $cmd = $pkg->create({
sqitch => $sqitch,
config => $config,
args => \@ARGV,
});
Creates and returns a new object for a subclass of App::Sqitch::Command. It
parses options from the "args" parameter, calls
"configure" to merge configuration with the options, and finally
calls "new" with the resulting hash. Supported parameters are the
same as for "load" except for the "command" parameter,
which will be ignored.
"new"
my $cmd = App::Sqitch::Command->new(%params);
Instantiates and returns a App::Sqitch::Command object. This method is not
designed to be overridden by subclasses; they should implement
"BUILDARGS" or "BUILD", instead.
"sqitch"
my $sqitch = $cmd->sqitch;
Returns the App::Sqitch object that instantiated the command. Commands may
access its properties in order to manage global state.
These methods should be overridden by all subclasses.
"execute"
$cmd->execute;
Executes the command. This is the method that does the work of the command. Must
be overridden in all subclasses. Dies if the method is not overridden for the
object on which it is called, or if it is called against a base
App::Sqitch::Command object.
"command"
my $command = $cmd->command;
The name of the command. Defaults to the last part of the package name, so as a
rule you should not need to override it, since it is that string that Sqitch
uses to find the command class.
These methods are mainly provided as utilities for the command subclasses to
use.
"default_target"
my $target = $cmd->default_target;
This method returns the default target. It should only be used by commands that
don't use a "parse_args()" to find and load a target.
This method should always return a target option, never "undef". If
the "core.engine" configuration option has been set, then the target
will support that engine. In the latter case, if
"engine.$engine.target" is set, that value will be used. Otherwise,
the returned target will have a URI of "db:" and no associated
engine; the "engine" method will throw an exception. This behavior
should be fine for commands that don't need to load the engine.
"parse_args"
my ($name1, $name2, $targets, $changes) = $cmd->parse_args(
names => \@names,
target => $target_name,
args => \@args
);
Examines each argument to determine whether it's a known change spec or
identifies a target or engine. Unrecognized arguments will replace false
values in the "names" array reference. Any remaining unknown
arguments will trigger an error.
Returns a list consisting all the desired names, followed by an array reference
of target objects and an array reference of change specs.
This method is useful for commands that take a number of arguments where the
order may be mixed.
The supported parameters are:
- "args"
- An array reference of the command arguments.
- "target"
- The name of a target, if any. Useful for commands that
offer their own "--target" option. This target will be the
default target, and the first returned in the targets array.
- "names"
- An array reference of names. If any is false, its place
will be taken by an otherwise unrecognized argument. The number of values
in this array reference determines the number of values returned as names
in the return values. Such values may still be false or undefined; it's up
to the caller to decide what to do about that.
- "all"
- In the event that no targets are recognized (or changes
that implicitly recognize the default target), if this parameter is true,
then all known targets from the configuration will be returned.
- "no_changes"
- If true, the parser will not check to see if any argument
corresponds to a change. The last value returned will be "undef"
instead of the usual array reference. Any argument that might have been
recognized as a change will instead be included in either the
"targets" array -- if it's recognized as a target -- or used to
set names to return. Any remaining are considered unknown arguments and
will result in an exception.
If a target parameter is passed, it will always be instantiated and returned as
the first item in the "target" array, and arguments recognized as
changes in the plan associated with that target will be returned as changes.
If no target is passed or appears in the arguments, a default target will be
instantiated based on the command-line options and configuration. Unlike the
target returned by "default_target", this target
must have an
associated engine specified by the configuration. This is on the assumption
that it will be used by commands that require an engine to do their work. Of
course, any changes must be recognized from the plan associated with this
target.
Changes are only recognized if they're found in the plan of the target that
precedes them. If no target precedes them, the target specified by the
"target" parameter or the default target will be searched. Such
changes can be specified in any way documented in sqitchchanges.
Targets may be recognized by any one of these types of arguments:
- •
- Target Name
- •
- Database URI
- •
- Engine Name
- •
- Plan File
In the case of plan files, "parse_args()" will return the first target
it finds for that plan file, even if multiple targets use the same plan file.
The order of precedence for this determination is the default project target,
followed by named targets, then engine targets.
"target_params"
my $target = App::Sqitch::Target->new( $cmd->target_params );
Returns a list of parameters suitable for passing to the "new" or
"all_targets" constructors of App::Sqitch::Target.
"run"
$cmd->run('echo hello');
Runs a system command and waits for it to finish. Throws an exception on error.
"capture"
my @files = $cmd->capture(qw(ls -lah));
Runs a system command and captures its output to "STDOUT". Returns the
output lines in list context and the concatenation of the lines in scalar
context. Throws an exception on error.
"probe"
my $git_version = $cmd->capture(qw(git --version));
Like "capture", but returns just the "chomp"ed first line of
output.
"verbosity"
my $verbosity = $cmd->verbosity;
Returns the verbosity level.
"trace"
Send trace information to "STDOUT" if the verbosity level is 3 or
higher. Trace messages will have "trace: " prefixed to every line.
If it's lower than 3, nothing will be output.
"debug"
$cmd->debug('Found snuggle in the crib.');
Send debug information to "STDOUT" if the verbosity level is 2 or
higher. Debug messages will have "debug: " prefixed to every line.
If it's lower than 2, nothing will be output.
"info"
$cmd->info('Nothing to deploy (up-to-date)');
Send informational message to "STDOUT" if the verbosity level is 1 or
higher, which, by default, it is. Should be used for normal messages the user
would normally want to see. If verbosity is lower than 1, nothing will be
output.
"comment"
$cmd->comment('On database flipr_test');
Send comments to "STDOUT" if the verbosity level is 1 or higher,
which, by default, it is. Comments have "# " prefixed to every line.
If verbosity is lower than 1, nothing will be output.
"emit"
$cmd->emit('core.editor=emacs');
Send a message to "STDOUT", without regard to the verbosity. Should be
used only if the user explicitly asks for output, such as for "sqitch
config --get core.editor".
"vent"
$cmd->vent('That was a misage.');
Send a message to "STDERR", without regard to the verbosity. Should be
used only for error messages to be printed before exiting with an error, such
as when reverting failed changes.
"page"
$sqitch->page('Search results:');
Like "emit()", but sends the output to a pager handle rather than
"STDOUT". Unless there is no TTY (such as when output is being piped
elsewhere), in which case it
is sent to "STDOUT". Meant to be
used to send a lot of data to the user at once, such as when display the
results of searching the event log:
$iter = $engine->search_events;
while ( my $change = $iter->() ) {
$cmd->page(join ' - ', @{ $change }{ qw(change_id event change) });
}
"warn"
$cmd->warn('Could not find nerble; using nobble instead.');
Send a warning messages to "STDERR". Warnings will have "warning:
" prefixed to every line. Use if something unexpected happened but you
can recover from it.
"usage"
$cmd->usage('Missing "value" argument');
Sends the specified message to "STDERR", followed by the usage
sections of the command's documentation. Those sections may be named
"Name", "Synopsis", or "Options". Any or all of
these will be shown. The doc used to display them will be the first found of:
- "sqitch-$command-usage"
- "sqitch-$command"
- "sqitch"
- "App::Sqitch::Command::$command"
- "App::Sqitch::Command"
For an ideal usage messages, "sqitch-$command-usage.pod" should be
created by all command subclasses.
- sqitch
- The Sqitch command-line client.
David E. Wheeler <
[email protected]>
Copyright (c) 2012-2022 iovation Inc., David E. Wheeler
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.