NAME

Venus::Task - Task Class

ABSTRACT

Task Class for Perl 5

SYNOPSIS

package Example;

use Venus::Class 'base';

base 'Venus::Task';

package main;

my $task = Example->new;

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

DESCRIPTION

This package provides a lightweight superclass and simple framework for building command-line interfaces (CLIs) in Perl. It defines a consistent structure and lifecycle for task execution, making it easy to create reusable and maintainable CLI commands.

The framework operates in the following order:

  • You assign the task a name.

  • You invoke the "handle" in handle method.

  • The handle method calls prepare and then execute.

  • The prepare method is where CLI arguments and options are configured. By default, prepare registers a single option: the help flag.

  • The execute method dispatches to the perform method, outputs to the terminal, and exits the application. Avoid overridding this method because this is where automated error handling is done. If you need to override this method, be sure to invoke SUPER or similar to retain the core behavior.

  • The perform method is the main method to override in a subclass and contains the core CLI logic. If the CLI is configured to support routing, be sure to invoke SUPER or similar to retain the core behavior.

This structure encourages clean separation of configuration, execution, and logic, making it easier to write and maintain CLI tools.

INHERITS

This package inherits behaviors from:

Venus::Cli

METHODS

This package provides the following methods:

execute

execute() (any)

The execute method dispatches to the perform method, outputs to the terminal, and exits the application.

Since 4.15

execute example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

package main;

my $task = Example->new;

my $execute = $task->execute;

# 0
execute example 2
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

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

  $self->log_info('hello world');

  return $self;
}

package main;

my $task = Example->new;

my $execute = $task->execute;

# 0
execute example 3
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

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

  $self->log_error('oh no');

  return $self;
}

package main;

my $task = Example->new;

my $execute = $task->execute;

# 1

handle

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

The handle method executes the prepare method, and then execute. Optionally accepting a list of command-line arguments to be parsed after "prepare" and before "execute", and if not provided will lazy parse the data in @ARGV.

Since 4.15

handle example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

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

  $self->SUPER::handle; # prepare and execute

  return $self;
}

package main;

my $task = Example->new;

my $handle = $task->handle;

# bless(..., 'Example')

handle_help

handle_help() (boolean)

The handle_help method calls the "help" in Venus::Cli method, outputting help text, if a help flag was found (i.e. provided). This method returns true if a help flag was found, and false otherwise.

Since 4.15

handle_help example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

package main;

my $task = Example->new;

$task->prepare;

my $handle_help = $task->handle_help;

# false
handle_help example 2
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

package main;

my $task = Example->new;

$task->prepare;

$task->parse('--help');

my $handle_help = $task->handle_help;

# true

new

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

The new method constructs an instance of the package.

Since 4.15

new example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

package main;

my $task = Example->new;

# bless({...}, 'Example')
new example 2
package Example;

use Venus::Class 'base';

base 'Venus::Task';

package main;

my $task = Example->new(name => 'example');

# bless({...}, 'Example')
new example 3
package Example;

use Venus::Class 'base';

base 'Venus::Task';

package main;

my $task = Example->new(name => 'example', version => '0.01');

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

perform

perform() (Venus::Task)

The perform method is the main method to override in a subclass and contains the core CLI logic. This method returns the invocant.

Since 4.15

perform example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

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

  $self->log_info('hello world');

  return $self;
}

package main;

my $task = Example->new;

my $execute = $task->perform;

# bless(..., 'Example')
perform example 2
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

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

  $self->log_error('oh no');

  return $self;
}

package main;

my $task = Example->new;

my $execute = $task->perform;

# bless(..., 'Example')

prepare

prepare() (Venus::Task)

The prepare method is the main method to override in a subclass, and is where CLI arguments and options are configured. By default, this method registers a single option: the help flag. This method returns the invocant.

Since 4.15

prepare example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

package main;

my $task = Example->new;

my $prepare = $task->prepare;

# bless(..., 'Example')
prepare example 2
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub name {
  'mycli'
}

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

  $self->option('help', {
    name => 'help',
    type => 'boolean',
  });

  $self->option('version', {
    name => 'version',
    aliases => ['v'],
    type => 'boolean',
  });

  return $self;
}

package main;

my $task = Example->new;

my $prepare = $task->prepare;

# bless(..., 'Example')

spec_data

spec_data() (maybe[hashref])

The spec_data method returns a hashref to be passed to the "spec" in Venus::Cli method during "prepare". By default, this method returns undef. Subclasses should override this method to provide CLI configuration data.

Since 4.15

spec_data example 1
package Example;

use Venus::Class 'base';

base 'Venus::Task';

package main;

my $task = Example->new;

my $spec_data = $task->spec_data;

# undef
spec_data example 2
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub spec_data {
  {
    name => 'example',
    version => '1.0.0',
    summary => 'Example CLI',
    options => [
      {
        name => 'verbose',
        type => 'boolean',
        aliases => ['v'],
      },
    ],
    commands => [
      ['command', 'run', 'handle_run'],
    ],
  }
}

sub handle_run {
  my ($self, $args, $opts) = @_;
  return 'running';
}

package main;

my $task = Example->new;

my $spec_data = $task->spec_data;

# {
#   name => 'example',
#   version => '1.0.0',
#   ...
# }
spec_data example 3
package Example;

use Venus::Class 'base';

base 'Venus::Task';

sub spec_data {
  {
    name => 'example',
    commands => [
      ['command', 'hello', 'handle_hello'],
    ],
  }
}

sub handle_hello {
  my ($self, $args, $opts) = @_;
  return 'hello world';
}

package main;

my $task = Example->new;

$task->prepare;

my $result = $task->dispatch('hello');

# "hello world"

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.