--- /dev/null
+package Tak::Script;
+
+use Getopt::Long qw(GetOptionsFromArray :config posix_defaults bundling);
+use Config::Settings;
+use IO::Handle;
+use Moo;
+
+has options => (is => 'ro', required => 1);
+has env => (is => 'ro', required => 1);
+
+has stdin => (is => 'lazy');
+has stdout => (is => 'lazy');
+has stderr => (is => 'lazy');
+
+sub _build_stdin { shift->env->{stdin} }
+sub _build_stdout { shift->env->{stdout} }
+sub _build_stderr { shift->env->{stderr} }
+
+has config => (is => 'lazy');
+
+sub _build_config {
+ my ($self) = @_;
+ Config::Settings->new->parse_file(
+ $self->options->{config} || '.tak/default.conf'
+ );
+}
+
+sub BUILD {
+ shift->setup_logger;
+}
+
+sub setup_logger { }
+
+sub _parse_options {
+ my ($self, $string, \@argv) = @_;
+ my @spec = split ';', $string;
+
+sub run {
+ my ($self) = @_;
+ my @argv = @{$self->env->{argv}};
+ unless (@argv && $argv[0]) {
+ return $self->local_help;
+ }
+ my $cmd = shift(@argv);
+ if (my $code = $self->can("local_$cmd")) {
+ return $self->_run($cmd, $code, @argv);
+ } elsif ($code = $self->can("each_$cmd")) {
+ return $self->_run_each($cmd, $code, @argv);
+ }
+ $self->stderr->print("No such command: ${cmd}\n");
+ return $self->local_help;
+}
+
+sub _load_file {
+ my ($self, $file) = @_;
+ $self->_load_file_in_my_script($file);
+}
+
+sub local_help {
+ my ($self) = @_;
+ $self->stderr->print("Help unimplemented\n");
+}
+
+sub _run_local {
+ my ($self, $cmd, $code, @argv) = @_;
+ my $opt = do {
+ if (my $proto = prototype($code)) {
+ $self->_parse_options($proto, \@argv);
+ } else {
+ {};
+ }
+ };
+ $self->$code($opt, @argv);
+}
+
+1;