practices
some engineering practices.
shell scripts
- Use
bash
. Usingzsh
orfish
or any other, will make it hard for others to understand / collaborate. Among all shells, bash strikes a good balance between portability and DX. - Just make the first line be
#!/usr/bin/env bash
, even if you don’t give executable permission to the script file. - Use the
.sh
(or.bash
) extension for your file. It may be fancy to not have an extension for your script, but unless your case explicitly depends on it, you’re probably just trying to do clever stuff. Clever stuff are hard to understand. - Use
set -o errexit
at the start of your script.So that when a command fails, bash exits instead of continuing with the rest of the script. - Prefer to use
set -o nounset
. You may have a good excuse to not do this, but, my opinion, it’s best to always set it.
- This will make the script fail, when accessing an unset variable. Saves from horrible unintended consequences, with typos in variable names.
- When you want to access a variable that may or may not have been set, use "
${VARNAME-}
" instead of "$VARNAME
", and you’re good.
- Use
set -o pipefail
. Again, you may have good reasons to not do this, but I’d recommend to always set it. This will ensure that a pipeline command is treated as failed, even if one command in the pipeline fails. - Use
set -o xtrace
, with a check on$TRACE
env variable.
- For copy-paste:
if [[ "${TRACE-0}" == "1" ]]; then set -o xtrace; fi
. - This helps in debugging your scripts, a lot. Like, really lot.
- People can now enable debug mode, by running your script as
TRACE=1 ./script.sh
instead of./script.sh
.
- Use
[[ ]]
for conditions inif / while
statements, instead of[ ]
ortest
.
[[ ]]
is a bash keyword, and is more powerful than[ ]
ortest
.
- Always quote variable accesses with double-quotes.
- One place where it’s okay not to is on the left-hand-side of an
[[ ]]
condition. But even there I’d recommend quoting. - When you need the unquoted behaviour, using bash arrays will likely serve you much better.
- Use
local
variables in functions. - Accept multiple ways that users can ask for help and respond in kind.
- Check if the first arg is
-h
or--help
orhelp
or justh
or even-help
, and in all these cases, print help text and exit. - Please. For the sake of your future-self.
- When printing error messages, please redirect to stderr. Use
echo 'Something unexpected happened' >&2
for this. - Use long options, where possible (like
--silent
instead of-s
). These serve to document your commands explicitly. Note though, that commands shipped on some systems like macOS don’t always have long options. - If appropriate, change to the script’s directory close to the start of the script.
- And it’s usually always appropriate.
- Use
cd "$(dirname "$0")"
, which works in most cases.
- Use
shellcheck
. Heed its warnings.
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi
if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then
echo 'Usage: ./script.sh arg-one arg-two
This is an awesome bash script to make your life better.
'
exit
fi
cd "$(dirname "$0")"
main() {
echo do awesome stuff
}
main "$@"
reference: Shell Script Best Practices (opens in a new tab)
conventional commits
a convention on top of commit messages, conforms with semver.
why use conventional commits?
- communicate and document changes better (easier to read and track).
- a more structured commit history, helping others to contribute easier.
- directs us to commit by scope (a commit for a specific problem)
- helps to generate automatic changelog when using
standard-version
.
<type>[optional scope]: <description>
# example
feat(pages): add home page
type | |
---|---|
feat | adds a new feature which brings changes |
fix | bug fix |
if you are using vscode (opens in a new tab), you can use this extension (opens in a new tab) to help you compose conventional commit messages.
read more:
conventional comments
code reviews can be better if we understand that the code we are reviewing are written by human and our review are also gonna be read by human. sometimes we don't realize if our comments are unhelpful. this can be improved by following conventional comments (opens in a new tab), a convention which are inspired by conventional commits (opens in a new tab) and google engineering practices (opens in a new tab).
example of unhelpful comments:
It's not worded correctly
by giving a label prefix:
suggestion: It's not worded correctly
how about
other_word
instead?
sounds better, right? reducing undercommunication and misunderstandings.
<label> [decorations]: <subject>
[discussion]
read more: conventional comments (opens in a new tab)