#!/usr/bin/env perl # TODO: # # Ideally, this would be able to handle the following gracefully: # # wrt ls 2016 # all entries for 2016 # wrt ls 2016/4 # all entries for April 2016 # wrt ls 2016/4/1 # everything for April 1, 2016 # # ...but I think doing that right requires a much cleaner separation of how # entries are _structured_ from how they're _displayed_, probably by moving # more operations into WRT::EntryStore. # # It makes some sense that wrt-ls would just expose the interface of # EntryStore in a relatively safe way, including the operations that find # things by depth, locate the next/previous entry, etc. All of these could # be useful in scripting and publishing pipelines. =pod =head1 NAME wrt-ls - list =head1 USAGE wrt ls # all entries wrt ls --days # entries for individual days wrt ls --months # entries for individual months wrt ls --years # entries for years wrt ls --props # all properties # Display help: wrt ls --help # Specify a different config file: wrt ls --config ./wrt.json ... =head1 DESCRIPTION Lists entries in the current wrt archive. This interface is experimental and subject to revision in upcoming releases. Detailed documentation can be found in the L man page or at L. =head1 LICENSE wrt is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. =head1 AUTHOR Brennen Bearnes =cut use 5.10.0; use strict; use warnings; use Getopt::Long qw(GetOptionsFromArray); use Pod::Usage; use App::WRT; use Carp; # If invoked directly from the command-line, caller() will return undef. # Execute main() with a callback to print output directly, and a copy of # our real @ARGV: if (not caller()) { my $output = sub { say @_; }; main($output, @ARGV); exit(0); } # main() takes an output callback and an @ARGV to pass in to # GetOptionsFromArray(). This allows relatively simple integration # tests to be written. See also: t/bin-wrt-ls.t sub main { my ($output, @local_argv) = @_; # Handle options, including help generated from the POD above. See: # - http://perldoc.perl.org/Getopt/Long.html#User-defined-subroutines-to-handle-options # - https://metacpan.org/pod/Pod::Usage # - http://michael.thegrebs.com/2014/06/08/Pod-Usage/ my $config_file = 'wrt.json'; my $with_titles = 0; my $list_days = 0; my $list_months = 0; my $list_years = 0; my $list_props = 0; my $list_all = 1; GetOptionsFromArray( \@local_argv, 'config=s' => \$config_file, help => sub { pod2usage(0) }, days => \$list_days, months => \$list_months, years => \$list_years, props => \$list_props, 'with-titles' => \$with_titles, ) or pod2usage(2); # Allow only one of --days, --months, --years, --props. Default to listing # all entries if none of these are specified. my $option_count = 0; foreach ($list_days, $list_months, $list_years, $list_props) { $option_count += $_; } if ($option_count > 1) { croak("Please specify at most one of --days, --months, --years, --props."); } elsif ($option_count == 1) { $list_all = 0; } unless (-e $config_file) { croak("No wrt config file found. Tried: $config_file"); } my $w = App::WRT::new_from_file($config_file); # Define the function that'll return the base list of entries to match # against: my $base_list; if ($list_days) { $base_list = sub { $w->{entries}->all_days(); }; } elsif ($list_months) { $base_list = sub { $w->{entries}->all_months(); }; } elsif ($list_years) { $base_list = sub { $w->{entries}->all_years(); }; } elsif ($list_props) { $base_list = sub { $w->{entries}->all_props(); }; } elsif ($list_all) { $base_list = sub { $w->{entries}->all(); }; } foreach my $entry ($base_list->()) { # When invoked from command line, this will normally be a simple # routine that does `say $entry`. Under testing, it may instead # accumulate output for checking elsewhere. if ($with_titles) { $output->($entry . "\t" . $w->get_title($entry)); } else { $output->($entry); } } } 1;