App-karr

 view release on metacpan or  search on metacpan

lib/App/karr/Role/BoardDiscovery.pm  view on Meta::CPAN

      . "This is not an empty board -- nothing was read here at all.\n"
      . $advice
      . ( defined $args{hint} ? $args{hint} : '' );
}

# How many task refs the repository holds. Through a list, because
# list_task_refs returns through sort and would answer the number of arguments
# sort was handed if it were called in scalar context.
sub _task_refs_held {
    my ($self) = @_;
    my @ids = $self->store->git->list_task_refs;
    return scalar @ids;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

App::karr::Role::BoardDiscovery - Role providing minimal board discovery and config access

=head1 VERSION

version 0.500

=head1 DESCRIPTION

This role provides the minimal interface for discovering the board's Git
repository and BoardStore. It provides:

=over 4

=item * C<dir> — CLI option overriding the directory discovery starts from

=item * C<git_root> — path to the Git repository (walks up from C<dir> or CWD)

=item * C<store> — L<App::karr::BoardStore> instance backed by the Git repo

=item * C<git> — shortcut to C<< $self->store->git >> (lazy)

=item * C<config> — shortcut to C<< $self->store->effective_config >> (lazy)

=back

Commands that need the sync lifecycle should also compose
L<App::karr::Role::SyncLifecycle>.

=head2 require_board

    $self->sync_before;
    $self->require_board;

Refuses to go on when this repository has no initialized board. Every command
that writes to C<refs/karr/*> calls it, because without the check a C<karr
create> typed in the wrong directory silently seeded a partial board in an
unrelated repository -- and that partial board then locked C<karr init> out of
it permanently (#62).

It distinguishes the two ways of not having a board, because they call for
different things from the reader (#133):

=over 4

=item * nothing under C<refs/karr/> — "No karr board found. Run 'karr init' to
create one.", the sentence C<backup>, C<destroy>, C<materialize> and C<repair>
raise off L<App::karr::BoardStore/has_board_refs> for the same state;

=item * refs present, C<refs/karr/config> missing — a half-board: the message
names it as one, says how many task refs are at stake, and says that C<karr
init> completes it without discarding them.

=back

Call it B<after> C<sync_before>, never before: on a fresh clone the board only
exists on the remote until the pull has run, and checking first would report a
board that is merely not fetched yet as missing. The four commands that read or
clean up raw refs (C<backup>, C<destroy>, C<materialize>, C<repair>) ask
L<App::karr::BoardStore/has_board_refs> instead, so they can still deal with a
half-board left behind by an older karr.

The read-only commands do not sync, so they cannot use this method; they ask
L</require_local_board>, which puts C<karr sync> in front of C<karr init> for
exactly the fresh clone this one may assume has already been pulled.

=head2 require_local_board

    $self->require_local_board;   # no sync_before: reads stay offline
    $self->require_local_board( hint => "...one more sentence.\n" );

The read side of L</require_board>, for the commands that render the board
without pulling first (C<board>, C<list>, C<show>, C<log>, C<context>, and
C<config show>/C<config get>). It answers one question those commands never
asked: was anything actually read here? Without it they rendered the code
defaults over an empty task list, so a repository holding no board printed
exactly what a board holding no tasks prints -- and since C<git clone> does not
fetch C<refs/karr/*>, that is the normal state of every fresh clone, where the
user's tickets are all on the remote (#135, and #136 for the config half).

The two states L</require_board> distinguishes need different answers on the
read path:

=over 4

=item * nothing under C<refs/karr/> — refuse. Naming C<refs/karr/> says what
was looked at, and where the repository has a remote the message leads with
C<karr sync>, not C<karr init>: on a fresh clone the board exists and is
merely unfetched, and C<init> is the one command that would answer that by
starting a second, empty one.

=item * refs present, C<refs/karr/config> missing — a half-board: go on, and
say so on STDERR. Refusing would hide tasks that are demonstrably there, which
is the mistake #133 was about; but the board name, statuses and defaults being
rendered are karr's own, not the board's, and nothing else on the page says so.
STDERR keeps C<--json> parsable.

=back



( run in 0.578 second using v1.01-cache-2.11-cpan-788537b7465 )