2025-01-17 08:03:19 +01:00
2025-01-17 08:01:29 +01:00
2025-01-16 10:21:52 +01:00
2025-01-17 08:01:29 +01:00
2025-01-16 10:38:40 +01:00
2025-01-16 10:38:40 +01:00
2025-01-18 14:17:39 +01:00
2025-01-18 14:17:39 +01:00

layout, permalink
layout permalink
layouts/base.njk /

task

Run any project.

The task file is a simple bash script and standardized interface for all software projects.

It is to be understood as a software development pattern to standardize the installation, configuration and execution of different software frameworks.

Specification

The specification is a short guide to setting 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.
#!/bin/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.
function help() {
    echo
    echo "task <command> [options]"
    echo
    echo "commands:"
    echo

    # Define column widths
    cmd_width=10
    opt_width=6
    desc_width=40

    # Print table header
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "Command" "Option" "Description"
    echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|"

    # Print table rows
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "all" "" "Run all tasks."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install" "" "Setup the local environment."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "lint" "" "Run pre-commit and update index.html."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "source" "" "Source the Python virtual env."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "version" "" "Show version of required tools."

    echo
}
  • Setup the command functions.
function version() {
    uv --version
}

function install() {
    echo "Setup venv and install python dependencies"
    uv venv env
    source env/bin/activate
    uv pip install pre-commit
}

function lint() {
    source env/bin/activate

    echo "Run pre-commit"
    pre-commit run --all-file
}
  • Finally finish the file with command switch cases.
if declare -f "$1" > /dev/null; then
    "$1" "${@:2}"
else
    case "$1" in
        all)
            install
            lint
            ;;
        source)
            source env/bin/activate
            ;;
        *)
            echo "Unknown command: $1"
            help
            exit 1
            ;;
    esac
fi

Usage

Running the task file requires a shell alias: alias task='./task'

Show the available commands with task help.

From the specification the project can be installed with task install.

To source the Python environment run source task source.

Execute all commands with task all.

Completion

With the output of task help the task commands can be completed.

Completion for bash: /etc/bash_completion.d/task_completions

#!/bin/bash

_task_completions() {
    local cur prev commands
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    commands=$(./task help | grep -A999 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr '\n' ' ')

    if [[ ${COMP_CWORD} == 1 ]]; then
        COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
    elif [[ ${COMP_CWORD} == 2 ]]; then
        COMPREPLY=( $(compgen -f -- "${cur}") )
    else
        COMPREPLY=()
    fi
}

complete -F _task_completions task

Completion for zsh: ~/.oh-my-zsh/completions/_task

#compdef task

_arguments '1: :->tasks' '*: :_files'

case "$state" in
    tasks)
        args=$(./task help | grep -A999 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr '\n' ' ')
        args="$args help"
        _arguments "1:profiles:($args)"
        ;;
esac

Examples

This website is built with a task file. Here is the source:

#!/bin/bash
set -e

function help() {
    echo
    echo "task <command> [options]"
    echo
    echo "commands:"
    echo

    # Define column widths
    cmd_width=10
    opt_width=6
    desc_width=40

    # Print table header
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "Command" "Option" "Description"
    echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|"

    # Print table rows
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "all" "" "Run all tasks."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install" "" "Install node packages."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "dev" "" "Run 11ty server."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "build" "" "Build the 11ty website."
    printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "version" "" "Show version of required tools."

    echo
}


function install() {
    npm install
}

function dev() {
    npx eleventy --serve
}

function build() {
    npx eleventy
}

function version() {
    echo "eleventy: $(npx eleventy --version)"
}

if declare -f "$1" > /dev/null; then
    "$1" "${@:2}"
else
    case "$1" in
        all)
            install
            build
            ;;
        *)
            echo "Unknown command: $1"
            help
            exit 1
            ;;
    esac
fi

Source: janikvonrotz/taskfile.build

More examples of task files can be accessed from these projects:

S
Description
No description provided
Readme AGPL-3.0
1.3 MiB
0 Stars 1 Watchers 0 Forks
Languages
Shell 99.5%
Dockerfile 0.5%