App-karr
view release on metacpan or search on metacpan
lib/App/karr/Cmd/Pick.pm view on Meta::CPAN
# ABSTRACT: Atomically find and claim the next available task
package App::karr::Cmd::Pick;
our $VERSION = '0.601';
use Moo;
use MooX::Cmd;
use MooX::Options (
usage_string => 'USAGE: karr pick --claim NAME [--move STATUS] [--status LIST] [--tags LIST] [--compact]',
);
use App::karr::Role::BoardAccess;
use App::karr::Role::Output;
use App::karr::Role::CompactOutput;
use App::karr::Role::DependencyCheck;
use App::karr::Role::PickRules;
use App::karr::Role::ClaimDefault;
use App::karr::Task;
use App::karr::Config;
use App::karr::Lock;
use App::karr::Error ();
use Time::Piece;
with 'App::karr::Role::BoardAccess', 'App::karr::Role::Output',
'App::karr::Role::CompactOutput', 'App::karr::Role::ClaimTimeout',
'App::karr::Role::DependencyCheck', 'App::karr::Role::PickRules',
'App::karr::Role::ClaimDefault';
option claim => (
is => 'ro',
format => 's',
doc => 'Agent name to claim the task for (defaults to KARR_CLAIM)',
);
option status => (
is => 'ro',
format => 's',
doc => 'Source status(es) to pick from (comma-separated)',
);
option move => (
is => 'ro',
format => 's',
doc => 'Move picked task to this status',
);
option tags => (
is => 'ro',
format => 's',
doc => 'Only pick tasks matching at least one tag',
);
sub execute {
my ($self, $args_ref, $chain_ref) = @_;
# --claim was `required => 1` before ADR 0005; KARR_CLAIM now fills it when the
# flag is omitted. pick has to claim under some name, so when neither supplies
# one this is a usage error (exit 2, as the old required was) naming both ways.
# Before sync_before, so an invalid invocation fails without a network round
# trip, the way an option-parse error always did.
my $claim = $self->resolved_claim;
$self->usage_error(
App::karr::Error::mandatory_claim_message( 'pick', 'pick', '--claim', 'NAME' ) )
unless defined $claim && length $claim;
$self->sync_before;
$self->require_board;
my $ec = $self->store->effective_config;
my $timeout = $self->_parse_timeout($ec->{claim_timeout} // '1h');
# Before any lock is taken: --move is a plain option value, and a bad one used
# to be discovered only after a task had already been locked and claimed, so
# the pick parked it in a status that is not a column (ticket #54). Pick does
# not go through apply_status_change -- it has its own compare-and-swap loop --
# so the check is here.
App::karr::Config->from_merged($ec)->validate_status($self->move)
if defined $self->move;
# --status is a comma-separated list of source statuses, and every element is
# a status the board must know -- a typo used to be answered with "No available
# tasks to pick." and exit 0, which reads as "no work" when the truth is "no
# such status" (ticket #271). The filter form accepts `archived` the way
# `list --status` does (App::karr::Config/validate_status_filter).
( run in 4.373 seconds using v1.01-cache-2.11-cpan-85d3896f969 )