Here you can find a number of best practices that you should strive to follow when you develop.
This will ensure that we produce better and safer code, easier to understand, to extend, in short: more maintainable.
-
Use editorconfig (and one of the many supported editors) to ensure coding style is consistent between each developer.
-
Chose your editor(s) of choice. For a text editor/general purpose editor, you can use any of Sublime Text (closed-source and not free (normally), but very fast), atom (free and open source, but slow (thx electron...), from GitHub), VS Code (free and open source, faster than atom even though it is also using electron, from Microsoft). They all support plugins, which can be very helpful. Use them!
-
If you need powerful IDEs (for Java, PHP, JS, Python, Ruby, Go...), JetBrains is offering all its products (that's 250€ of free stuff!) to anyone with a student email (see here for more information). Register here with your
centraliens de lille
email, and get access to unlimited free goodies! -
Whether you start a new project or you want to add a library to an existing project, look at the Awesome lists. Your dream lib in any language is probably already there, curated by the community! (If you like awesome lists of awesome lists, check out this ^^)
This guide, although more oriented towards Node module development, explains how to write a top-notch README, that makes it easy to discover and use your features without diving into the code.
Look at these READMEs if you want to copy the creme de la creme.
Versioning is a form of documentation. So keep a changelog: you can follow the KeepChangelog format, which is very nice (you describe changes in different categories, and you even have an Unreleased category, so you can addd features & fixes as you code, instead of trying to remember everything you did when the new version is released...).
Use git. Git everything, use git to its full extent.
- Create branches before working on a feature
- Write meaningful commit messages.
- Rebase and squash for private branches (or public branches if you know for sure that nobody else ever used it).
- Don't forget to ignore useless files (compiled binaries, node dependencies, editor junk files) with a
.gitignore
. Don't hesitate to use gitignore.io to generate a.gitignore
specific to your IDE/language/framework.
// TODO: Add links to explain what a good commit message is
Use GitHub, use it to its full extent.
- Ask for Pull Requests before merging a branch.
- Wait until at least one person has reviewed your code and accepted it.
- Review others code, and don't be afraid to question nor criticize it.
- Create issues if you ever find a bug, or think of an improvement to make.
- Link issues to branches in your commit messages, so that they can be automatically closed.
- Add a
CONTRIBUTING.md
if you plan to make the project public, aPULL_REQUEST_TEMPLATE.md
and anISSUE_TEMPLATE.md
to standardize the repo. If you don't want to clutter the directory, place all these files in a.github
folder (more information here).
Follow this guide, in particular:
- Use
shellcheck
, even better use it as a linter in your editor. - Use the "unofficial strict mode" everywhere (more information here).
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
- Cleanup after yourself with a
trap
, that way you can delete temporary directories, restart services or release locks whether the script stops gracefully or on an error.
cleanup() {
# ...
}
trap cleanup EXIT
- Log your scripts with this snippet (use it with
info "Executing this..."
).
You cansource Utils/scripts/sources/logger.sh
if you want it included easily.
print_date() {
date '+%d-%m-%Y %H:%M:%S'
}
readonly LOG_FILE="/tmp/$(basename "$0").log"
info() { echo "$(print_date) [INFO] $*" | tee -a "$LOG_FILE" >&2 ; }
warning() { echo "$(print_date) [WARNING] $*" | tee -a "$LOG_FILE" >&2 ; }
error() { echo "$(print_date) [ERROR] $*" | tee -a "$LOG_FILE" >&2 ; }
fatal() { echo "$(print_date) [FATAL] $*" | tee -a "$LOG_FILE" >&2 ; exit 1 ; }
- If you want to debug, run the script with
bash -x
, or addset -x
at the beginning of the script; it displays all commands being executed - If you need to use positional parameters (like
$1
,$2
...), it won't work withset -u
. You have to use parameter default value (like here)
input=${1:-} # If $1 exists, input=$1, else input=""
if [[ -z "$input" ]]; then # Test if $input is an empty string
echo "No input found"
exit 1
fi