App-karr
view release on metacpan or search on metacpan
lib/App/karr/Cmd/Edit.pm view on Meta::CPAN
# (ticket #78). The outer guard had drifted back to truth while the
# comment still read length-not-truth (ticket #153). What the append
# itself does -- blank-line separator, no leading separator on an empty
# body, optional UTC stamp -- lives in App::karr::Task::append_body,
# shared with handoff, which held a copy of it (ticket #238).
$task->append_body( $self->append_body, $self->timestamp )
if defined $self->append_body && length $self->append_body;
if (defined $self->add_tag && length $self->add_tag) {
my @new = split /,/, $self->add_tag;
my %existing = map { $_ => 1 } @{$task->tags};
push @{$task->tags}, grep { !$existing{$_} } @new;
}
if (defined $self->remove_tag && length $self->remove_tag) {
my %remove = map { $_ => 1 } split /,/, $self->remove_tag;
$task->tags([grep { !$remove{$_} } @{$task->tags}]);
}
# The --add-tag/--remove-tag shape: append-unique and remove, so one
# rule covers both list fields (ticket #124).
if ($add_depends) {
my %existing = map { $_ => 1 } @{$task->depends_on};
push @{$task->depends_on}, grep { !$existing{$_} } @$add_depends;
}
if ($remove_depends) {
my %remove = map { $_ => 1 } @$remove_depends;
$task->depends_on([grep { !$remove{$_} } @{$task->depends_on}]);
}
# Same shape once more, one field over: a cross-board link is a tag, so
# append-unique and remove are literally the tag rules (see
# App::karr::CrossBoard for why the link lives there and not in a
# frontmatter field of its own).
App::karr::CrossBoard->add_needs( $task, $add_needs ) if $add_needs;
App::karr::CrossBoard->remove_needs( $task, $remove_needs ) if $remove_needs;
if (defined $claim && length $claim) {
$task->claimed_by($claim);
$task->claimed_at(gmtime->datetime . 'Z');
}
if (defined $self->block && length $self->block) {
$task->block($self->block);
}
if ($self->unblock) {
$task->unblock;
}
});
printf "Updated task %d: %s\n", $task->id, $task->title unless $self->json;
# --status goes through apply_status_change, so an edit that takes a card
# up gets the same dependency warning `karr move` does, for free and by
# construction -- the #55 point again (ticket #123). An edit that changes
# anything else records nothing, so this adds no key.
# --release skips check_claim entirely, so an edit that breaks a claim on
# purpose records nothing and adds no key here either: it is not an override
# that went unnoticed, it is the one command whose whole job is saying so
# (App::karr::Role::ClaimTimeout/expired_claim_report, #177).
return { id => $task->id, title => $task->title,
$self->expired_claim_report( $task->id ),
$self->dependency_report( $task->id ) };
});
$self->sync_after;
$self->print_json_results(@$results);
$self->report_batch_failure($failed, scalar @ids);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
App::karr::Cmd::Edit - Modify an existing task
=head1 VERSION
version 0.601
=head1 SYNOPSIS
karr edit 5 --title "Updated title"
karr edit 5 --add-tag urgent --remove-tag stale
karr edit 5 --add-depends-on 2,3 --remove-depends-on 4
karr edit 5 --add-needs other-repo#7 --block "needs other-repo#7: API change first"
karr edit 5 -a "Waiting for review"
karr edit 5 -a "Handed the API question upstream" --timestamp
karr edit 5 --claim agent-fox --block "waiting on API"
karr edit 5 --class expedite --estimate 3d --due 2026-09-15
karr edit 5 --clear-due
=head1 DESCRIPTION
Updates one or more existing tasks in place. Use it to adjust metadata, append
notes, manage tags, claim or release ownership, and mark tasks as blocked or
unblocked without changing the task id.
At least one field option is required. C<karr edit 5> on its own, or with only
output options such as C<--json>, names nothing to change and is rejected as a
usage error (exit 2) before any task is read -- it used to report C<Updated
task 5>, bump C<updated> and append an activity-log entry for a card nothing
had touched. An option carrying an empty value counts as no option at all here,
matching the write path, which discards such a value rather than storing it.
=head1 COMMON OPERATIONS
=over 4
=item * Metadata updates
C<--title>, C<--status>, C<--priority>, C<--assignee>, C<--class>,
( run in 0.992 second using v1.01-cache-2.11-cpan-85d3896f969 )