Skip to content
Sylvain303 edited this page Feb 21, 2019 · 8 revisions

Welcome to the docopts wiki!

New API proposal for docopts - docopt on shell (bash)

Copied from: API_proposal.md

See issue #7 for the discussion and proposing your changes.

2018-06-03 JSON support API Proposal

The golang version of docopts could handle and parse JSON output natively.

We propose to embed JSON support into docopts (single binary, no need to extra jq for handling JSON in bash).

The idea is to store parsed arguments result into a shell env variable, and to reuse it by docopts sub-call with action expecting this variable to be filled with JSON output.

Experimental version is available at: https://github.com/Sylvain303/docopts/tree/json-api

But performance are weak for now (multiple docopts call are slow)

Usage examples

DOCOPTS_JSON=$(docopts --json -h "Usage: mystuff [--code] INFILE [--out=OUTFILE]" : "$@")

# automatically use $DOCOPTS_JSON
if [[ $(docopts get --code) == checkit ]]
then
  action
fi

The var name could be explicitly set to any user's need (instead of default DOCOPTS_JSON):

docopts --env SOME_DOCOPTS_JSON get --code

# or using an env var naming the env var...
DOCOPTS_JSON_VAR=SOME_DOCOPTS_JSON
docopts get --code

parse failure detection and reaction inside bash code:

  • On parse success, the JSON is filled as expected => exit 0 (DOCOPTS_JSON is filled with parsed options)
  • if -h is given, exit is ≠ 0 (DOCOPTS_JSON is filled with help message)
  • else exit 1 => some argument parsing error (DOCOPTS_JSON is filled with error message)

DOCOPTS_JSON also contains exit code for the caller if necessary.

DOCOPTS_JSON=$(docopts --json --auto-parse "$0" --version '0.1.1rc' : "$@")
# docopts fail : displays error stored in DOCOPTS_JSON and output exit code for
# caller
[[ $? -ne 0 ]] && eval $(docopts fail)

2015-03-13 old school python like bash eval API refactoring

Date: 2015-03-13

Proposed API

I propose to keep a compatibility version for docopts version 0.6.3

It doesn't use the python parser any more. This is an new standalone golang binary: docopts.go

The returned output is a still a snippet of Bash source code, representing a bash shell associative array for $args. It also handles --help + quit (exit 0) directly.

Example of usage

Converted from quick_example.py

#!/bin/bash
#
# Usage:
#  quick_example.sh tcp <host> <port> [--timeout=<seconds>]
#  quick_example.sh serial <port> [--baud=9600] [--timeout=<seconds>]
#  quick_example.sh -h | --help | --version

PATH=..:$PATH

# sourcing the API provides some bash functions ie: docopt()
# still using the python parser
source docopts.sh

help=$(docopt_get_help_string $0)
version='0.1.1rc'

# $@ needs to be at the last param
parsed=$(docopts -A args -h "$help" -V $version : "$@")
echo "$parsed"                                                                                                                        
eval "$parsed"

# Evaluating the parsed output, will create $args in the current scope.
# It is an associative array the name is passed from the command line with -A
# (same switch as bash: declare -A assoc)

shell helpers

# auto extract the Usage string from the top shell script comment
# ie: help=$(sed -n -e '/^# Usage:/,/^$/ s/^# \?//p' < $0)
help_string=$(docopt_get_help_string $0)

# if the option as multiples values, you can get it into an array
array_opt=( $(docopt_get_values args --multiple-time) )

Examples

naval_fate.sh

See python/docopt

Source: naval_fate.sh

naval_fate.sh ship Guardian move 100 150 --speed=15

returned $parsed string to be evaluated:

declare -A arguments
arguments['--drifting']=false    
arguments['mine']=false
arguments['--help']=false
arguments['move']=true
arguments['--moored']=false
arguments['new']=false
arguments['--speed']='15'
arguments['remove']=false
arguments['--version']=false
arguments['set']=false
arguments['<name>']='Guardian'
arguments['ship']=true
arguments['<x>']='100'
arguments['shoot']=false
arguments['<y>']='150'

Limitations

  • repeatable options with filename with space inside, will not be easily split on $IFS, but old fake nested array is still available or use an helper eval "$(docopt_get_eval_array args FILE myarray)"
Clone this wiki locally