Initial script infrastructure
[scpubgit/Tak.git] / lib / Tak / Script.pm
1 package Tak::Script;
2
3 use Getopt::Long qw(GetOptionsFromArray :config posix_defaults bundling);
4 use Config::Settings;
5 use IO::Handle;
6 use Moo;
7
8 has options => (is => 'ro', required => 1);
9 has env => (is => 'ro', required => 1);
10
11 has stdin => (is => 'lazy');
12 has stdout => (is => 'lazy');
13 has stderr => (is => 'lazy');
14
15 sub _build_stdin { shift->env->{stdin} }
16 sub _build_stdout { shift->env->{stdout} }
17 sub _build_stderr { shift->env->{stderr} }
18
19 has config => (is => 'lazy');
20
21 sub _build_config {
22   my ($self) = @_;
23   Config::Settings->new->parse_file(
24     $self->options->{config} || '.tak/default.conf'
25   );
26 }
27
28 sub BUILD {
29   shift->setup_logger;
30 }
31
32 sub setup_logger { }
33
34 sub _parse_options {
35   my ($self, $string, \@argv) = @_;
36   my @spec = split ';', $string;
37
38 sub run {
39   my ($self) = @_;
40   my @argv = @{$self->env->{argv}};
41   unless (@argv && $argv[0]) {
42     return $self->local_help;
43   }
44   my $cmd = shift(@argv);
45   if (my $code = $self->can("local_$cmd")) {
46     return $self->_run($cmd, $code, @argv);
47   } elsif ($code = $self->can("each_$cmd")) {
48     return $self->_run_each($cmd, $code, @argv);
49   }
50   $self->stderr->print("No such command: ${cmd}\n");
51   return $self->local_help;
52 }
53
54 sub _load_file {
55   my ($self, $file) = @_;
56   $self->_load_file_in_my_script($file);
57 }
58
59 sub local_help {
60   my ($self) = @_;
61   $self->stderr->print("Help unimplemented\n");
62 }
63
64 sub _run_local {
65   my ($self, $cmd, $code, @argv) = @_;
66   my $opt = do {
67     if (my $proto = prototype($code)) {
68       $self->_parse_options($proto, \@argv);
69     } else {
70       {};
71     }
72   };
73   $self->$code($opt, @argv);
74 }
75
76 1;