aboutsummaryrefslogtreecommitdiff

Generate Markdown documentation from shell-scripts

Source: comments, followed by declare prefix and assignments (repeatable inline)
Variable: assignment followed by comments
Function: function, followed by comments, followed by local prefix and assignments (repeatable inline)

Comparison with other implementations

  • Does not requires extensive documentation (either in a custom format or Javadoc-like)
  • Signatures are extracted directly from code (no duplicate signature, in code and docs)

Notes

  • Sources may be prefixed by shebang line
  • Variables may be prefixed by declare or export
  • Functions may be prefixed by function
  • Arguments must be prefixed by declare, export or local (resumable inline)
  • Arguments definition stops at first non-assignment
  • Functions and variables may be prefixed by _ (excluded)
  • Arguments may be prefixed by _ (included)
  • Check Makefile for installation

Usage

shdoc [sources...]

Documentation

This document is auto-generated from shell-scripts sources

modifier @

Array variable or variadic argument

modifier =

Constant variable or argument

modifier :

Treat null variable or argument as unset

modifier ?

Error if variable or argument unset

modifier -

Default value if variable or argument unset


Example source code

#!/usr/bin/env bash
# Script utilities (bash specific)
# Recommended shebang is `/usr/bin/env bash` (so `PATH` is used)
# Then source `SCRIPT_SRC` (defaulting to `/usr/local/share/script`)
# Shell options `errexit` and `nounset` are supported and can be enabled

# Fundamental variables
SCRIPT_SRC="${SCRIPT_SRC:-${BASH_SOURCE:?}}"
# Current script library entry path
# Imported and exported from the environment

source script() [L1]

Script utilities (bash specific)

Recommended shebang is /usr/bin/env bash (so PATH is used)
Then source SCRIPT_SRC (defaulting to /usr/local/share/script)
Shell options errexit and nounset are supported and can be enabled

variable SCRIPT_SRC=:- [L8]

Current script library entry path

Imported and exported from the environment


Example source code

function parse_array() {
	# Parse string to an array
	# Similar to `var=($txt)` but it does respect quotes and escapes
	# Similar to `eval var=($txt)` but it does not respect substitutions and expansions
	# **Notice**: array is declared using the name provied
	local _var="${1:?}"; shift; local _txts="${*?}"; declare -n _var

function parse_array(var:?, txts@?) [L4]

Parse string to an array

Similar to var=($txt) but it does respect quotes and escapes
Similar to eval var=($txt) but it does not respect substitutions and expansions
Notice: array is declared using the name provied


Example source code

TRUE='1'
# Value representing true
# Used by `is_true` and non-null for tests

variable TRUE= [L5]

Value representing true

Used by is_true and non-null for tests


Example source code

function parse_args() {
	# Parses script arguments
	# - Verifies arguments are supplied (aborting)
	# - Assign them to `const_name` variables named as provided
	local _args=("$@")

function parse_args(args@) [L4]

Parses script arguments

  • Verifies arguments are supplied (aborting)
  • Assign them to const_name variables named as provided

Example source code

function local_dir() {
	# Get specific local directory (and optionally create it if missing)
	# Prefix with `sys` or `user` follow by `-` to get relevant variant
	# - `conf`  = Configuration
	# - `log`   = Logging
	# - `exe`   = Executables
	# - `ref`   = Data (ro)
	# - `state` = Data (rw)
	# - `tmp`   = Data (timed)
	# - `run`   = Data (session)
	local key="${1:?}" gen="${2-${FALSE?}}" path

function local_dir(key:?, gen-) [L4]

Get specific local directory (and optionally create it if missing)

Prefix with sys or user follow by - to get relevant variant

  • conf = Configuration
  • log = Logging
  • exe = Executables
  • ref = Data (ro)
  • state = Data (rw)
  • tmp = Data (timed)
  • run = Data (session)

Example source code

function typescript() {
	# Record the std{in,out,err} of a command (including timing and exit code)
	# Similar to `script -c $@` but keeping streams separated
	# **Warning**: stdin logger remains active briefly after command (stdin may consume writes)
	local log="${1:?}"; shift; local cmd=("${@:?}")

function typescript(log:?, cmd@:?) [L26]

Record the std{in,out,err} of a command (including timing and exit code)

Similar to script -c $@ but keeping streams separated
Warning: stdin logger remains active briefly after command (stdin may consume writes)


Example source code

function @~() {
	# Terniary command operator
	# **Notice**: result evaluation is not short-circuited
	local cmd=("${@:?}") true="${2?}" false="${3?}"

function @~(cmd@:?, true?, false?) [L4]

Terniary command operator

Notice: result evaluation is not short-circuited


Example source code

function is_sys() {
	# Checks if the current scope is `sys`

function is_sys() [L18]

Checks if the current scope is sys


Example source code

function rsh() {
	# Execute a remote command in a non-interactive environment
	# Optional options, host, command (concatenated and evaluated)
	local opts=("$@") host="${0:?}" cmd="${*:?}"

function rsh(opts@, host:?, cmd@:?) [L10]

Execute a remote command in a non-interactive environment

Optional options, host, command (concatenated and evaluated)


Example source code

function is_abspath() {
	# Checks if path is absolute
	local path="${1?}"

function is_abspath(path?) [L4]

Checks if path is absolute


Example source code

function atexit() {
	# Register code to be run at exit (LIFO order)
	# Code runs with the enviroment present at exit (not at register)
	# When enabled `SCRIPT_EXIT` contains the script's exit code
	# **Notice**: queues and exits are scoped to the current subshell
	# **Warning**: uses `trap ... EXIT` (override)
	# - Arguments: concatenated and evaluated at exit
	# - No arguments: evaluate queue immediately
	local _code="$*" _ _last="$?"

function atexit(code@) [L4]

Register code to be run at exit (LIFO order)

Code runs with the enviroment present at exit (not at register)
When enabled SCRIPT_EXIT contains the script’s exit code
Notice: queues and exits are scoped to the current subshell
Warning: uses trap ... EXIT (override)

  • Arguments: concatenated and evaluated at exit
  • No arguments: evaluate queue immediately

Example source code

function is_int() {
	# Checks if value is a valid integer
	local val="${1?}"

function is_int(val?) [L4]

Checks if value is a valid integer


Example source code

SCRIPT_ARGS=("$@")
# Effective script's arguments
# Used when functions need access to the script's arguments insted of their own

SCRIPT_PATH="${SCRIPT_PATH:-$(script_path)}"
# Effective script's path base
# Single path componet used to index into script's specific paths
# Imported from the environment

variable SCRIPT_ARGS@ [L5]

Effective script’s arguments

Used when functions need access to the script’s arguments insted of their own

variable SCRIPT_PATH=:- [L9]

Effective script’s path base

Single path componet used to index into script’s specific paths
Imported from the environment