The Huberator
I have come across more and more utilities that are hosted directly on Github and are simple binaries. As I am not thrilled at how the homebrew setup works on Linux, and other tools seemed a little heavy for my use case, I thought I would see how simple I could make something to do the same job. Below is my zsh script, which requires jq, yq, and gh to be installed.
The config file is a yaml file stored at $HOME/.config/huberator.yaml
, and it has the following structure (using hugo as an example):
repos:
- name: hugo # Name of the repo, for display only
repo: gohugoio/hugo # Github repo owner/project
version: v0.143.1 # Current, installed version. The script will change this
glob: hugo_extended_w*linux-amd64.tar.gz # Glob pattern that matches the specific asset to download from the releases page
file: hugo # Specific binary to download from the tarball
strip: 0 # Some tarballs have a leading path ./ or other path structures
The script will read each entry in the repos array, check the latest non-draft release, and compare the tag with the version
in the config file. If they do not match, it will download the tarball that matches the glob
pattern and extract the binary named file
to the $HOME/bin
directory. This makes it ideal to be added to a cron job to keep those binaries up to date.
Here is the huberator
in its entirety:
#!/bin/zsh
FN="${HOME}/.config/huberator.yaml"
if [[ ! -f $FN ]]; then
echo "repos: []" > $FN
fi
cnt=$(yq '.repos | length' $FN)
typeset -A REPO
for i in `seq $cnt`; do
export index=$((i-1))
rep=$(yq '.repos[env(index)] | "name \(.name) repo \(.repo) version \(.version) glob \"\(.glob)\" file \"\(.file)\" strip \"\(.strip // 0)\""' $FN)
eval "REPO=( $rep )"
echo -n "Checking repo ${REPO[name]}..."
version=$(gh release ls --exclude-pre-releases --exclude-drafts -L 1 -R "${REPO[repo]}" --json tagName | jq -r '.[0].tagName')
echo " published version: $version (installed is ${REPO[version]})"
if [[ "$version" != "${REPO[version]}" ]]; then
echo ".... Downloading binary ${REPO[file]}"
gh release download $version -R "${REPO[repo]}" -p "${REPO[glob]}" -O - | tar -C $HOME/bin/ --strip-components="${REPO[strip]}" -zx "${REPO[file]}"
export version
yq -i '.repos[env(index)].version=env(version)' $FN
fi
done