The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Venus::Task - Task Class

ABSTRACT

Task Class for Perl 5

SYNOPSIS

package Example;

use base 'Venus::Task';

package main;

my $task = Example->new(['--help']);

# bless({...}, 'Example')

DESCRIPTION

This package provides a superclass, methods, and a simple framework for creating CLIs (command-line interfaces).

ATTRIBUTES

This package has the following attributes:

data

data(arrayref $data) (arrayref)

The data attribute is read-write, accepts (ArrayRef) values, and is optional.

Since 2.91

data example 1
# given: synopsis

package main;

my $set_data = $task->data([1..4]);

# [1..4]
data example 2
# given: synopsis

# given: example-1 data

package main;

my $get_data = $task->data;

# [1..4]

tryer

tryer(Venus::Try $data) (Venus::Try)

The tryer attribute is read-write, accepts (Venus::Try) values, and is optional.

Since 4.11

tryer example 1
# given: synopsis

package main;

my $set_tryer = $task->tryer($task->try('execute'));

# bless(..., "Venus::Try")
tryer example 2
# given: synopsis

# given: example-1 tryer

package main;

my $get_tryer = $task->tryer;

# bless(..., "Venus::Try")

INHERITS

This package inherits behaviors from:

Venus::Kind::Utility

INTEGRATES

This package integrates behaviors from:

Venus::Role::Buildable

METHODS

This package provides the following methods:

args

args() (hashref)

The args method can be overridden and returns a hashref suitable to be passed to the "set" in Venus::Cli method as type "arg". An "arg" is a CLI positional argument.

Since 2.91

args example 1
# given: synopsis

package main;

my $args = $task->args;

# {}
args example 2
package Example;

use base 'Venus::Task';

sub args {

  return {
    name => {
      help => 'Name of user',
    },
  }
}

package main;

my $task = Example->new;

my $args = $task->args;

# {
#   name => {
#     help => 'Name of user',
#   },
# }

auto

auto(coderef $code) (Venus::Task)

The auto class method is similar to the "run" method but accepts a callback which will be invoked with the instansiated class before calling the "execute" method. This method is meant to be used directly in package scope outside of any routine, and will only auto-execute under the conditions that the caller is the "main" package space and the VENUS_TASK_AUTO environment variable is truthy.

Since 4.11

auto example 1
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new(['--help']);

my $auto = $task->auto(sub{});

# bless({...}, 'Venus::Task')
auto example 2
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

auto Example sub {
  my ($self) = @_;
  $self->tryer->no_default;
};

# bless({...}, 'Venus::Task')

cmds

cmds() (hashref)

The cmds method can be overridden and returns a hashref suitable to be passed to the "set" in Venus::Cli method as type "cmd". A "cmd" is a CLI command which maps to an positional argument declare by "args".

Since 2.91

cmds example 1
# given: synopsis

package main;

my $cmds = $task->cmds;

# {}
cmds example 2
package Example;

use base 'Venus::Task';

sub args {

  return {
    op => {
      help => 'Name of operation',
    },
  }
}

sub cmds {

  return {
    init => {
      help => 'Initialize the system',
      arg => 'op',
    },
  }
}

package main;

my $task = Example->new;

my $cmds = $task->cmds;

# {
#   init => {
#     help => 'Initialize the system',
#     arg => 'op',
#   },
# }

description

description() (Venus::Task)

The description method doesn't exist on the Venus::Task superclass but if defined returns a string that will be used as the CLI "description" (before the arguments, options, and commands text).

Since 2.91

description example 1
package Example;

use base 'Venus::Task';

sub description {

  "This text used in the description area of the usage text"
}

package main;

my $task = Example->new;

my $description = $task->description;

# "..."

execute

execute() (Venus::Task)

The execute method can be overridden and returns the invocant. This method prepares the Venus::Cli via "prepare", and runs the "startup", "handler", and "shutdown" sequences, passing "parsed" in Venus::Cli to each method. This method is not typically invoked directly, but instead by the "tryer" attribute via the "run" or "auto" class methods.

Since 2.91

execute example 1
# given: synopsis

package main;

my $execute = $task->execute;

# bless({...}, 'Venus::Task')
execute example 2
package Example;

use base 'Venus::Task';

sub args {

  return {
    name => {
      help => 'Name of user',
    },
  }
}

