Style guidelines =============== Indentation ----------- Code must be indented using four spaces. In vim, this can be accomplished using set shiftwidth=4 set expandtab Naming ------ Short version: $GLOBAL, $local, func_name() Variables must be declared and scoped. GLOBAL_VARIABLES # are uppercase unless there's a good reason not to. # (e.g., path as a special meaning in Zsh) local samplevar # are lowercase and scoped to the function # name # should be readable. Do not make unnecessary # shortcuts that would impede others to read fluidly # Please comment your functions before coding them: it helps # clear the mind on the objective. If it does too much, you # probably want to split it. Any reusable code should be # isolated. any_function() {} _internals() {} # Prepend an _ if the function is clearly internal, # that is, if it's only called within the scope of # another function. Sample code: # Sample public command. # # It shows developers how to write readable code. # Returns 0 on success, or fails public_command() { local tombpath="$1" # First argument is the path to the tomb local orientation="${2:-South}" # Second optional argument local something is happening [[ -z $tombpath ]] && { _failure "Usage public_command tombpath [orientation=South]" } case $orientation in (South|North|East|West) break;; (*) _failure "orientation must be one of South, North, East, or West." ;; esac _check_swap # Ensure the available memory is safe _plot $tombpath # Set TOMB{PATH,DIR,FILE,NAME} for is in $TOMBLOOPDEVS; do [[ -k $is ]] && { happening+="$is " } || { something+="$is " } done _message "You gotta sort your bones." return 0 } Reporting to the user --------------------- There are some nifty messaging functions to use. They all come with shortcuts that you can use during development or for temporary messages. The long name is to be used for translatable strings. They display formatted messages, using colors when available. DEBUG=1 make the _verbose messages visible. QUIET=1 suppresses all messages (but the _verbose messages if DEBUG=1). Here is the deal: Name (Shortcut) Return When to use ================================================================================= _verbose (xxx) You need to check the current state of the program. _message (say) You want to tell the user about what's going on. You can pass -n (shortcut: act) for inline messages. _warning (no) You want to inform the user about an error condition. _success (yes) You want to tell the user about a successful result. _failure (die) exit 1 You want to exit the program with a fatal error. You may pass a different exit code as exitval. All messaging function take a single "message" argument. _failure takes an exit code as an optional exitval environment variable. Additionally you can use _print to pass translatable string without decoration. Examples: _verbose "Showing translatable debug message" xxx "This is temporary debug" _message "The program is doing something" _message -n "Inline messages " echo "are useful" _success "All is fine" _warning "Something's wrong" _print "Did I really say that?" _failure "Fatal error: exiting with default exit code 1" _message "This is not reached, nor the next 'die' command" exitval=127 die "I am Jack's dead corpse." Will display something like: tomb [D] Showing translatable debug message tomb [D] This is temporary debug tomb . The program is doing something tomb > Inline messages are useful tomb (*) All is fine tomb [W] Something's wrong Did I really say that? tomb [E] Fatal error: exiting with default exit code 1