NAME
App::karr::Role::DependencyCheck - Warn when a card is taken up while its dependencies are unfinished
VERSION
version 0.500
DESCRIPTION
depends_on was stored, round-tripped and written into the frontmatter by App::karr::Task long before anything read it. That is worse than a missing feature: a card recording depends_on: [5] looked as though karr would hold it back until 5 was finished -- the field was accepted, kept and materialized -- while move, edit --status and pick handed it out with no word said (ticket #123).
This role is what reads it. Taking a card up with unsatisfied dependencies proceeds and exits 0, but says so. "Taking up" is a status change into a non-terminal status, and on pick it is also the claim itself -- an agent that runs karr pick --claim X holds the card and starts on it whether or not a --move came with it.
Consumed by App::karr::Role::TaskMutation, so every command that changes a status through apply_status_change is covered by the one call there, and directly by App::karr::Cmd::Pick, which has its own compare-and-swap loop and does not go through that path.
Setting the field is the other half, and a separate role: App::karr::Role::DependencyArgs is what create and edit parse and validate their dependency options with. The two were one role until ticket #137; they are split because their contracts differ -- this half needs the command's output options to choose a channel for the warning, that half needs none of them and is composed by a command (create) that has no --json.
What counts as satisfied
A dependency in one of the board's own terminal statuses ("is_terminal_status" in App::karr::Config), never the literal done: a board whose final column is shipped would otherwise have every finished dependency reported as outstanding. Same rule as kanban-md's allDepsSatisfied (internal/board/filter.go:148).
Which channel it comes out of
The rules "run_batch" in App::karr::Role::TaskMutation already set for its per-id errors, rather than a second convention: the human copy goes to STDERR so STDOUT stays parseable, --json carries the identical sentence in the result object instead -- a JSON consumer never reads STDERR, so a warning left there is a warning nobody sees -- and --quiet silences the STDERR copy. The JSON field is data, not chatter, so --quiet does not remove it; the key is simply absent when there is nothing to report.
SEE ALSO
karr, App::karr, App::karr::Role::DependencyArgs, App::karr::Role::TaskMutation, App::karr::Cmd::Pick, App::karr::Cmd::Move, App::karr::Cmd::Show, App::karr::Config
check_dependencies
$self->check_dependencies( $task, $new_status );
Records, for $task->id, one warning per dependency that is not finished and one per dependency naming an id the board does not have. Returns the warnings and stashes them for "dependency_report" to emit; it prints nothing and changes nothing itself, which is what makes it safe to call from inside a compare-and-swap callback that may run more than once.
A $new_status that is terminal for this board, or a task with no depends_on, records nothing. Call it with the status the task is moving to, not the one it is moving from -- or, where nothing is moving and the card is merely being taken up (karr pick --claim with no --move), with the status it stays in.
dependency_report
return { id => $task->id, ..., $self->dependency_report( $task->id ) };
Emits whatever "check_dependencies" recorded for $id and returns it as the dependency_warnings => \@warnings pair for the command's --json payload, or the empty list when there is nothing to report -- so the key is absent rather than an empty array a consumer would have to test the length of.
Emitting and reporting are one call on purpose: they are the same warning on two channels, and splitting them is how the two drift apart. STDERR is skipped under --json (where the pair carries it) and under --quiet.
Call it after the write has landed, never from inside the guarded callback: a warning about a move that then lost its compare-and-swap is a warning about something that did not happen.
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/karr/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <getty@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.