Bli kvitt lange terminalstrofer

· 579 ord · 3 min å lese

Å skrive lange kommandoer i terminalen er repetitivt og kjedelig. Så klart kan du bruke den gode gamle Makefilen eller en egetskrevet CLI, men ellers takk. Som en mellomting bruker jeg heller en Taskfile!

Introduksjon av problemstillingen 🔗

Problemstillingen er som følger: du skal bygge og kjøre opp en docker-compose-stack i bakgrunnen med spesifisert .env-fil, en egen development-override, og en egen debug profil. Dette resulterer i en nokså drøy strofe som får fingrene og hukommelsen til å grøsse 😵‍💫

#!/bin/bash
docker-compose -f docker-compose.debug.yml --env-file .env.dev -p debug up -d --build

Ellers takk til alternativet over. Ofte blir løsningen å heller putte denne typen skript i mappen scripts™️ i rota av repoet vårt. Dette fungerer erfaringsmessig godt i starten av prosjektet, men blir kjipt når nye og varianter av gamle skript introduseres. Enda verre er det når du bestemmer deg for å endre navnet på en eller annen yaml-fil, og må gå gjennom hvert skript for å endre. Huff og gru.

Så det nye alternativet bør kunne:

  • Korte ned kommandoer i terminal
  • Gjenbruke uttrykk så endringen skjer på kun et sted.
  • Gi oversikt over tilgjengelige skript

Løsningen Taskfile 🔗

En løsning er å bruke konseptet Makefile fra C-verdenen til å definere kommandoene våre. Dette er et populært og solid alternativ, men kanskje ikke like god på:

  • Oversikt over skript
    • Selvdokumenterende
    • Fargebruk i terminal (valgfritt) 🌈
  • Utvidelse og gjenbruk (subjektivt?)

Så nok prat, la oss komme til løsningen, Taskfile (av adriancooney). Skriptet under er alt du trenger for å komme i gang.

#!/bin/bash
set -eo pipefail

# Taskfile idea inspired from https://github.com/adriancooney/Taskfile
# Incase of running `source ./Taskfile` instead of `./Taskfile`
FILENAME="${0}"
if [ "$0" == "/bin/bash" ]; then FILENAME="./Taskfile"; fi

# TERMINAL COLOR PALETTE
RED=$(tput setaf 1)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
BOLD=$(tput bold)
CLEAR=$(tput sgr0)

function _dc_dev {
    ENV_FILE=".env.dev" \
    docker-compose \
    --env-file .env.dev \
    "${@}"
}

function up { ## Start up services
    _dc_dev up "${@}"
}

function down { ## Shut down services
    _dc_dev down "${@}"
}

function --help {
    help
}
function help { ## Display commands and usage
    printf "${RED}No command provided. Displaying help utility:\n${BOLD}${BLUE}\nUsage:"
    printf "${CLEAR}\t${FILENAME} COMMAND [ARGS/OPTIONS]\n\n"
    printf "${BOLD}${BLUE}%-30s${BLUE}%s\033[0m\n" "Commands" "Description"

    # Formatting inspired from https://gist.github.com/tvalladon/e316bee4b58ca082d2190be023565949
    grep -E '^function [a-zA-Z:_-]+ {.*?## .*$$' "${FILENAME}" |
        sed -e 's/function //' | sort |
        grep -v "^_" |
        awk 'BEGIN {FS = "{.*?## "}; {printf "%-30s%s\033[0m\n", $1, $2}'
    printf "\n"
}

TIMEFORMAT="${BOLD}${BLUE}(Task completed in %3lR)"
time "${@:-help}"

Kjøring av Taskfile 🔗

taskfile-demonstration

Gi videre tilgang til å kjøre filen, og et valgfritt alias (anbefaler å putte disse i postCreateCommand i devcontainer):

chmod u+x ./Taskfile

# om du ønsker et kortere alias
alias run=./Taskfile

Kjør ./Taskfile for å få en oversikt over tilgjengelige skript.

./Taskfile

Kjør definerte kommandoer ved å skrive f.eks:

./Taskfile up

# og med flere flagg
./Taskfile up -d --build

Forklaring av filen 🔗

Dokumentasjon og oversikt skapes vha. funksjonen help() som bruker grep og litt flittig filtrering til å hente ut funksjoner som ikke starter med “_” og deres tilhørende dokumentasjonssnutt etter “##”.

Gjenbruk kan gjøres på vanlig måte i bash-skript. Funksjoner som starter med karakteren “_” tas ikke med i oversikten og kan derfor brukes til å abstrahere ut uttrykk.

Farge defineres av brukeren selv vha. printf og tput. En OBS! er at visse terminaler ikke “liker” farger (f.eks. GitHub Actions), du kan da være nødt å skrive:

TERM=xterm bash ./Taskfile <din kommando>

Til ettertanke 🔗

Om du også bruker VSCode kan du kombinere en Taskfile med VSCodes settings/tasks.json. Da slipper du å låse deg til en editor, får integrasjon mot VSCode, og kan gjenbruke de allerede definerte oppgavene i CI/CD-pipelines.

Kanskje kunne man også lage et eget skript som automatisk lager en tasks.json ut i fra Taskfilen vår 🤔