#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2022 Patrick Spek
#
# SPDX-License-Identifier: AGPL-3.0-or-later
. "$BASHTARD_LIBDIR/util/config.bash"
. "$BASHTARD_LIBDIR/util/pkg.bash"
. "$BASHTARD_LIBDIR/util/svc.bash"
# Change the working directory. In usage, this is the same as using cd,
# however, it will make additional checks to ensure everything is going fine.
chgdir() {
debug "bashtard/chgdir" "Changing workdir to $1"
cd -- "$1" || die "Failed to change directory to $1"
}
# Create a datetime stamp. This is a wrapper around the date utility, ensuring
# that the date being formatted is always in UTC and respect SOURCE_DATE_EPOCH,
# if it is set.
datetime() {
local date_opts
# Apply SOURCE_DATE_EPOCH as the date to base off of.
if [[ $SOURCE_DATE_EPOCH ]]
then
date_opts+=("-d@$SOURCE_DATE_EPOCH")
date_opts+=("-u")
fi
date "${date_opts[@]}" +"${1:-%FT%T}"
}
# Log a message as error, and exit the program. This is intended for serious
# issues that prevent the script from running correctly. The exit code can be
# specified with -i, or will default to 1.
die() {
local OPTIND
local code
while getopts ":i:" opt
do
case "$opt" in
i) code=$OPTARG ;;
*) alert "bashtard/die" "Unused argument specified: $opt" ;;
esac
done
shift $(( OPTIND -1 ))
alert "$@"
exit "${code:-1}"
}
# Fetch a file from an URL. Using this function introduces a dependency on curl.
fetch_http() {
local OPTIND
local buffer
while getopts ":o:" opt
do
case "$opt" in
o) buffer=$OPTARG ;;
*) alert "bashtard/fetch_http" "Unused argument specified: $opt" ;;
esac
done
shift $(( OPTIND -1 ))
[[ -z $buffer ]] && buffer="$(tmpfile)"
notice "bashtard/fetch_http" "Downloading $1 to $buffer"
for util in curl wget
do
command -v "$util" > /dev/null || continue
"fetch_http_$util" "$1" "$buffer" || continue
local exit_code=$?
printf "%s" "$buffer"
return $exit_code
done
die "bashtard/fetch_http" "Unable to download file over HTTP!"
}
fetch_http_curl() {
curl -Ls "$1" > "$2"
}
fetch_http_wget() {
wget --quiet --output-document "$2" "$1"
}
# Check if the first argument given appears in the list of all following
# arguments.
in_args() {
local needle="$1"
shift
for arg in "$@"
do
[[ $needle == "$arg" ]] && return 0
done
return 1
}
# Join a list of arguments into a single string. By default, this will join
# using a ",", but you can set a different character using -c. Note that this
# only joins with a single character, not a string of characters.
join_args() {
local OPTIND
local IFS=","
while getopts ":c:" opt
do
case "$opt" in
c) IFS="$OPTARG" ;;
*) warn "bashtard/join_args" "Unused opt specified: $opt" ;;
esac
done
shift $(( OPTIND - 1))
printf "%s" "$*"
}
file_template()
{
local file="$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/share/$1" ; shift
local sedfile
sedfile="$(tmpfile)"
if [[ ! -f $file ]]
then
crit "bashtard/template" "Tried to render template from $file, but it doesn't exist"
return
fi
for kv in "$@"
do
debug "bashtard/template" "Adding $kv to sedfile at $sedfile"
key="$(awk -F= '{ print $1 }' <<< "$kv")"
if [[ -z "$key" ]]
then
crit "bashtard/template" "Empty key in '$kv' while rendering $file?"
fi
value="$(awk -F= '{ print $NF }' <<< "$kv")"
if [[ -z "$value" ]]
then
crit "bashtard/template" "Empty key in '$kv' while rendering $file?"
fi
# shellcheck disable=SC2016
printf 's@${%s}@%s@g\n' "$key" "$value" >> "$sedfile"
done
sed -f "$sedfile" "$file"
}
# Create a temporary directory. Similar to tempfile, but you'll get a directory
# instead.
tmpdir() {
local dir
dir="$(mktemp -d)"
# Ensure the file was created succesfully
if [[ ! -d "$dir" ]]
then
die "bashtard/tmpdir" "Failed to create a temporary directory at $dir"
fi
debug "bashtard/tmpdir" "Temporary file created at $dir"
printf "%s" "$dir"
}
# Create a temporary file. In usage, this is no different from mktemp itself,
# however, it will apply additional checks to ensure everything is going
# correctly, and the files will be cleaned up automatically at the end.
tmpfile() {
local file
file="$(mktemp)"
# Ensure the file was created succesfully
if [[ ! -f "$file" ]]
then
die "bashtard/tmpfile" "Failed to create a temporary file at $file"
fi
debug "bashtard/tmpfile" "Temporary file created at $file"
printf "%s" "$file"
}