| File: | lib/App/TimeTracker/Proto.pm |
| Coverage: | 81.2% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package App::TimeTracker::Proto; | ||||||
| 2 | 3 3 3 | 452626 9 59 | use strict; | ||||
| 3 | 3 3 3 | 12 6 78 | use warnings; | ||||
| 4 | 3 3 3 3 3 3 | 115 128 40 15 8 33 | use 5.010; | ||||
| 5 | |||||||
| 6 | # ABSTRACT: TimeTracker Proto Class | ||||||
| 7 | |||||||
| 8 | 3 3 3 | 595 668472 29 | use Moose; | ||||
| 9 | 3 3 3 | 16398 280988 33 | use MooseX::Types::Path::Class; | ||||
| 10 | 3 3 3 | 2155 2992 86 | use File::HomeDir (); | ||||
| 11 | 3 3 3 | 14 9 177 | use Path::Class; | ||||
| 12 | 3 3 3 | 902 5179 49 | use Hash::Merge qw(); | ||||
| 13 | 3 3 3 | 751 12350 30 | use JSON; | ||||
| 14 | |||||||
| 15 | has 'home' => ( | ||||||
| 16 | is => 'ro', | ||||||
| 17 | isa => 'Path::Class::Dir', | ||||||
| 18 | lazy_build => 1, | ||||||
| 19 | ); | ||||||
| 20 | sub _build_home { | ||||||
| 21 | 2 | 36 | my $self = shift; | ||||
| 22 | 2 | 21 | my $home = | ||||
| 23 | Path::Class::Dir->new( File::HomeDir->my_home, '.TimeTracker' ); | ||||||
| 24 | 2 | 699 | $home->mkpath unless -d $home; | ||||
| 25 | 2 | 78 | return $home; | ||||
| 26 | } | ||||||
| 27 | |||||||
| 28 | has 'configfile' => ( | ||||||
| 29 | is => 'ro', | ||||||
| 30 | isa => 'Path::Class::File', | ||||||
| 31 | lazy_build => 1, | ||||||
| 32 | ); | ||||||
| 33 | sub _build_configfile { | ||||||
| 34 | 2 | 52 | my $self = shift; | ||||
| 35 | 2 | 16 | return $self->home->file('tracker.json'); | ||||
| 36 | } | ||||||
| 37 | |||||||
| 38 | has 'project' => (is=>'rw',isa=>'Str'); | ||||||
| 39 | |||||||
| 40 | sub run { | ||||||
| 41 | 1 | 0 | 200512 | my $self = shift; | |||
| 42 | |||||||
| 43 | 1 | 4 | my $config = $self->load_config; | ||||
| 44 | |||||||
| 45 | 6 | 25 | my $class = Moose::Meta::Class->create_anon_class( | ||||
| 46 | superclasses => ['App::TimeTracker'], | ||||||
| 47 | roles => [ | ||||||
| 48 | 1 1 | 4 3 | map { 'App::TimeTracker::Command::' . $_ } 'Core', @{ $config->{plugins} } | ||||
| 49 | ], | ||||||
| 50 | ); | ||||||
| 51 | |||||||
| 52 | 1 | 25740 | my %commands; | ||||
| 53 | 1 | 20 | foreach my $method ($class->get_all_method_names) { | ||||
| 54 | 69 | 3282 | next unless $method =~ /^cmd_/; | ||||
| 55 | 11 | 28 | $method =~ s/^cmd_//; | ||||
| 56 | 11 | 29 | $commands{$method}=1; | ||||
| 57 | } | ||||||
| 58 | 1 | 207 | my $load_attribs_for_command; | ||||
| 59 | 1 | 4 | foreach (@ARGV) { | ||||
| 60 | 0 | 0 | if ($commands{$_}) { | ||||
| 61 | 0 | 0 | $load_attribs_for_command='_load_attribs_'.$_; | ||||
| 62 | 0 | 0 | last; | ||||
| 63 | } | ||||||
| 64 | } | ||||||
| 65 | 1 | 5 | if ($load_attribs_for_command && $class->has_method($load_attribs_for_command)) { | ||||
| 66 | 0 | 0 | $class->name->$load_attribs_for_command($class); | ||||
| 67 | } | ||||||
| 68 | |||||||
| 69 | $class->name->new_with_options( { | ||||||
| 70 | 1 | 11 | home => $self->home, | ||||
| 71 | config => $config, | ||||||
| 72 | _currentproject => $self->project, | ||||||
| 73 | } )->run; | ||||||
| 74 | } | ||||||
| 75 | |||||||
| 76 | sub load_config { | ||||||
| 77 | 3 | 0 | 189499 | my $self = shift; | |||
| 78 | |||||||
| 79 | 3 | 26 | my $all_config = decode_json( $self->configfile->slurp ); | ||||
| 80 | 3 | 1659 | my %projects; | ||||
| 81 | 3 3 | 7 13 | foreach my $job (keys %{$all_config->{jobs}}) { | ||||
| 82 | 6 6 | 14 21 | foreach my $project (keys %{$all_config->{jobs}{$job}{projects}}) { | ||||
| 83 | 6 | 19 | $projects{$project} = $job; | ||||
| 84 | } | ||||||
| 85 | } | ||||||
| 86 | |||||||
| 87 | 3 | 8 | my $project; | ||||
| 88 | 3 | 9 | my @argv = @ARGV; | ||||
| 89 | 3 | 13 | while (@argv) { # check if project is specified via commandline | ||||
| 90 | 1 | 3 | my $arg = shift(@argv); | ||||
| 91 | 1 | 3 | if ($arg eq '--project') { | ||||
| 92 | 1 | 3 | my $p = shift(@argv); | ||||
| 93 | 1 | 3 | $project = $p if $projects{$p}; | ||||
| 94 | 1 | 5 | unless ($project) { | ||||
| 95 | 0 | 0 | say "Cannot find project $p in config."; | ||||
| 96 | } | ||||||
| 97 | } | ||||||
| 98 | } | ||||||
| 99 | 3 | 10 | unless ($project) { # try to figure out project via current dir | ||||
| 100 | 2 | 22 | my $cwd = Path::Class::Dir->new->absolute; | ||||
| 101 | 2 | 413 | my $regex = join('|',keys %projects); | ||||
| 102 | 2 | 69 | if ($cwd =~m{/($regex)}) { | ||||
| 103 | 2 | 70 | $project = $1 if $projects{$1}; | ||||
| 104 | } | ||||||
| 105 | } | ||||||
| 106 | |||||||
| 107 | 3 | 8 | my $config; | ||||
| 108 | 3 | 12 | if ($project) { | ||||
| 109 | 3 | 25 | $self->project($project); | ||||
| 110 | 3 | 64 | my $job = $projects{$project}; | ||||
| 111 | # merge project <- job <- global config | ||||||
| 112 | 3 | 25 | $config = Hash::Merge::merge($all_config->{'jobs'}{$job}{'projects'}{$project},$all_config->{'jobs'}{$job}{'job'}); | ||||
| 113 | 3 | 1692 | $config = Hash::Merge::merge($config,$all_config->{'global'}); | ||||
| 114 | } | ||||||
| 115 | else { | ||||||
| 116 | 0 | 0 | say "Cannot figure out project. Please check config and/or --project"; | ||||
| 117 | 0 | 0 | $self->project('_no_project'); | ||||
| 118 | 0 | 0 | $config = $all_config->{'global'}; | ||||
| 119 | } | ||||||
| 120 | |||||||
| 121 | 3 | 580 | $config->{project2job}=\%projects; | ||||
| 122 | 3 | 29 | return $config; | ||||
| 123 | } | ||||||
| 124 | |||||||
| 125 | 1; | ||||||