The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

appspec-bash - Command line framework generator for bash

ABSTRACT

Generate commandline parser, completion and man pages

DESCRIPTION

This script can generate a commandline parser for bash from a specification file written in YAML.

Writing a parser for commandline arguments isn't rocket science, but it's something you don't want to do manually for all of your scripts, especially in bash. Some tools exist, but they often don't support subcommands or validating of option values.

appspec/appspec-bash can generate pretty much everything for you:

Commandline parser for subcommands, options and parameters
Usage output
Shell completion files
man pages

EXAMPLES

Here is an example of a very simple script.

The following files are needed:

  share/mytool.yaml
  bin/mytool
  lib/mytool
  lib/appspec                       # generated
  share/completion/zsh/_mytool      # generated
  share/completion/bash/mytool.bash # generated
  pod/mytool.pod                    # generated
  lib/help                          # generated

The spec:

  # share/mytool.yaml
  ---
  name: mytool           # commandname
  appspec: { version: 0.001 }
  plugins: [-Meta]       # not supported in bash
  title: My cool tool    # Will be shown in help
  class: MyTool          # "Class name" (means function prefix here)

  subcommands:
    command1:
      op: command1       # The function name (MyTool.command1)
      summary: cmd one   # Will be shown in help and completion
      options:
      - foo|f=s --Foo    # --foo or -f; '=s' means string
      - bar|b   --Bar    # --bar or -b; a flag

Your script mytool would look like this:

  # bin/mytool
  #!/bin/bash
  DIR="$( dirname $BASH_SOURCE )"
  source "$DIR/../lib/appspec"
  source "$DIR/../lib/mytool"
  APPSPEC.run $@

The actual app:

  # lib/mytool
  #!/bin/bash
  MyTool.command1() {
      echo "=== OPTION foo: $OPT_FOO"
      echo "=== OPTION bar: $OPT_BAR"
  }

Generating the parser

Then generate the parser like this:

  $ appspec-bash generate parser share/mytool.yaml lib/appspec

APPSPEC.run will parse the arguments and then call the function MyTool.command1. In this function you can use the options via $OPT_FOO and $OPT_BAR.

  $ ./bin/mytool command1 --foo x --bar
  # or
  $ mytool command1 -f x -b
  === OPTION foo: x
  === OPTION bar: true

Generate completion

    $ appspec completion share/mytool.yaml --zsh >share/completion/zsh/_mytool
    $ appspec completion share/mytool.yaml --bash >share/completion/bash/mytool.bash

Generate pod

    $ appspec pod share/mytool.yaml > pod/mytool.pod
    $ perldoc pod/mytool.pod

Generate help

    $ appspec-bash generate help share/mydemo.yaml lib/help

Generate a new app skeleton

  appspec-bash new --class MyTool --name mytool

This will create your app mytool in the directory MyTool and output some usage information like this:

  To generate the parser and help, do:

    % cd MyTool
    % appspec-bash generate parser share/mytool.yaml lib/appspec
    % appspec-bash generate help share/mytool.yaml lib/help

  Try it out:

    % bin/mytool cmd1 -ab --opt-x x -yfoo --opt-y bar
    % bin/mytool cmd2 -vvv
    % bin/mytool cmd2 -vvv foo

OPTION AND PARAMETER PARSING

appspec-bash supports various types of options.

Flags

    # YAML
    options:
    - verbose|v -- Verbose output

    % mytool --verbose
    % mytool -v

You can also stack several flags:

    % mytool -abc

Options with values

    # YAML
    options:
    - color|c=s --Specify color

    % mytool --color red
    % mytool -c red
    % mytool -cred
    # Not yet supported
    # mytool --color=red

You can stack flags together with options. If you have the flags -a and -b and the option -c, then you can use this syntax:

    % mytool -abc23

Incremental flags

    # YAML
    options:
    - verbose|v+ --Verbose output (incremental)

    % mytool -vvv                # like: declare -i OPT_VERBOSE=3
    % mytool --verbose --verbose # like: declare -i OPT_VERBOSE=2

Options with multiple values

    # YAML
    options:
    - server|s=s@  --List of servers

    % mytool --server foo --server bar
    % mytool -s foo -s bar

Parameters

    # YAML
    parameters:
    - name: server
      required: true
      summary: Server name

Option types

By default, an option is a flag. To accept a value, add a =. Then it will be a string by default:

    - foo=
    # or
    - foo=s

You can also create integer options:

    - max=i --Specify maximum value

Then you can treat it as an integer and use OPT_MAX+=1 for example.

There are also the types file, dir, filename and dirname. Currently they are only relevant for completion.

    # YAML
    - input= +file      --Input filename
    - source-dir= +dir  --Source directory
    - output= +filename --Output file
    - out-dir= +dirname --Output directory

In the future, file and dir will check for an existing file or directory. And filename and dirname can be used if the file or directory doesn't exist yet, but the tab completion will still offer file or directory names.

See the mydemo app in the example directory for examples of options and parameters.

GLOBAL OPTIONS

    --help -h    Show command help (flag)

SUBCOMMANDS

generate

    appspec-bash  generate <subcommands>

Generate parser, help

generate help

    appspec-bash generate help <spec> <output>

Generate help functions

Parameters:

    spec    *  YAML Specification file   
    output  *  Output file, e.g. lib/help

generate parser

    appspec-bash generate parser <spec> <output>

Generate main commandline parser script

Parameters:

    spec    *  YAML Specification file      
    output  *  Output file, e.g. lib/appspec

new

    appspec-bash  new [options] [<path>]

Generate new app

This command creates a skeleton for a new app. It will create a directory for your app and write a skeleton spec file.

Example:

  appspec-bash new --name mytool --class MyTool MyTool

Options:

    --name -n       *  The (file) name of the app                                    
    --class -c      *  The main "class" (function prefix) for your app implementation
    --overwrite -o     Overwrite existing dist directory (flag)                      

Parameters:

    path    Path to the distribution directory (default is the classname in current directory)

help

    appspec-bash  help <subcommands> [options]

Show command help

Options:

    --all     (flag)

_meta

    appspec-bash  _meta <subcommands>

Information and utilities for this app

_meta completion

    appspec-bash _meta completion <subcommands>

Shell completion functions

_meta completion generate

    appspec-bash _meta completion generate [options]

Generate self completion

Options:

    --name    name of the program (optional, override name in spec)
    --zsh     for zsh (flag)                                       
    --bash    for bash (flag)                                      

_meta pod

    appspec-bash _meta pod <subcommands>

Pod documentation

_meta pod generate

    appspec-bash _meta pod generate

Generate self pod