Last active
April 18, 2025 03:06
-
-
Save goliatone/d136377d7768acf6960f7cceefb8a24e to your computer and use it in GitHub Desktop.
Taskfile template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Check for -debug flag | |
if [[ $* == *-debug* ]]; then | |
set -x | |
fi | |
export LGR_NO_TIMESTAMP=true | |
VERSION_FILE="./.version" | |
# If we have a .taskenv file load it as source | |
# the file should be e.g. | |
# #!/bin/bash | |
# export DATABASE_URL="..." | |
if [ -f .taskenv ]; then | |
# shellcheck disable=SC1091 | |
source .taskenv | |
fi | |
# This makes all bin packages installed via npm available here | |
# e.g. bogota, nyc, autocannon, etc. | |
PATH=$(pwd)/node_modules/.bin:$PATH | |
# This will make all scripts available in the ./src/bin directory | |
PATH=$(pwd)/src/bin:$PATH | |
################################################# | |
# Development dependencies | |
################################################# | |
function _install:lgr { | |
mkdir -p bin | |
if hash lgr 2>/dev/null; then | |
lgr OK "lgr already installed..." | |
else | |
if [[ $(command -v brew) == "" ]]; then | |
echo "Installing lgr" | |
brew tap goliatone/homebrew-tap | |
brew install lgr | |
lgr OK "lgr installed..." | |
else | |
LGR_VERSION="0.1.1" | |
LGR_FILENAME="lgr_${LGR_VERSION}_linux_x86_64.tar.gz" | |
curl -sL "https://github.com/goliatone/lgr/releases/download/v${LGR_VERSION}/${LGR_FILENAME}" | tar xz | |
chmod +x lgr | |
lgr OK "lgr installed" | |
fi | |
fi | |
} | |
function _install:changelog { | |
if git-cliff lgr 2>/dev/null; then | |
lgr OK "git-cliff already installed..." | |
else | |
echo "Installing lgr" | |
brew install brew install orhun/git-cliff/git-cliff | |
lgr OK "git-cliff installed..." | |
fi | |
} | |
function _install:brew { | |
if [[ $(command -v brew) == "" ]]; then | |
lgr I "Installing Hombrew" | |
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" | |
else | |
lgr I "Updating Homebrew" | |
brew update | |
fi | |
} | |
function _install:envset { | |
if hash envset 2>/dev/null; then | |
lgr OK "envset installed..." | |
else | |
lgr I "Installing envset..." | |
brew install envset | |
lgr OK "envset installed..." | |
fi | |
} | |
function lgr { | |
if command -v lgr >/dev/null 2>&1; then | |
command lgr "$@" | |
else | |
echo "$@" # fallback to plain echo | |
fi | |
} | |
########################################## | |
# Application management | |
########################################## | |
function dev:install { | |
cd "$(pwd)/src" || exit "$?" | |
_install:lgr | |
_install:brew | |
_install:envset | |
_install:changelog | |
lgr ok "dependencies intalled..." | |
} | |
function dev:env:load { | |
eval "$(envset development --isolated=true)" | |
} | |
## | |
## ######################################## | |
## Version Management | |
## ######################################## | |
## | |
## ----- | |
## | |
## version:upsert | |
## | |
## Save version to meta file. | |
## First time will create file if not present | |
## | |
## Arguments: | |
## @arg 1 {string} [tag=0.0.1] | |
function version:upsert { | |
local tag=${1} | |
if [ -z "$tag" ]; then | |
version:get | |
else | |
version:set "$tag" | |
version:get | |
fi | |
} | |
## | |
## ----- | |
## | |
## version:get | |
## | |
## Get version from meta file. | |
function version:get { | |
test -f "${VERSION_FILE}" || touch "${VERSION_FILE}" | |
local tag | |
tag=$(cat "${VERSION_FILE}") | |
if [ -z "$tag" ]; then | |
tag="0.0.1" | |
version:set "$tag" | |
fi | |
echo -n "$tag" | |
} | |
## | |
## ----- | |
## | |
## version:set | |
## | |
## Set and save version to meta file. | |
## First time will create file if not present. | |
## | |
## Arguments: | |
## @arg 1 {string} [tag=0.0.1] | |
function version:set { | |
local tag | |
tag=${1} | |
if [ -z "$tag" ]; then | |
exit 1 | |
fi | |
version:check | |
echo -e "$tag" > "${VERSION_FILE}" | |
} | |
## | |
## ----- | |
## | |
## version:bump | |
## Bump sem ver by specifying a level. | |
## Valid levels are: | |
## - patch (default) | |
## - minor | |
## - major | |
## | |
## If you want to update the .version file | |
## pass the `--write` flag. | |
## @see https://github.com/fsaintjacques/semver-tool/blob/master/src/semver | |
## | |
## @arg 1 {string} [level=patch] | |
## Outputs: | |
## Semver string "$major.$minor.$patch" | |
## | |
## @flag --write Will write to .version file | |
## | |
function version:bump { | |
version:check | |
# Default values | |
level='patch' | |
write_to_file=0 | |
# Parse options | |
while [[ "$#" -gt 0 ]]; do | |
case $1 in | |
--write) | |
write_to_file=1 | |
shift | |
;; | |
patch|minor|major) | |
level=$1 | |
shift | |
;; | |
*) | |
echo "Invalid option: $1" | |
return 2 | |
;; | |
esac | |
done | |
# Read contents of version and store in | |
IFS='.' read -ra identifiers < "$VERSION_FILE" | |
[[ "${#identifiers[@]}" -ne 3 ]] && echo "Invalid semver string" && return 1 | |
patch=${identifiers[2]} | |
minor=${identifiers[1]} | |
major=${identifiers[0]} | |
case $level in | |
patch) | |
patch=$((patch+1)) | |
;; | |
minor) | |
minor=$((minor+1)) | |
patch=0 | |
;; | |
major) | |
major=$((major+1)) | |
minor=0 | |
patch=0 | |
;; | |
*) | |
echo "Invalid level passed" | |
return 2 | |
esac | |
new_version="$major.$minor.$patch" | |
if [[ $write_to_file -eq 1 ]]; then | |
echo "$new_version" > "${VERSION_FILE}" | |
else | |
echo "$new_version" | |
fi | |
} | |
function version:check { | |
if [ ! -f "$VERSION_FILE" ]; then | |
echo "0.0.0" > "$VERSION_FILE" | |
fi | |
} | |
## | |
## ----- | |
## | |
## release | |
## | |
## Bump our current version, create a git tag | |
## and push to trigger our release flow. | |
## | |
## Arguments: | |
## @arg 1 {string} [level=patch] | |
## Accepted major, minor, patch | |
function release { | |
local tag | |
local level | |
local message | |
# Fetch all changes from origin | |
git fetch --all | |
if [ -f ".version" ]; then | |
# Make sure we have the latest version file | |
git checkout origin/main -- ".version" | |
else | |
lgr I "File .version does not exist. Skipping." | |
fi | |
# Pull tags to make sure we have | |
git pull --tags -f | |
level=${1:-"patch"} | |
# Bump our version | |
tag=$(version:bump "${level}") | |
# Set message: default to New major|minor|patch release: vx.x.x | |
message=${2:-"New ${level} release: v${tag}"} | |
lgr I "$message" | |
# Update version file | |
version:set "${tag}" | |
# Add updated version file to git | |
git add "${VERSION_FILE}" | |
git commit -m "Bump version: v${tag}" | |
# Create a new tag | |
git tag -a "v${tag}" -m "${message}" | |
# Push tags and trigger release 🚀 🥳 | |
git push --tags | |
git push | |
# Generate changelog | |
git cliff --output CHANGELOG.md | |
git add CHANGELOG.md | |
git commit -m "docs: update changelog for v${tag}" | |
git push | |
lgr OK "We released v${tag} 🚀 🥳" | |
} | |
########################################## | |
# Help and auxiliary functions | |
########################################## | |
## Show function code | |
function help:show { | |
declare -f "$1" | |
} | |
function help { | |
echo "" | |
echo "$0 <task> [...arguments]" | |
echo "" | |
echo "Project: ${PROJECT}" | |
echo "" | |
echo "Tasks:" | |
compgen -A function | grep -v '^_' | cat -n | |
echo "" | |
prog="$0" | |
me=$(basename "$prog") | |
grep -e '^##[[:space:]]' -e '^##$' "$prog" | sed -e 's/^##//' -e "s/_PROG_/$me/" 2>&1 | less | |
} | |
TIMEFORMAT="Task completed in %3lR" | |
time "${@:-help}" |
have a way to mark a task as "singleton" and implement a sort of lock file we check before running the task, to prevent to run the same task concurrently, e.g. i run server:fresh
which drops the database and then runs the server, then in another window I use up arrow to bring a cmd and mistakenly autocomplete to the wrong command, which could drop the db
have a simple wrapper to run these task files. taskrun
- which would download the task from gist
- would run an specific command
- could be used to parse help from a given task
Use this to get the latest tag for logger:
LATEST_TAG=$(curl -s https://api.github.com/repos/goliatone/lgr/releases/latest | jq -r .tag_name)
LGR_FILENAME="lgr_${LGR_VERSION}_linux_x86_64.tar.gz"
curl -sL "https://github.com/goliatone/lgr/releases/download/v${LGR_VERSION}/${LGR_FILENAME}" | tar xz
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this to
.zshrc