App-JobLog
view release on metacpan or search on metacpan
lib/App/JobLog/Command/edit.pm view on Meta::CPAN
package App::JobLog::Command::edit;
$App::JobLog::Command::edit::VERSION = '1.042';
# ABSTRACT: edit the log
use App::JobLog -command;
use Modern::Perl;
use Class::Autouse qw{
App::JobLog::Log
App::JobLog::Log::Line
Digest::MD5
FileHandle
};
use autouse 'File::Temp' => qw(tempfile);
use autouse 'File::Copy' => qw(copy);
use autouse 'App::JobLog::Config' => qw(editor log);
use autouse 'Getopt::Long::Descriptive' => qw(prog_name);
use autouse 'App::JobLog::TimeGrammar' => qw(parse);
use autouse 'App::JobLog::Time' => qw(now);
sub execute {
my ( $self, $opt, $args ) = @_;
if ( $opt->close || $opt->validate ) {
eval {
my $log = App::JobLog::Log->new;
if ( $opt->close ) {
my $time = join ' ', @$args;
my ($s) = parse($time);
$self->usage_error(
'you may only insert closing times prior to present')
unless $s < now;
my ( $e, $i ) = $log->find_previous($s);
$self->usage_error('log does not contain appropriate event')
unless $e;
$self->usage_error('no open event at this time')
unless $e->is_open;
$log->insert( $i + 1,
App::JobLog::Log::Line->new( time => $s, done => 1 ) );
}
if ( $opt->validate ) {
my $errors = $log->validate;
_error_report($errors);
}
};
$self->usage_error($@) if $@;
}
elsif ( my $editor = editor ) {
if ( my $log = log ) {
my ( $fh, $fn ) = tempfile;
binmode $fh;
copy( $log, $fh );
$fh->close;
$fh = FileHandle->new($log);
my $md5 = Digest::MD5->new;
my $md51 = $md5->addfile($fh)->hexdigest;
system "$editor $log";
$fh = FileHandle->new($log);
my $md52 = $md5->reset->addfile($fh)->hexdigest;
if ( $md51 ne $md52 ) {
$fh = FileHandle->new( "$log.bak", 'w' );
copy( $fn, $fh );
$fh->close;
say "saved backup log in $log.bak";
my $errors = App::JobLog::Log->new->validate;
_error_report($errors);
}
else {
unlink $fn;
}
}
else {
say 'nothing in log to edit';
}
}
else {
$self->usage_error('no editor specified') unless $opt->close;
}
}
sub usage_desc {
'%c ' . __PACKAGE__->name . ' [--validate] [-c <date and time>]';
}
sub abstract { 'open a text editor to edit the log' }
sub full_description {
<<END;
Close an open task or open a text editor to edit the log.
Closing an open task is the only edit you'll commonly have to make (it's
easy to forget to close the last task of the day). Fortunately, it is the easiest
edit to perform. You simply type
@{[prog_name]} @{[__PACKAGE__->name]} --close yesterday at 8:00 pm
for example and @{[prog_name]} will insert the appropriate line if it can do so.
If it can't because there is no open task at the time specified, it will emit a warning
instead.
The date and time parsing is handled by the same code used by the @{[App::JobLog::Command::summary->name]} command,
so what works for one works for the other. One generally does not specify hours and such
for summaries, but @{[prog_name]} will understand most common natural language time expressions.
If you need to do more extensive editing of the log this command will open a text editor
for you and confirm the validity of the log after you save, commenting out
ill-formed lines and printing a warning. This command requires the you
to have set editor configuration parameter to specify a text.
The text editor must be invokable like so,
( run in 0.689 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )