./task
Run any project.
The task file is a simple bash script and standardized interface for any software project.
It is to be understood as a software development pattern to standardize the installation, configuration and execution of different software frameworks.
- Package Management: Install and configure software and tools with ease.
- Docker Build: Build and publish Docker imgages for your project.
- KeePass / Pass: Store and load secrets from KeePass and pass.
- .env / dotenv: Manage multiple dotenv files for your projects.
- CI Pipelines: Simplify CI pipelines by making the executed task reproducable.
- Helper scripts: There are many examples and commands that make scripting easier.
# Specification
The specification is a short guide to set up a task file for a Python project.
Create a file task in your project.
touch task
Ensure it is executable.
chmod +x task
First add the bash shebang.
#!/usr/bin/env bash
Then append the abort on error setting.
set -e
Load environment variables from the .env file.
if [[ -a ".env" ]]; then
source .env
fi
Add a help function.
help-table() {
local -a rows
local max_cmd=7 max_opt=6 max_desc=11
rows+=("Command|Option|Description")
rows+=("help|[grep]|Show help for commands.")
rows+=("install||Setup the local environment.")
rows+=("lint||Run pre-commit and update index.html.")
rows+=("version||Show version of required tools.")
for row in "${rows[@]}"; do
IFS='|' read -r cmd opt desc <<< "$row"
(( ${#cmd} > max_cmd )) && max_cmd=${#cmd}
(( ${#opt} > max_opt )) && max_opt=${#opt}
(( ${#desc} > max_desc )) && max_desc=${#desc}
done
printf '| %-*s | %-*s | %-*s |\n' \
"$max_cmd" "Command" \
"$max_opt" "Option" \
"$max_desc" "Description"
printf '|-%*s-|-%*s-|-%*s-|\n' \
"$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \
"$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \
"$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')"
for row in "${rows[@]:1}"; do
IFS='|' read -r cmd opt desc <<< "$row"
printf '| %-*s | %-*s | %-*s |\n' \
"$max_cmd" "$cmd" \
"$max_opt" "$opt" \
"$max_desc" "$desc"
done
}
help() {
echo
if [[ -n "$1" ]]; then
help-table | grep -i "$1" | column -t -s'|'
else
echo 'task <command> [options]'
echo
echo 'commands:'
echo
help-table
fi
echo
}
Setup the command functions.
install() {
echo 'Setup venv and install python dependencies'
uv venv env
source env/bin/activate
uv pip install pre-commit
}
lint() {
source env/bin/activate
echo 'Run pre-commit'
pre-commit run --all-file
}
version() {
uv --version
}
Finish the task file with command switch cases.
if [[ "$1" == *","* ]]; then
# Split comma-separated commands
IFS=',' read -ra COMMANDS <<< "$1"
for cmd in "${COMMANDS[@]}"; do
# Trim whitespace
cmd=$(echo "$cmd" | xargs)
if declare -f "$cmd" > /dev/null; then
"$cmd"
else
echo "Unknown command: $cmd"
help
exit 1
fi
done
elif declare -f "$1" > /dev/null; then
"$1" "${@:2}"
else
case "$1" in
all)
install
lint
;;
*)
echo "Unknown command: $1"
help
exit 1
;;
esac
fi
These are the main parts of every task file script.
Now see usage on how to use the task file.
# Naming
The naming of functions is important. There are basically two styles:
- Action + Object
- Object + Action
The task file functions use the first style. The name of the function starts with an action followed by an object. The object name can be singular or plural.
Examples for actions: activate, install, dev, develop, init, build, start, update, remove, delete, enable, disable, template, convert, create, edit, change, get, set, patch, fetch, generate, push, pull, import, export, list, publish, release, test, setup, prepare, restart, stop, store, restore, translate, upgrade, zip, visualize, sync, switch, run, reset, load, dump, checkout, commit, drop, deploy, handle, trigger, render, lint, uninstall, split, parse, fix, refactor, transform, cat, ls, rm, serve, help, show, filter, login, logout, encrypt, decrypt, upload, download, analyse, transpile, compile, minify, copy
Examples for objects: env, venv, submodule, container, database, snippet, model, module, repo, mail, doc, dependency, view, user, vault, file, host, node, log, password, hash, script, requirement, part, component, system, workspace, image, process, state, platform, dir, folder, readme, overview, lang, level, request, response, result, worker, server, proxy, workflow, volume, network, package, field, value, secret, chart, node, edge, function, method, firewall, html, css, image, svg, style, query, native, group, notebook
Objects can be tools: odoo, vupress, nodejs, zsh, bash, fish, podman, kind, minikube, helm, nvim, docker, podman, rust, python, tmux, vim, helix, system, git, pass, llm, sql, dotenv, javascript, vue, vite, astro, typescript, turbo, pnpm, eslint, jenkins, k8s, nextcloud, postgres, metabase, ansible, prometheus, grafana, hugo, deno, bun, babel, panda, gulp, grunt, electron, react, express, mongodb, angular, ionic, meteor, webpack, bower, jupyter
# Style
The bash scripts follow the Bash Style Guide | ysap.sh. Have a look at the AGENTS.md for details on the applied styling.