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) '
},
],
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 )