16.1 Introduction to action trees

Traditional Unix–style command–line programs perform a single action, with behaviour variants selected by command–line dash and double–dash options. For example ls prints a list of directory entries and the format of the output can be custommised with options like -1 and --colour. MBFL implements this behaviour by default when the actions module is not used.

Other Unix–style command–line programs offer a set of possible actions and allow the executor to select one by specifying command–line options. For example tar acts on archive files and it can pack, unpack, validate them along with other actions selected with by the double–dash options --create, --extract, --validate and others. MBFL implements this behaviour through “action options” provided by the getopts module; action options are available also when using the actions module.

Other command–line programs break this Unix–style to offer action selection throuh “action arguments”. For example git acts upon revision control repositories offering a big set of actions selected with its first argument: ‘commit’, ‘log’, ‘merge’ and many others; the behaviour of each “subcommand” can be customised with a specific set of dash and double–dash options. MBFL implements this behaviour through the actions module.

One–level actions

The script below (one-level-actions.sh, available in the doc/ directory of the source distribution) shows how to implement one–level actions. It implements the following behaviour:

one-level-actions.sh

With no action argument: print a generic help screen and exit.

one-level-actions.sh one

With the action argument one: perform the action ‘ONE’, possibly with the options -a and -b.

one-level-actions.sh one -H

With the action argument one and the option -H: print the brief help screen for the action ‘ONE’ and exit.

one-level-actions.sh two

With the action argument two: perform the action ‘TWO’, possibly with the options -d and -g.

one-level-actions.sh two -H

With the action argument two and the option -H: print the brief help screen for the action ‘TWO’ and exit.

one-level-actions.sh help

With the action argument help: print a generic help screen and exit. Notice how the ‘HELP’ action function makes use of mbfl_actions_fake_action_set() to print the same help screen of the main action.

# one-level-actions.sh --

script_PROGNAME=one-level-actions.sh
script_VERSION=1.0
script_COPYRIGHT_YEARS='2013'
script_AUTHOR='Marco Maggi'
script_LICENSE=BSD
script_USAGE="usage: ${script_PROGNAME} [action] [options]"
script_DESCRIPTION='Example script showing action arguments.'
script_EXAMPLES=

source "${MBFL_LIBRARY:=$(mbfl-config)}"

mbfl_declare_action_set MAIN
mbfl_declare_action MAIN ONE  NONE one  'Do main action one.'
mbfl_declare_action MAIN TWO  NONE two  'Do main action two.'
mbfl_declare_action MAIN HELP NONE help 'Do main action help.'

function script_before_parsing_options_ONE () {
    script_USAGE="usage: ${script_PROGNAME} one [options]"
    script_DESCRIPTION='Example action tree: one.'
    mbfl_declare_option ALPHA no a alpha noarg 'Enable option alpha.'
    mbfl_declare_option BETA  '' b beta  witharg 'Set option beta.'
}
function script_before_parsing_options_TWO () {
    script_USAGE="usage: ${script_PROGNAME} two [options]"
    script_DESCRIPTION='Example action tree: two.'
    mbfl_declare_option DELTA no d delta noarg 'Enable option delta.'
    mbfl_declare_option GAMMA '' g gamma witharg 'Set option gamma.'
}
function main () {
    mbfl_main_print_usage_screen_brief
}
function script_action_HELP () {
    mbfl_actions_fake_action_set MAIN
    mbfl_main_print_usage_screen_brief
}
function script_action_ONE () {
    printf 'performing action one: alpha=%s, beta=%s\n' \
        "$script_option_ALPHA" "$script_option_beta"
}
function script_action_TWO () {
    printf 'performing action two: delta=%s, gamma=%s\n' \
        "$script_option_DELTA" "$script_option_GAMMA"
}
mbfl_main

### end of file
# Local Variables:
# mode: sh
# End:

Two–levels actions

The script below (two-levels-actions.sh, available in the doc/ directory of the source distribution) shows how to implement two–levels actions. It implements the following behaviour:

two-levels-actions.sh

With no action argument: print a generic help screen and exit.

two-levels-actions.sh help

With the action argument help: print a generic help screen and exit. Notice how the ‘HELP’ action function makes use of mbfl_actions_fake_action_set() to print the same help screen of the main action.

two-levels-actions.sh one

With the non–leaf action argument one: print the help screen of the action ‘ONE’.

two-levels-actions.sh two

With the non–leaf action argument two: print the help screen of the action ‘TWO’.

two-levels-actions.sh one red

With the action arguments one red: perform the action ‘RED’, possibly with the options -a and -b.

two-levels-actions.sh one red -H

With the action argument one red and the option -H: print the brief help screen for the action ‘RED’ and exit.

two-levels-actions.sh one blue

With the action arguments one blue: perform the action ‘BLUE’, possibly with the options -a and -b.