sub opts {

  return {
    sudo => {
      help => 'Elevate user privileges',
      alias => ['s'],
    },
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

sub startup {
  my ($self) = @_;

  $self->{startup} = time;

  return $self;
}

sub handler {
  my ($self, $data) = @_;

  $self->{handler} = time;
  $self->{parsed} = $data;

  return $self;
}

sub shutdown {
  my ($self) = @_;

  $self->{shutdown} = time;

  return $self;
}

package main;

my $task = Example->new(['admin', '-s']);

my $execute = $task->execute;

# bless({...}, 'Venus::Task')
execute example 3
package Example;

use base 'Venus::Task';

sub args {

  return {
    name => {
      help => 'Name of user',
    },
  }
}

sub opts {

  return {
    sudo => {
      help => 'Elevate user privileges',
      alias => ['s'],
    },
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

sub handler {
  my ($self, $data) = @_;

  $self->{handler} = time;
  $self->{parsed} = $data;

  return $self;
}

package main;

my $task = Example->new(['-s']);

my $execute = $task->execute;

# bless({...}, 'Venus::Task')

exit

exit(number $code, string | coderef $code, any @args) (any)

The exit method exits the program using the exit code provided. The exit code defaults to 0. Optionally, you can dispatch before exiting by providing a method name or coderef, and arguments. If an exit code of undef is provided, the exit code will be determined by the result of the dispatching.

Since 2.91

exit example 1
# given: synopsis

package main;

my $exit = $task->exit;

# ()
exit example 2
# given: synopsis

package main;

my $exit = $task->exit(0);

# ()
exit example 3
# given: synopsis

package main;

my $exit = $task->exit(1);

# ()
exit example 4
# given: synopsis

package main;

my $exit = $task->exit(1, 'log_error', 'oh no');

# ()

fail

fail(string | coderef $code, any @args) (any)

The fail method exits the program with the exit code 1. Optionally, you can dispatch before exiting by providing a method name or coderef, and arguments.

Since 2.91

fail example 1
# given: synopsis

package main;

my $fail = $task->fail;

# ()
fail example 2
# given: synopsis

package main;

my $fail = $task->fail('log_error', 'oh no');

# ()
footer() (Venus::Task)

The footer method doesn't exist on the Venus::Task superclass but if defined returns a string that will be used as the CLI "footer" (after the arguments, options, and commands text).

Since 2.91

package Example;

use base 'Venus::Task';

sub footer {

  "This text used in the footer area of the usage text"
}

package main;

my $task = Example->new;

my $footer = $task->footer;

# "..."

handler

handler(hashref $data) (Venus::Task)

The handler method can and should be overridden and returns the invocant. This method is where the central task operations are meant to happen. By default, if not overriden this method calls "usage" if a "help" flag is detected.

Since 2.91

handler example 1
# given: synopsis

package main;

my $handler = $task->handler({});

# bless({...}, 'Venus::Task')
handler example 2
# given: synopsis

package main;

my $handler = $task->handler({help => 1});

# bless({...}, 'Venus::Task')
handler example 3
package Example;

use base 'Venus::Task';

sub handler {
  my ($self, $data) = @_;

  $self->{handler} = time;
  $self->{parsed} = $data;

  return $self;
}

package main;

my $task = Example->new;

my $handler = $task->handler({});

# bless({...}, 'Venus::Task')
header() (Venus::Task)

The header method doesn't exist on the Venus::Task superclass but if defined returns a string that will be used as the CLI "header" (after the title, before the arguments, options, and commands text).

Since 2.91

header example 1
package Example;

use base 'Venus::Task';

sub header {

  "This text used in the header area of the usage text"
}

package main;

my $task = Example->new;

my $header = $task->header;

# "..."

help

help() (string)

The help method can be overridden and returns a string representing "help" text for the CLI. By default this method returns the result of "help" in Venus::Cli, based on the "cli" object.

Since 2.91

help example 1
# given: synopsis

package main;

my $help = $task->help;

# "Usage: application"
help example 2
package Example;

use base 'Venus::Task';

sub name {

  return 'eg';
}

package main;

my $task = Example->new;

$task->prepare;

my $help = $task->help;

# "Usage: application"

log_debug

log_debug(any @log_debug) (Venus::Log)

The log_debug method dispatches to the "debug" in Venus::Log method and returns the result.

Since 2.91

log_debug example 1
# given: synopsis

package main;

my $log_debug = $task->log_debug('something' ,'happened');

# bless({...}, 'Venus::Log')

log_error

log_error(any @log_error) (Venus::Log)

The log_error method dispatches to the "error" in Venus::Log method and returns the result.

Since 2.91

log_error example 1
# given: synopsis

package main;

my $log_error = $task->log_error('something' ,'happened');

# bless({...}, 'Venus::Log')

log_fatal

log_fatal(any @log_fatal) (Venus::Log)

The log_fatal method dispatches to the "fatal" in Venus::Log method and returns the result.

Since 2.91

log_fatal example 1
# given: synopsis

package main;

my $log_fatal = $task->log_fatal('something' ,'happened');

# bless({...}, 'Venus::Log')

log_info

log_info(any @log_info) (Venus::Log)

The log_info method dispatches to the "info" in Venus::Log method and returns the result.

Since 2.91

log_info example 1
# given: synopsis

package main;

my $log_info = $task->log_info('something' ,'happened');

# bless({...}, 'Venus::Log')

log_level

log_level() (string)

The log_level method can be overridden and returns a valid "level" in Venus::Log value. This method defaults to returning info.

Since 2.91

log_level example 1
# given: synopsis

package main;

my $log_level = $task->log_level;

# "info"

log_trace

log_trace(any @log_trace) (Venus::Log)

The log_trace method dispatches to the "trace" in Venus::Log method and returns the result.

Since 2.91

log_trace example 1
# given: synopsis

package main;

my $log_trace = $task->log_trace('something' ,'happened');

# bless({...}, 'Venus::Log')

log_warn

log_warn(any @log_warn) (Venus::Log)

The log_warn method dispatches to the "warn" in Venus::Log method and returns the result.

Since 2.91

log_warn example 1
# given: synopsis

package main;

my $log_warn = $task->log_warn('something' ,'happened');

# bless({...}, 'Venus::Log')

name

name() (Venus::Task)

The name method can be overridden and returns the name of the task (and application). This method defaults to $0 if not overridden.

Since 2.91

name example 1
# given: synopsis

package main;

my $name = $task->name;

# "/path/to/application"
name example 2
package Example;

use base 'Venus::Task';

sub name {

  return 'eg';
}

package main;

my $task = Example->new;

my $name = $task->name;

# "eg"

okay

okay(string | coderef $code, any @args) (any)

The okay method exits the program with the exit code 0. Optionally, you can dispatch before exiting by providing a method name or coderef, and arguments.

Since 2.91

okay example 1
# given: synopsis

package main;

my $okay = $task->okay;

# ()
okay example 2
# given: synopsis

package main;

my $okay = $task->okay('log_info', 'yatta');

# ()

opts

opts() (hashref)

The opts method can be overridden and returns a hashref suitable to be passed to the "set" in Venus::Cli method as type "opt". An "opt" is a CLI option (or flag).

Since 2.91

opts example 1
# given: synopsis

package main;

my $opts = $task->opts;

# {}
opts example 2
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new;

my $opts = $task->opts;

# {
#   help => {
#     help => 'Display help',
#     alias => ['h'],
#   },
# }

output

output(string $level, string @messages) (Venus::Task)

The output method is configured as the "handler" in Venus::Log by "prepare", can be overridden and returns the invocant.

Since 2.91

output example 1
# given: synopsis

package main;

$task->prepare;

$task = $task->output('info', 'something happened');

# bless({...}, 'Example')

pass

pass(string | coderef $code, any @args) (any)

The pass method exits the program with the exit code 0. Optionally, you can dispatch before exiting by providing a method name or coderef, and arguments.

Since 3.10

pass example 1
# given: synopsis

package main;

my $pass = $task->pass;

# ()
pass example 2
# given: synopsis

package main;

my $pass = $task->pass('log_info', 'yatta');

# ()

prepare

prepare() (Venus::Task)

The prepare method can be overridden, but typically shouldn't, is responsible for configuring the "cli" and "log" objects, parsing the arguments, and after returns the invocant.

Since 2.91

prepare example 1
# given: synopsis

package main;

my $prepare = $task->prepare;

# bless({...}, 'Venus::Task')
prepare example 2
package Example;

use base 'Venus::Task';

sub args {

  return {
    name => {
      help => 'Name of user',
    },
  }
}

sub opts {

  return {
    sudo => {
      help => 'Elevate user privileges',
      alias => ['s'],
    },
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new;

my $prepare = $task->prepare;

# bless({...}, 'Venus::Task')
prepare example 3
package Example;

use base 'Venus::Task';

sub args {

  return {
    name => {
      help => 'Name of user',
    },
  }
}

sub cmds {

  return {
    admin => {
      help => 'Run as an admin',
      arg => 'name',
    },
    user => {
      help => 'Run as a user',
      arg => 'name',
    },
  }
}

sub opts {

  return {
    sudo => {
      help => 'Elevate user privileges',
      alias => ['s'],
    },
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new(['admin', '-s']);

my $prepare = $task->prepare;

# bless({...}, 'Venus::Task')

run

run(any @args) (Venus::Task)

The run class method will automatically execute the task class by instansiating the class and calling the "execute" method and returns the invocant. This method is meant to be used directly in package scope outside of any routine, and will only auto-execute under the conditions that the caller is the "main" package space and the VENUS_TASK_AUTO environment variable is truthy.

Since 2.91

run example 1
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new(['--help']);

my $run = $task->run;

# bless({...}, 'Venus::Task')
run example 2
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

run Example;

# 'Example'

shutdown

shutdown(hashref $data) (Venus::Task)

The shutdown method can be overridden and returns the invocant. This method is called by "execute" automatically after "handler" and is passed the result of "parsed" in Venus::Cli.

Since 2.91

shutdown example 1
# given: synopsis

package main;

my $shutdown = $task->shutdown({});

# bless({...}, 'Venus::Task')

startup

startup(hashref $data) (Venus::Task)

The startup method can be overridden and returns the invocant. This method is called by "execute" automatically after "prepare" and before "handler", and is passed the result of "parsed" in Venus::Cli.

Since 2.91

startup example 1
# given: synopsis

package main;

my $startup = $task->startup({});

# bless({...}, 'Venus::Task')

system

system(string @args) (Venus::Task)

The system method attempts to make a "system" in perlfunc call and returns the invocant. If the system call is unsuccessful an error is thrown.

Since 2.91

system example 1
# given: synopsis

package main;

my $system = $task->system($^X, '-V');

# bless({...},  'Example')
system example 2
# given: synopsis

package main;

my $system = $task->system('/path/to/nowhere');

# Exception! (isa Example::Error) (see error_on_system_call)

test

test(string $type, string $name) (any)

The test method validates the values for the arg or opt specified and returns the value(s) associated. This method dispatches to "test" in Venus::Cli.

Since 3.10

test example 1
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new(['--help']);

my ($help) = $task->prepare->test('opt', 'help');

# true
test example 2
package Example;

use base 'Venus::Task';

sub opts {

  return {
    help => {
      type => 'string',
      help => 'Display help',
      alias => ['h'],
    },
  }
}

package main;

my $task = Example->new(['--help']);

my ($help) = $task->prepare->test('opt', 'help');

# Exception! (isa Venus::Cli::Error) (see error_on_arg_validation)

# Invalid option: help: received (undef), expected (string)

usage

usage() (Venus::Task)

The usage method exits the program with the exit code 1 after calling "log_info" with the result of "help". This method makes it easy to output the default help text and end the program if some condition isn't met.

Since 2.91

usage example 1
# given: synopsis

package main;

my $usage = $task->usage;

# bless({...}, 'Venus::Task')

ERRORS

This package may raise the following errors:

error: error_on_system_call

This package may raise an error_on_system_call exception.

example 1

# given: synopsis;

my $input = {
  throw => 'error_on_system_call',
  args => ['/path/to/nowhere', 'arg1', 'arg2'],
  error => $?,
};

my $error = $task->catch('error', $input);

# my $name = $error->name;

# "on_system_call"

# my $message = $error->render;

# "Can't make system call \"/path/to/nowhere arg1 arg2\": $?"

# my $args = $error->stash('args');

# []

AUTHORS

Awncorp, awncorp@cpan.org

LICENSE

Copyright (C) 2022, Awncorp, awncorp@cpan.org.

This program is free software, you can redistribute it and/or modify it under the terms of the Apache license version 2.0.