aboutsummaryrefslogtreecommitdiff
path: root/lib/util.bash
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util.bash')
-rw-r--r--lib/util.bash135
1 files changed, 101 insertions, 34 deletions
diff --git a/lib/util.bash b/lib/util.bash
index 6ad69e1..ad84247 100644
--- a/lib/util.bash
+++ b/lib/util.bash
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-# SPDX-FileCopyrightText: 2022 Patrick Spek <p.spek@tyil.nl>
+# SPDX-FileCopyrightText: 2023 Patrick Spek <p.spek@tyil.nl>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -18,6 +18,11 @@ chgdir() {
cd -- "$1" || die "Failed to change directory to $1"
}
+# Removes whitespace surrounding a given text.
+chomp() {
+ awk '{$1=$1};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.
@@ -56,6 +61,26 @@ die() {
exit "${code:-1}"
}
+# Recursively hash files in a directory, and hashing the output of all those
+# hashes again. This results in a single hash representing the state of files
+# in a directory. It can be used to check whether contents changed after
+# templating files in a given directory.
+dir_hash() {
+ local path
+
+ path="$1" ; shift
+
+ for entry in "$path"/*
+ do
+ if [[ -d "$entry" ]]
+ then
+ dir_hash "$entry"
+ fi
+
+ file_hash "$entry"
+ done | file_hash -
+}
+
# Fetch a file from an URL. Using this function introduces a dependency on curl.
fetch_http() {
local OPTIND
@@ -96,45 +121,35 @@ 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
+# Hash a given file. This is a convenience function to work around different
+# systems calling their file hashing programs differently, and generating
+# different output. This function only expects 1 file as argument, and only
+# outputs the hash of this particular file.
+file_hash() {
+ file_hash_md5 "$@"
}
-# 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
+file_hash_md5() {
+ local file
- shift $(( OPTIND - 1))
+ file="$1" ; shift
- printf "%s" "$*"
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) md5 "$file" | awk '{ print $NF }' ;;
+ linux-*) md5sum "$file" | awk '{ print $1 }' ;;
+ esac
}
+# A very simple means of templating a file, using sed and awk. The template
+# file is assumed to exist within the share directory of the current playbook.
+# Variables are passed as key=value pairs to this function. Inside the
+# template, they are expected to be written as ${key}.
file_template()
{
- local file="$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/share/$1" ; shift
+ local file
local sedfile
+ file="$(playbook_path "base")/share/$1" ; shift
sedfile="$(tmpfile)"
if [[ ! -f $file ]]
@@ -147,18 +162,18 @@ file_template()
do
debug "bashtard/template" "Adding $kv to sedfile at $sedfile"
- key="$(awk -F= '{ print $1 }' <<< "$kv")"
+ key="$(cut -d'=' -f -1 <<< "$kv")"
if [[ -z "$key" ]]
then
- crit "bashtard/template" "Empty key in '$kv' while rendering $file?"
+ crit "bashtard/template" "Empty key in '$kv' while rendering $file"
fi
- value="$(awk -F= '{ print $NF }' <<< "$kv")"
+ value="$(cut -d'=' -f 2- <<< "$kv")"
if [[ -z "$value" ]]
then
- crit "bashtard/template" "Empty key in '$kv' while rendering $file?"
+ crit "bashtard/template" "Empty key in '$kv' while rendering $file"
fi
# shellcheck disable=SC2016
@@ -168,6 +183,58 @@ file_template()
sed -f "$sedfile" "$file"
}
+# 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" "$*"
+}
+
+# Convenience function to easily get paths used by the playbook, or to use in
+# your playbook.
+playbook_path() {
+ if [[ -z "$BASHTARD_PLAYBOOK" ]]
+ then
+ crit "bashtard/playbook_path" "Called outside of a playbook"
+ return 1
+ fi
+
+ case "$1" in
+ base) printf "%s/playbooks.d/%s" "$BASHTARD_ETCDIR" "$BASHTARD_PLAYBOOK" ;;
+ data) printf "%s/data.d/%s" "$BASHTARD_ETCDIR" "$BASHTARD_PLAYBOOK" ;;
+ *)
+ crit "bashtard/playbook_path" "Invalid path '$1'"
+ return 1
+ esac
+}
+
# Create a temporary directory. Similar to tempfile, but you'll get a directory
# instead.
tmpdir() {