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.