NAME Command::Template - A template to build command line arrays, and run them VERSION This document describes Command::Template version 0.001. SYNOPSIS use Command::Template qw< command_runner command_template cr ct >; #### COMMAND EXPANSION GENERATION (NO EXECUTION) #### # command_template is aliased to ct my $ct = command_template(qw{ ls [options=-l] }); # @c1 = qw< ls -l / > my @c1 = $ct->generate(dir => '/'); # @c2 = qw< ls -la / > my @c2 = $ct->generate(dir => '/etc', options => '-la'); # @c3 = @c4 = qw< ls /usr/bin > my @c3 = $ct->generate(dir => '/usr/bin', options => undef); my @c4 = $ct->generate(dir => '/usr/bin', options => []); # @c5 = qw< ls -l -a /usr/bin > my @c5 = $ct->generate(dir => '/usr/bin', options => [qw< -l -a >]); #### COMMAND RUNNING (VIA IPC::Run) #### # command_runner is aliased to cr my $runner = command_runner(qw{ ls [options=-l] }); # run command qw< ls -l / >, returns a Command::Template::RunRecord my $r = $runner->run(dir => '/'); my $run_successful = $r->success; my $exit_code = $r->exit_code; # 0 is OK as usual in UNIX my $received_signal = $r->signal; # e.g. if killed, ... my $stdout = $r->stdout; my $stderr = $r->stderr; my $merged = $r->merged; # stderr then stdout, no newlines # added # command_runner is aliased to cr my $other_runner = cr(qw< cat >); # gives stdin as stdout my $message = "blah\nblah"; $r = $other_runner->run(-stdin => $message); my $equal = $r->stdout eq $message; # true DESCRIPTION Command::Template eases the creation of objects that help building up command-lines and/or to run them. As an example, it might be needed to generate multiple commands according to the following template: ls [options=-l] i.e. the ls command, where there might be some options (defaulting to option -l) and there MUST be a directory dir (which in this case has no default). The following possible expansions adhere to the template above: ls -l / ls -la /usr ls -l -a /etc ls /run while the following does not (because there is no directory, which we want because we used the <...> form): ls -l The module provides two different interfaces: * "command_template" allows generating the commands as lists, which are then supposed to be used somehow (e.g. provided to system); * "command_runner" allows running the commands via IPC::Run. Both adhere to the same "Expansion Rules" explained below and implemented in Command::Template::Instance. Expansion Rules A template in Command::Template resembles the way commands are explained in documentation: * required parameters are enclosed by <...> delimiters; * optional parameters are enclosed by [...] delimiters. Parameters name can only start with a letter or an underscore, then can be followed by any sequence of underscores, letters, and digits. The following names are valid: foo bar dir baz1 baz_2 name_or_surname Any parameter can be optionally set with a default value, which can be set with the = sign, like in the following examples: Spaces are preserved starting immediately after the = sign. When Template::Command::Instance expands a template, it uses a hash that maps each name to the value it should take: * if undef, then the corresponding item is removed from the command. This allows getting rid of a default value set for an optional parameter; it is an error (leading to an exception) if the parameter is required; * if any other plain scalar, it is set as the value in the specific command line parameter location; * if an array reference, all items inside are put in the specific command line parameter location. The last possibility provides the flexibility to e.g. set options that require a parameter (e.g. it would be the case of option -name for command find). Running Commands While Command::Template::Instance only allows generating command lines as lists of strings, Command::Template::Runner allows running them by means of IPC::Run. All the heavy work for expanding is provided by Command::Template::Instance behind the scenes; the "SYNOPSIS" contains examples of actual running of commands. INTERFACE command_runner # parse a command line template and use it for running commands my $cr = command_runner(qw{ ls [options=-l] }); Returns a Command::Template::Runner object with a run method that allows actually running generated commands via IPC::Run. Each run returns a Command::Template::Runner::Record object that allows peeking into the actual result of the run. my $r = $cr->run(options => '-la', '/etc'); say $r->stdout if $r->success; cr Alias for "command_runner". command_template my $ct = command_template(qw{ galook [baz] [sil=Y] }) Returns a Command::Template::Instance object with a generate method that performs the actual expansion, returning a list of strings representing the command line. ct Alias for "command_template". EXTENDING If extending Command::Template is of interest, here are a few hints: * class Command::Template::Instance encapsulates parsing a command template and expanding it for generating command lists, based on a hash with values binding; * class Command::Template::Runner provides a simple running facility around Command::Template::Instance that uses IPC::Run to run expanded commands, returning the result as a Command::Template::Runner::Record object. * class Command::Template::Runner::Record provides accessors into the outcome of a single run from Command::Template::Runner. Possible reasons for expanding might be: * different or additional rules for expansions are needed. If this is the case, the alternative to Command::Template::Instance must provide a generate method; Comman::Template::Runner can still be used, as long as a reference to the alternative object for the instance is passed to the constructor. * a different running facility is needed. In this case, it suffices to impelement a new runner class, leveraging Command::Template::Instance for the command expansion. BUGS AND LIMITATIONS Minimum perl version 5.24. Report bugs through GitHub (patches welcome) at https://github.com/polettix/Command-Template. AUTHOR Flavio Poletti COPYRIGHT AND LICENSE Copyright 2021 by Flavio Poletti Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.