App-Task
view release on metacpan or search on metacpan
lib/App/Task.pm view on Meta::CPAN
App::Task - Nest tasks w/ indented output and pre/post headers
=head1 VERSION
This document describes App::Task version 0.03
=head1 SYNOPSIS
use App::Task;
task "â¦" => sub {};
task "â¦" => ["system","args","here"], {fatal => 1};
task "â¦" => "system command here";
Nested
task "â¦" => sub {
task "â¦" => sub {
task "â¦" => sub { ⦠};
};
task "â¦" => sub { ⦠};
task "â¦" => sub {
task "â¦" => sub {
task "â¦" => sub { ⦠};
};
};
}
=head1 DESCRIPTION
This allows us to create scripts that organize tasks together and have their output be organized similarly and with added clarity.
It does this by wrapping each task in a starting/ending output line, indenting output congruent with nested C<task()> depth.
For example, say this:
system(â¦);
foo();
system(â¦,â¦);
say test_foo() ? "foo is good" : "foo is down";
outputs this:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit amet.
Facilisi morbi tempus iaculis urna id volutpat lacus laoreet.
Ullamcorper eget nulla facilisi etiam dignissim diam.
Maecenas volutpat blandit aliquam etiam erat velit scelerisque in dictum.
foo is good
Nothing wrong with that but it could be easier to process visually, so if we C<task()>âd it up a bit like this:
task "setup foo" => sub {
task "configure foo" => "â¦";
task "run foo" => \&foo;
};
task "finalize foo" => sub {
task "enable barring" => [â¦,â¦];
task "verify foo" => sub {
my $status = test_foo();
say $status ? "foo is good" : "foo is down";
return $status;
};
};
Now you get:
ââââ [1.1] setup foo â¦
ââââ [2.1] configure foo â¦
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
⦠done (configure foo).
ââââ [2.2] run foo â¦
Nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit amet.
Facilisi morbi tempus iaculis urna id volutpat lacus laoreet.
⦠done (run foo).
⦠done (setup foo).
ââââ [1.2] finalize foo â¦
ââââ [2.1] enable barring â¦
Ullamcorper eget nulla facilisi etiam dignissim diam.
Maecenas volutpat blandit aliquam etiam erat velit scelerisque in dictum.
⦠done (enable barring).
ââââ [2.2] verify foo â¦
foo is down
⦠failed (verify foo).
⦠done (finalize foo).
=head1 INTERFACE
Each variant has a pre/post heading and indented output.
=head2 task NAME => CODEREF
If CODEREF returns true the post heading will be âdoneâ, if it returns false it will be âfailedâ.
To make CODEREF fatal just throw an exception.
=head2 task NAME => CMD_STRING
CMD_STRING is a string suitable for C<system(CMD_STRING)>.
If the command exits clean the post heading will be âdoneâ, if it exits unclean it will be âfailedâ.
To make CMD_STRING exiting unclean be fatal you can set fatal to true in the optional 3rd argument to task:
task "prep fiddler" => "/usr/bin/fiddler prep"; # will continue on unclean exit
task "create fiddler" => "/usr/bin/fiddler new", { fatal => 1 }; # will die on unclean exit
=head2 task NAME => CMD_ARRAYREF
task NAME => CMD_ARRAYREF is a string suitable for C<system(@{CMD_ARRAYREF})>.
If the command exits clean the post heading will be âdoneâ, if it exits unclean it will be âfailedâ.
To make CMD_STRING exiting unclean be fatal you can set fatal to true in the optional 3rd argument to task:
task "prep fiddler" => ["/usr/bin/fiddler", "prep"]; # will continue on unclean exit
task "create fiddler" => ["/usr/bin/fiddler", "new"], { fatal => 1 }; # will die on unclean exit
=head3 $ENV{App_Task_DRYRUN}
If this is true the C<CMD_ARRAYREF> and C<CMD_STRING> version of C<task()> will out put a DEBUG string of the command it would have run.
You can then check it in your applicationâs code to do things differently in a dry run mode. An example is found in the L</App::Task::tie_task()> example function below.
=head2 App::Task::tie_task()
Not exported or exportable.
Take no arguments. Returns the tied() objects for STDOUT, STDERR.
App::Task::tie_task();
my ($o, $e) = App::Task::tie_task();
Dies if you call it and STDOUT or STDERR are already tied.
Some modules donât play well with tied STDOUT/STDERR. To get them to work you need to do some wrapping to essentially:
redefine the thing in question to do this pseudo code logic:
if (SDTDOUT/STDERR are tied) {
untie STDOUT/STDERR
do the original thing
reset STDOUT/STDERR by calling C<App::Task::tie_task()>
( run in 2.735 seconds using v1.01-cache-2.11-cpan-13bb782fe5a )