App-Easer

 view release on metacpan or  search on metacpan

docs/docs/10-tutorial-base.md  view on Meta::CPAN


The example `tudu` application also contains an *outlier* sub-command
`dump`, which is normally excluded from the children list (we would have
to set it explicitly in `MAIN`'s `children` in case).

```perl
# inside hash at $application->{commands}:
dump => { # this child is normally excluded!
   help => 'dump configuration',
   execute => sub ($m, $c, $a) {
      require Data::Dumper;
      warn Data::Dumper::Dumper({config => $c, args => $a});
      return 0;
   },
},
```

In this case we don't need to hand the execution over to `TuDu`, but can
provide it right off the bat with a `sub` reference. This gives us an
idea of how flexible we can be with the *executables*, ranging from
in-site implementation, to reference to other subs, up to putting stuff
in different packages and, possibly, different module files.

docs/docs/10-tutorial-base.md  view on Meta::CPAN

            },
         ],
         sources        => '+SourcesWithFiles',
         'config-files' => ["$ENV{HOME}/.tudu.conf", '/etc/tudu.conf'],
         commit         => '#ensure_basedir',
         children => [qw< list show cat add edit done wait resume remove >],
      },
      dump => { # this child is normally excluded!
         help => 'dump configuration',
         execute => sub ($m, $c, $a) {
            require Data::Dumper;
            warn Data::Dumper::Dumper({config => $c, args => $a});
            return 0;
         },
      },
      list => {
         help        => 'list tasks',
         description => 'Get full or partial list of tasks',
         supports    => [qw< list ls >],
         options     => [
            {
               help => 'include all tasks (including done) '

eg/tudu  view on Meta::CPAN

            },
         ],
         sources        => '+SourcesWithFiles',
         'config-files' => ["$ENV{HOME}/.tudu.conf", '/etc/tudu.conf'],
         commit         => '#ensure_basedir',
         children => [qw< list show cat add edit done wait resume remove >],
      },
      dump => { # this child is normally excluded!
         help => 'dump configuration',
         execute => sub ($m, $c, $a) {
            require Data::Dumper;
            warn Data::Dumper::Dumper({config => $c, args => $a});
            return 0;
         },
      },
      list => {
         help        => 'list tasks',
         description => 'Get full or partial list of tasks',
         supports    => [qw< list ls >],
         options     => [
            {
               help => 'include all tasks (including done) '

lib/App/Easer/V1.pm  view on Meta::CPAN

   return @retval;
} ## end sub commandline_help ($getopt)

sub commit_configuration ($self, $spec, $args) {
   my $commit = $spec->{commit} // return;
   $self->{factory}->($commit, 'commit')->($self, $spec, $args);
}

sub d (@stuff) {
   no warnings;
   require Data::Dumper;
   local $Data::Dumper::Indent = 1;
   warn Data::Dumper::Dumper(@stuff % 2 ? \@stuff : {@stuff});
} ## end sub d (@stuff)

sub default_getopt_config ($self, $spec) {
   my @r = qw< gnu_getopt >;
   push @r, qw< require_order pass_through >
      if has_children($self, $spec);
   push @r, qw< pass_through > if  $spec->{'allow-residual-options'};
   return \@r;
}

lib/App/Easer/V1.pod  view on Meta::CPAN



=head1 FUNCTIONS

The following functions can be optionally imported.

=head2 d

   d(['whatever', {hello => 'world'}]);

Dump data on standard error using L<Data::Dumper>.

=head2 run

   run($application, \@args);

   # hash data structure
   run({...}, \@ARGV);

   # filename or string, in JSON or Perl
   run('/path/to/app.json', \@ARGV);

lib/App/Easer/V2.pm  view on Meta::CPAN


use parent 'Exporter';
our @EXPORT_OK = qw< appeaser_api d dd run >;

# repeated stuff to ease direct usage and fatpack-like inclusion
sub appeaser_api { __PACKAGE__ =~ s{.*::}{}rmxs }
sub d            { warn dd(@_) }

sub dd (@stuff) {
   no warnings;
   require Data::Dumper;
   local $Data::Dumper::Indent = 1;
   local $Data::Dumper::Sortkeys = 1;
   Data::Dumper::Dumper(
        @stuff == 0 ? []
      : (ref($stuff[0]) || @stuff % 2) ? \@stuff
      :                                  {@stuff}
   );
} ## end sub dd (@stuff)

sub run ($app, @args) {
   my $class = 'App::Easer::V2::Command';
   my $instance =
       ref($app) eq 'HASH'  ? $class->new($app)

lib/App/Easer/V2.pod  view on Meta::CPAN

=item * C<d>

   d($whatever);

Sends C<$whatever> through C<dd> and then to C<warn>.

=item * C<dd>

   my $dumped = dd($whatever);

Sends C<$whatever> through L<Data::Dumper> and returns it.

=item * C<run>

   my $exit_code = run($cmd_hashref, $0, @ARGV);

Run a command with the provided parameters (first the name of the
command, using C<$0>, then the command-line arguments).

=back

t/V2/LocalTester.pm  view on Meta::CPAN

package LocalTester;
use v5.24;
use experimental 'signatures';
use Capture::Tiny 'capture';
use App::Easer V2 => 'run';
use Test::More;
use Exporter 'import';
use Data::Dumper;

our @EXPORT = qw< test_run executor >;

sub executor ($cb = undef) {
   return sub ($self) {
      LocalTester::command_execute($self);
      $cb->($self) if $cb;
      return $self->name;
   };
}

t/V2/LocalTester.pm  view on Meta::CPAN

   return $self;
}

sub name_is ($self, $expected, $test_name = undef) {
   $test_name //= "command name is '$expected'";
   is $self->{name}, $expected, $test_name;
   return $self;
}

sub conf_is ($self, $expected, $name = 'configuration') {
   local $Data::Dumper::Indent = 1;
   local $Data::Dumper::Sortkeys = 1;
   is_deeply $self->{conf}, $expected, $name
      or diag Dumper({ got => $self->{conf}, expected => $expected });
   return $self;
}

sub conf_contains ($self, $expected, $name = 'partial configuration') {
   my $got = { map { $_ => $self->{conf}{$_} } keys $expected->%* };
   is_deeply $got, $expected, $name;
   return $self;
}



( run in 0.537 second using v1.01-cache-2.11-cpan-4d50c553e7e )