:B~ Coding Style

1~coding-style Coding Style

This chapter documents the coding style used in live systems.

2~ Compatibility

_* Avoid "bashisms", the codebase must be POSIX compliant and thus universally compatible.

_* Furthermore it must comply with the version of the POSIX specification chosen by the current Debian Policy.

_* You can check your scripts with 'sh -n' and 'checkbashisms'.

_* Make sure all shell code runs with 'set -e'.

2~ Indenting

_* Always use tabs over spaces.

_* Keep case branch terminators (";;") aligned with the "content" of the branch, rather than the branch "entry".

Good:

code{

 case "${1}" in
         foo)
                 foobar
                 ;;

         bar)
                 foobar
                 ;;
 esac

}code

2~ Wrapping

_* Generally, lines should be 80 chars at maximum.

_* Placement of keywords like #{then}# and #{do}# should be chosen with good judgement with respect to clutter and readability. For small bits of code in particular it should be preferred to have them on the same line as the prior keyword they relate to (#{if}#; #{for}#; etc). Only place on the next line where it makes good sense to do so; typically this might only be to comply with maximum line length restrictions. One situation where they should always be placed on the next line is where what they follow is broken up onto multiple lines, and thus it being on a new line creates clear separation between that and the body of code following it. I.e. :

Preferred:

code{

 if foo; then
         bar
 fi

 for FOO in $ITEMS; do
         bar
 done

 if [ "${MY_LOCATION_VARIABLE}" = "something" ] && [ -e "${MY_OUTPUT_FILE}" ]
 then
         MY_OTHER_VARIABLE="$(some_bin ${FOOBAR} | awk -F_ '{ print $1 }')"
 fi

 if [ "${MY_FOO}" = "something" ] && [ -e "path/${FILE_1}" ] ||
   [ "${MY_BAR}" = "something_else" ] && [ ${ALLOW} = "true" ]
 then
         foobar
 fi

}code

Less ideal:

code{

 if [ "${MY_LOCATION_VARIABLE}" = "something" ] && [ -e "${MY_OUTPUT_FILE}" ]; then
         MY_OTHER_VARIABLE="$(some_bin ${FOOBAR} | awk -F_ '{ print $1 }')"
 fi

}code

Horrible:

code{

 if [ "${MY_LOCATION_VARIABLE}" = "something" ] && [ -e "${MY_OUTPUT_FILE}" ] || [ "${MY_LOCATION_VARIABLE}" = "something-else" ] && [ -e "${MY_OUTPUT_FILE_2}" ]; then
         MY_OTHER_VARIABLE="$(some_bin ${FOOBAR} | awk -F_ '{ print $1 }')"
 fi

}code

_* Prefer placing the opening brace of a function on a new line (for consistency with established style), and keep the braces aligned with the function name:

Good:

code{

 Foo ()
 {
         bar
 }

}code

Bad (inconsistent with existing style):

code{

 Foo () {
         bar
 }

}code

Awful:

code{

 Foo ()
         {
         bar
         }

}code

2~ Variables

_* Variables are always in capital letters.

_* Config variables used in live-build should start with an #{LB_}# prefix.

_* Local function variables should be restricted to local scope.

_* Variables in connection to a boot parameter in live-config start with #{LIVE_}#.

_* All other variables in live-config start with #{_}# prefix.

_* Use braces around variables; e.g. write #{${FOO}}# instead of #{$FOO}#.

_* Always protect variables with quotes to respect potential whitespaces (except where necessary to achieve correct word splitting): write #{"${FOO}"}# not #{${FOO}}#.

_* For consistency reasons, always use quotes when assigning values to variables:

Bad:

code{

 FOO=bar

}code

Good:

code{

 FOO="bar"

}code

_* If multiple variables are used, prefer quoting the full expression:

Typically bad:

code{

 if [ -f "${FOO}"/foo/"${BAR}"/bar ]; then
         foobar
 fi

}code

Good:

code{

 if [ -f "${FOO}/foo/${BAR}/bar" ]; then
         foobar
 fi

}code

2~ Miscellaneous

_* Prefer "#{|}#" (without the surround quotes) as a separator in calls to sed, e.g. "#{sed -e 's|foo|bar|'}#" (without "").

_* Don't use the #{test}# command for comparisons or tests, use "#{[}#" and "#{]}#" (without ""); e.g. "#{if [ -x /bin/foo ]; ...}#" and not "#{if test -x /bin/foo; ...}#".

_* Use #{case}# wherever it makes code more readable than conditional checks (#{if foo; ...}# and tests without the actual #{if}# keyword, e.g. #{[ -e "${FILE}" ] || exit 0}#).

_* Use "Foo_bar" style names for functions, i.e. a capital first letter, then all lowercase, with sensible use of underscores for better readability.