two-levels-actions.sh one blue -H

With the action argument one blue and the option -H: print the brief help screen for the action ‘BLUE’ and exit.

two-levels-actions.sh two green

With the action arguments two green: perform the action ‘GREEN’, possibly with the options -d and -g.

two-levels-actions.sh two green -H

With the action argument two green and the option -H: print the brief help screen for the action ‘GREEN’ exit.

two-levels-actions.sh two cyan

With the action arguments two cyan: perform the action ‘CYAN’, possibly with the options -d and -g.

two-levels-actions.sh two cyan -H

With the action argument two cyan and the option -H: print the brief help screen for the action ‘CYAN’ exit.

notice how the action functions of the non–leaf nodes print the help screen describing the subactions.

# two-level-actions.sh --

script_PROGNAME=two-levels-actions.sh
script_VERSION=1.0
script_COPYRIGHT_YEARS='2013'
script_AUTHOR='Marco Maggi'
script_LICENSE=BSD
script_USAGE="usage: ${script_PROGNAME} [action] [subaction] [options]"
script_DESCRIPTION='Example script showing action arguments.'
script_EXAMPLES=

source "${MBFL_LIBRARY:=$(mbfl-config)}"

mbfl_declare_action_set ONE
mbfl_declare_action ONE RED  NONE red  'Do main action one red.'
mbfl_declare_action ONE BLUE NONE blue 'Do main action one blue.'

mbfl_declare_action_set TWO
mbfl_declare_action TWO GREEN NONE green 'Do main action one green.'
mbfl_declare_action TWO CYAN  NONE cyan  'Do main action one cyan.'

mbfl_declare_action_set MAIN
mbfl_declare_action MAIN ONE  ONE  one  'Do main action one.'
mbfl_declare_action MAIN TWO  TWO  two  'Do main action two.'
mbfl_declare_action MAIN HELP NONE help 'Do main action help.'

function script_before_parsing_options_ONE () {
    script_USAGE="usage: ${script_PROGNAME} one [action] [options]"
    script_DESCRIPTION='Example action tree: one.'
}
function script_before_parsing_options_TWO () {
    script_USAGE="usage: ${script_PROGNAME} two [action] [options]"
    script_DESCRIPTION='Example action tree: two.'
}

function script_before_parsing_options_RED () {
    script_USAGE="usage: ${script_PROGNAME} one red [options]"
    script_DESCRIPTION='Example action tree: one red.'
    mbfl_declare_option ALPHA no a alpha noarg 'Enable option alpha.'
    mbfl_declare_option BETA  '' b beta  witharg 'Set option beta.'
}
function script_before_parsing_options_BLUE () {
    script_USAGE="usage: ${script_PROGNAME} one blue [options]"
    script_DESCRIPTION='Example action tree: one blue.'
    mbfl_declare_option DELTA no d delta noarg 'Enable option delta.'
    mbfl_declare_option GAMMA '' g gamma witharg 'Set option gamma.'
}
function script_before_parsing_options_GREEN () {
    script_USAGE="usage: ${script_PROGNAME} two green [options]"
    script_DESCRIPTION='Example action tree: two green.'
    mbfl_declare_option ALPHA no a alpha noarg 'Enable option alpha.'
    mbfl_declare_option BETA  '' b beta  witharg 'Set option beta.'
}
function script_before_parsing_options_CYAN () {
    script_USAGE="usage: ${script_PROGNAME} two cyan [options]"
    script_DESCRIPTION='Example action tree: two cyan.'
    mbfl_declare_option DELTA no d delta noarg 'Enable option delta.'
    mbfl_declare_option GAMMA '' g gamma witharg 'Set option gamma.'
}

function main () {
    mbfl_main_print_usage_screen_brief
}
function script_action_ONE () {
    mbfl_main_print_usage_screen_brief
}
function script_action_TWO () {
    mbfl_main_print_usage_screen_brief
}
function script_action_HELP () {
    mbfl_actions_fake_action_set MAIN
    mbfl_main_print_usage_screen_brief
}

function script_action_RED () {
    printf 'performing action red: alpha=%s, beta=%s\n' \
        "$script_option_ALPHA" "$script_option_BETA"
}
function script_action_BLUE () {
    printf 'performing action blue: delta=%s, gamma=%s\n' \
        "$script_option_DELTA" "$script_option_GAMMA"
}
function script_action_GREEN () {
    printf 'performing action green: alpha=%s, beta=%s\n' \
        "$script_option_ALPHA" "$script_option_BETA"
}
function script_action_CYAN () {
    printf 'performing action cyan: delta=%s, gamma=%s\n' \
        "$script_option_DELTA" "$script_option_GAMMA"
}

mbfl_main

### end of file
# Local Variables:
# mode: sh
# End:

This document describes version 3.0.0-devel.9 of Marcos Bash Functions Library.