NAME
Pb - a workflow system made from Perl and bash
VERSION
This document describes version 0.02 of Pb.
SYNOPSIS
use Pb;
use Path::Tiny;
use Types::Standard -types;
my %HOSTS =
(
integration => 'foo.mydomain.com',
staging => 'bar.mydomain.com',
production => 'baz.mydomain.com',
);
command 'push-file' =>
arg env => one_of [ keys %HOSTS ],
arg file => must_be Str,
flow
{
verify { pwd eq $ENV{MY_ROOT_DIR} } 'must be run from $MY_ROOT_DIR';
verify { -f $FLOW->{file} } 'file must exist';
my $host = $HOSTS{$FLOW->{env}};
my $from = path($FLOW->{file});
my $dir = $from->dirname;
SH scp => -p => $from, "$host:$dir";
CODE sub { say "it worked!" };
};
Pb->go;
DESCRIPTION
If you are a devops developer--even if you're a devops developer who doesn't believe that devops is really a thing--you spend a bunch of your time writing control scripts. Some of them you probably write in bash
, because job control is one of those things that bash
is actually good at. A lot of them you probably write in Perl, because programming is one of those things that bash
is pretty terrible at. Trying to do real programming in bash
is pretty horrifying, but trying to do job control in Perl isn't much nicer: the return value of system
is backwards, there's no equivalent to bash -e
, END
blocks don't get run if your script is dying due to a signal, and so on and so forth, ad inifinitum. None of the deficiencies of Perl in this area are very significant on their own, but it can become death by a thousand cuts as you try to layer more and more devops complexity onto your Perl scripts. In the end, if you write it in bash
, you'll end up wishing you'd written it in Perl, and if you write it in Perl, you'll say to yourselt at least once before it's done: man, this part would have been easier in bash
.
Well, now you no longer need to choose. Leadpipe takes Perl and bash
and glues them together to form Pb
, a module which allows you to quickly write commands which can do one or all of the following:
Can have subcommands (reminiscent of
git
).Can have command-line options and command-line arguments with sophisticated validation.
Can run pre-command verification checks to ensure a known state.
Can break your command down into steps (called "directives"), where each step can be printed out instead of performing it (in
--pretend
mode) or performed only after verification from the user (in--interactive
mode).Shell (
SH
) directives look (mostly) just likebash
commands, with quoting handled for you easily, and you have the full range ofbash
syntax (unlike withsystem
).But you can also do code (
CODE
) directives, which are pure Perl.And run (
RUN
) directives, which allow one subcommand to call another, retaining the environment and context.Will abort if any individual directive fails (similar to
bash -e
).Can automatically log to a file.
Can automatically abort if a previous instance of the script is running.
Can save the result of the script run to a file, and (optionally) refuse to run if the previous run failed. This can be useful in a cronjob situation where a run error needs to be cleared manually before automated runs can resume.
Much much more.
Honestly, most of the things discussed above are not original to this module. The main value of Leadpipe is that it glues it all together and gives you a declarative syntax that looks like Perl (because it is), but also looks like what you're actually doing. Syntax is provided in a similar fashion to Moose (i.e. not using source filters or Devel::Declare
or even Perl's new(ish) keyword plugin API), but Moo is used rather than Moose to keep startup time quick.
The main functionality of Leadpipe is provided by the following modules:
If you decide not to use Leadpipe (perhaps you don't like the glitzy syntax layer), you should definitely look at those other modules for whatever solution you're contemplating.
COMMAND DEFINITION SYNTAX
command
Declare a Pb command.
base_command
Declare a base (i.e. default) command.
arg
Declare an argument to a command.
opt
Declare an option to a command.
must_be
Specify the type (of either an argument or option).
one_of
Specify the valid values for an enum type (for either an argument or option). Use instead of must_be
, not in addition to.
also
Specify additional properties (other than type) for an option.
log_to
Specify a logfile for the output of a command.
control_via
Specify a control structure. This is where you put pidfile, statusfile, etc.
flow
Specify the code for the actual command.
verify
Make an assertion (using a code block) which must return a true value before the command will execute. Also specify the error message if the assertion fails.
SH
Run a command in bash
. If the command does not exit with 0, the entire command will exit.
CODE
Run a code block. If the block returns a falsey value, the entire command will exit.
RUN
Run one command inside another. Although you pass the nested command its own arguments, all other parts of the context (including options) are retained.
fatal
Print a fatal error and exit.
STATUS
This module is very new, although it is being actively used for small projects. Documentation is skeletal and the API may change a bit before it all shakes out. Please be cautious in adopting it for anything mission-critical, but I would love to get any feedback you may have from trying it out for your own experimental projects.
USAGE
Doing use Pb
gets you all the syntax above, plus the following global(ish) variables:
$FLOW
-
This is the Pb::Command::Context for the currently running command. Context variables (including arguments) can be accessed as if
$FLOW
were a hashref (e.g.$FLOW->{file}
), but it's really an object with proper methods (e.g.$FLOW->error
). %OPT
-
This is the hash which contains the values of all options to the command (e.g.
$OPT{pretend}
).
You also get these functions passed through from PerlX::bash:
pwd
-
Same as "cwd" in Cwd.
BUGS, CAVEATS and NOTES
Probably lots. Check out TODO.md
in the distribution for things that are in the queue to be done.
SUPPORT
Perldoc
You can find documentation for this module with the perldoc command.
perldoc Pb
Bugs / Feature Requests
This module is on GitHub. Feel free to fork and submit patches. Please note that I develop via TDD (Test-Driven Development), so a patch that includes a failing test is much more likely to get accepted (or at least likely to get accepted more quickly).
If you just want to report a problem or suggest a feature, that's okay too. You can create an issue on GitHub here: https://github.com/barefootcoder/leadpipe/issues.
Source Code
none https://github.com/barefootcoder/leadpipe
git clone https://github.com/barefootcoder/leadpipe.git
AUTHOR
Buddy Burden <barefootcoder@gmail.com>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2020 by Buddy Burden.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)