summaryrefslogtreecommitdiffstats
path: root/contrib/util.sh
diff options
context:
space:
mode:
authorLibravatarLarge Libravatar memdmp <memdmpmemewarenet>2025-01-13 16:54:34 +0100
committerLibravatarLarge Libravatar memdmp <memdmpmemewarenet>2025-01-13 16:54:34 +0100
commit6e3b3c8013e6d8814dbf70c854e55d062bedbdf4 (patch)
tree5b07a6d26c349293bc61a71a32d6e368fed11c4e /contrib/util.sh
downloadbibata-cursor-cli-master.tar.gz
bibata-cursor-cli-master.tar.bz2
bibata-cursor-cli-master.tar.lz
bibata-cursor-cli-master.zip

chore: initial commit

HEADmaster
Diffstat (limited to 'contrib/util.sh')
-rw-r--r--contrib/util.sh215
1 files changed, 215 insertions, 0 deletions
diff --git a/contrib/util.sh b/contrib/util.sh
new file mode 100644
index 0000000..5f846be
--- /dev/null
+++ b/contrib/util.sh
@@ -0,0 +1,215 @@
+#!/bin/bash
+set -e
+
+# Logging
+TASKS=()
+_last() {
+ echo -n "${TASKS[0]}"
+}
+start() {
+ for n in "${TASKS[@]}"; do
+ echo -n ' '
+ done
+ TASKS=(
+ "$@"
+ "${TASKS[@]}"
+ )
+ echo -e "\x1b[0;1;34m@\x1b[0;34m $@\x1b[0m"
+}
+complete() {
+ last="$(_last)"
+ if [[ "$NOSHIFT" != 1 ]]; then
+ TASKS=(
+ "${TASKS[@]:1}"
+ )
+ fi
+ if [[ "$1" == "" ]] && [[ "$last" != "" ]]; then
+ NOSHIFT=1 complete "$last"
+ else
+ for n in "${TASKS[@]}"; do
+ echo -n ' '
+ done
+ echo -e "\x1b[0;1;32m+\x1b[0;32m $@\x1b[0m"
+ fi
+}
+err() {
+ last="$(_last)"
+ if [[ "$NOSHIFT" != 1 ]]; then
+ TASKS=(
+ "${TASKS[@]:1}"
+ )
+ fi
+ if [[ "$1" == "" ]] && [[ "$last" != "" ]]; then
+ NOSHIFT=1 err "$last"
+ else
+ for n in "${TASKS[@]}"; do
+ echo -n ' '
+ done
+ echo -e "\x1b[0;1;31m!\x1b[0;31m $@\x1b[0m" 1>&2;
+ fi
+}
+info() {
+ echo -e "\x1b[0;1;94mi\x1b[0;94m $@\x1b[0m" 1>&2;
+}
+
+# Bash Array Joiner
+join_array() {
+ printf -v __ "${1//%/%%}%s" "${@:2}"
+ echo -n "${__:${#1}}"
+}
+
+# jq abstraction layer
+
+# Determines where to store the JSON - if the value is `IN_MEM`, then the value is kept in the JQ_BUFFER variable
+JSON_STORAGE_LOCATION="IN_MEM"
+JQ_BUFFER=""
+JQ_BUFFER_OUTPUT_FILE=""
+JQ_TRANSACTION=()
+JQ_IS_DOING_TRANSACTION=false
+JQ_POSITIONALS=()
+JQ_POSITIONAL_IDX=1
+ARG=null
+jsettempstorage() {
+ newstorage="${1:-"IN_MEM"}"
+ if [[ "$newstorage" == "$JSON_STORAGE_LOCATION" ]]; then return 0; fi
+ if [[ "$JSON_STORAGE_LOCATION" == "IN_MEM" ]]; then
+ touch "$newstorage"
+ <<< "$JQ_BUFFER" > "$newstorage"
+ JQ_BUFFER=""
+ elif [[ "$newstorage" == "IN_MEM" ]]; then
+ JQ_BUFFER="$(<"$JSON_STORAGE_LOCATION")"
+ rm "$JSON_STORAGE_LOCATION"
+ else
+ mv "$JSON_STORAGE_LOCATION" "$newstorage"
+ fi
+ JSON_STORAGE_LOCATION="$newstorage"
+}
+# Reads the storage buffer
+jreadbuffer() {
+ if [[ "$JSON_STORAGE_LOCATION" == "IN_MEM" ]]; then
+ echo -n "$JQ_BUFFER"
+ else
+ cat "$JSON_STORAGE_LOCATION"
+ fi
+}
+# Writes the storage buffer
+jwritebuffer() {
+ if [[ "$JSON_STORAGE_LOCATION" == "IN_MEM" ]]; then
+ JQ_BUFFER="$@"
+ else
+ echo -n "$@" > "$JSON_STORAGE_LOCATION"
+ fi
+}
+
+# Creates a new jq blank file
+jnew() {
+ JQ_BUFFER_OUTPUT_FILE="$(realpath "${1:-"/dev/null"}")"
+ jwritebuffer "${2:-"{}"}"
+}
+# Loads an existing jq file, falling back to creating a blank one if it doesnt exist
+jload() {
+ JQ_BUFFER_OUTPUT_FILE="$(realpath "${1:-"/dev/null"}")"
+ if [[ -f "$JQ_BUFFER_OUTPUT_FILE" ]]; then
+ jwritebuffer "$(cat $JQ_BUFFER_OUTPUT_FILE)"
+ else
+ jwritebuffer "${2:-"{}"}"
+ fi
+}
+
+# SQL-like Transaction Logic
+jtransaction() {
+ if [[ "$JQ_IS_DOING_TRANSACTION" == "true" ]]; then
+ err "Already performing transaction!"
+ return 1
+ fi
+ JQ_IS_DOING_TRANSACTION=true
+ JQ_TRANSACTION=()
+}
+jabort() {
+ if [[ "$JQ_IS_DOING_TRANSACTION" == "false" ]]; then
+ err "No pending transaction!"
+ return 1
+ fi
+ JQ_IS_DOING_TRANSACTION=false
+ JQ_TRANSACTION=()
+}
+jcommit() {
+ if [[ "$JQ_IS_DOING_TRANSACTION" == "false" ]]; then
+ err "No pending transaction!"
+ return 1
+ fi
+ JQ_IS_DOING_TRANSACTION=false
+ # Incase it's empty:
+ JQ_TRANSACTION+=(
+ "."
+ )
+ # As we are no longer in a transaction, jrun will run the pipe-delimited query
+ jrun "$(join_array ' | ' "${JQ_TRANSACTION[@]}")"
+ # We can, after running, clear the transaction
+ JQ_TRANSACTION=()
+}
+
+# Loads a string that jq can positionally access later
+jsetasset() {
+ ARG="(\$ARGS.positional[$JQ_POSITIONAL_IDX] | @base64d)"
+ JQ_POSITIONALS+=(
+ "$(base64 -w 0 <<< "$@")"
+ );
+ ((JQ_POSITIONAL_IDX=JQ_POSITIONAL_IDX+1))
+}
+jgetassetref() {
+ echo -n "$ARG"
+ ARG=null
+}
+
+# Perform a jq write operation
+jrun() {
+ if [[ "$JQ_IS_DOING_TRANSACTION" == "true" ]]; then
+ # If we're in a transaction, just push it to the list
+ JQ_TRANSACTION+=(
+ "($@)"
+ )
+ else
+ # Otherwise, perform the operation and write to the buffer
+ if [[ "$JSON_STORAGE_LOCATION" == "IN_MEM" ]]; then
+ JQ_BUFFER="$(jq -Mc "$@" --args owo ${JQ_POSITIONALS[@]} <<< "$JQ_BUFFER")"
+ else
+ jq -Mc "$@" --args owo ${JQ_POSITIONALS[@]} < "$JSON_STORAGE_LOCATION" > "$JSON_STORAGE_LOCATION~"
+ mv "$JSON_STORAGE_LOCATION~" "$JSON_STORAGE_LOCATION"
+ fi
+ JQ_POSITIONALS=()
+ JQ_POSITIONAL_IDX=1
+ fi
+}
+# Perform a jq write operation using a temp file
+_jrun_file() {
+ if [[ "$JQ_IS_DOING_TRANSACTION" == "true" ]]; then
+ # Does not work for transactions
+ err "Cannot use _jrun_file in transaction!";
+ return 1;
+ else
+ # Otherwise, perform the operation and write to the buffer
+ if [[ "$JSON_STORAGE_LOCATION" == "IN_MEM" ]]; then
+ echo -n "$@" > /tmp/.operation.jq
+ JQ_BUFFER="$(jq -Mcf /tmp/.operation.jq --args owo ${JQ_POSITIONALS[@]} <<< "$JQ_BUFFER")"
+ rm /tmp/.operation.jq
+ else
+ echo -n "$@" > /tmp/.operation.jq
+ jq -Mcf /tmp/.operation.jq --args owo ${JQ_POSITIONALS[@]} < "$JSON_STORAGE_LOCATION" > "$JSON_STORAGE_LOCATION~"
+ rm /tmp/.operation.jq
+ mv "$JSON_STORAGE_LOCATION~" "$JSON_STORAGE_LOCATION"
+ fi
+ JQ_POSITIONALS=()
+ JQ_POSITIONAL_IDX=1
+ fi
+}
+jsave() {
+ if [[ "$JQ_IS_DOING_TRANSACTION" == "true" ]]; then
+ err "There is a pending transaction."
+ return 1
+ fi
+ jreadbuffer | jq -M . > "${1:-"$JQ_BUFFER_OUTPUT_FILE"}"
+}
+escape_str() {
+ jq '.=$ARGS.positional[0]' --args "$@" -M <<< '""'
+}