App-TimeTracker
view release on metacpan or search on metacpan
lib/App/TimeTracker/Proto.pm view on Meta::CPAN
package App::TimeTracker::Proto;
# ABSTRACT: App::TimeTracker Proto Class
our $VERSION = '3.010'; # VERSION
use strict;
use warnings;
use 5.010;
use App::TimeTracker::Utils qw(error_message);
use Moose;
use MooseX::Types::Path::Class;
use File::HomeDir ();
use Path::Class;
use Hash::Merge qw(merge);
use JSON::XS;
use Carp;
use Try::Tiny;
use App::TimeTracker::Data::Task;
use App::TimeTracker::Constants qw(MISSING_PROJECT_HELP_MSG);
has 'home' => (
is => 'ro',
isa => 'Path::Class::Dir',
lazy_build => 1,
);
sub _build_home {
my ( $self, $home ) = @_;
$home ||=
Path::Class::Dir->new( $ENV{TRACKER_HOME} || (File::HomeDir->my_home, '.TimeTracker' ));
unless (-d $home) {
$home->mkpath;
$self->_write_config_file_locations( {} );
my $fh = $self->global_config_file->openw;
print $fh $self->json_decoder->encode( {} );
close $fh;
}
return $home;
}
has 'global_config_file' => (
is => 'ro',
isa => 'Path::Class::File',
lazy_build => 1,
);
sub _build_global_config_file {
my $self = shift;
return $self->home->file('tracker.json');
}
has 'config_file_locations' => (
is => 'ro',
isa => 'HashRef',
lazy_build => 1,
);
sub _build_config_file_locations {
my $self = shift;
my $file = $self->home->file('projects.json');
if ( -e $file && -s $file ) {
my $decoded_json;
try {
$decoded_json = decode_json( $file->slurp );
}
catch {
error_message( "Could not json decode '%s'.\nError: '%s'", $file, $_ );
exit 1;
};
return $decoded_json;
}
else {
return {};
}
}
has 'project' => ( is => 'rw', isa => 'Str', predicate => 'has_project' );
has 'json_decoder' => ( is => 'ro', isa => 'JSON::XS', lazy_build => 1 );
sub _build_json_decoder {
my $self = shift;
return JSON::XS->new->utf8->pretty->canonical->relaxed;
}
sub run {
my $self = shift;
try {
my $config = $self->load_config;
my $class = $self->setup_class($config);
$class->name->new_with_options( {
home => $self->home,
config => $config,
( $self->has_project
? ( _current_project => $self->project )
: ()
),
} )->run;
}
catch {
my $e = $_;
if ( blessed $e && $e->can('message') ) {
warn $e->message, "\n";
}
else {
warn "$e\n";
}
}
}
sub setup_class {
my ( $self, $config, $command ) = @_;
# unique plugins
$config->{plugins} ||= [];
my %plugins_unique = map { $_ => 1 } @{ $config->{plugins} };
$config->{plugins} = [ keys %plugins_unique ];
my $class = Moose::Meta::Class->create_anon_class(
superclasses => ['App::TimeTracker'],
roles => [
map { 'App::TimeTracker::Command::' . $_ } 'Core',
@{ $config->{plugins} }
],
);
my %commands;
foreach my $method ( $class->get_all_method_names ) {
next unless $method =~ /^cmd_/;
$method =~ s/^cmd_//;
$commands{$method} = 1;
}
my $load_attribs_for_command;
foreach my $cmd ( $command ? $command : @ARGV) {
if ( defined $commands{$cmd} ) {
$load_attribs_for_command = '_load_attribs_' . $cmd;
if ($cmd eq 'start' && !$self->has_project) {
error_message( MISSING_PROJECT_HELP_MSG );
exit;
}
( run in 0.600 second using v1.01-cache-2.11-cpan-39bf76dae61 )