From f729bedc9993d3075b72d98e82cd91cd193ef944 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Sun, 5 Oct 2025 15:21:50 -0400 Subject: [PATCH] feat: Adds logging script as a general logging utility to not pollute console for TUI's for example. Updated gen script to put it into newly generated scripts, need to update existing scripts to use it. --- env/.config/hypr/windows.conf | 10 +- env/.local/scripts/hypr/logging | 134 +++++++++++++++++++++++++ env/.local/scripts/hypr/utils-launcher | 34 ++++--- gen | 49 ++++++--- 4 files changed, 196 insertions(+), 31 deletions(-) create mode 100755 env/.local/scripts/hypr/logging diff --git a/env/.config/hypr/windows.conf b/env/.config/hypr/windows.conf index 5f367dc..1ea9f4a 100644 --- a/env/.config/hypr/windows.conf +++ b/env/.config/hypr/windows.conf @@ -17,14 +17,18 @@ windowrule = size 90% 80%, class:^(com.ghostty.weather)$ # Force windows to be a floating window windowrule = tag +floating-window, class:^(blueberry.py|org.gnome.Nautilus|com.ghostty.float)$ -windowrule = tag +floating-window, class:^(com.ghostty.utils-launcher)$ +# windowrule = tag +floating-window, class:^(com.ghostty.utils-launcher)$ # Force to stay focused when visible. windowrule = stayfocused, class:(blueberry.py) windowrule = stayfocused, class:Pinentry.gtk windowrule = stayfocused, class:com.ghostty.float -windowrule = stayfocused, class:com.ghostty.utils-launcher -# windowrule = stayfocused, class:.*pass.proton.me.* + +# Utils-Launcher +windowrule = stayfocused, class:^(com.ghostty.utils-launcher)$ +windowrule = float, class:^(com.ghostty.utils-launcher)$ +windowrule = center, class:^(com.ghostty.utils-launcher)$ +windowrule = size 80% 80%, class:^(com.ghostty.utils-launcher)$ # Clipboard history tui in floating window. windowrule = tag +floating-window, class:.*clipse.* diff --git a/env/.local/scripts/hypr/logging b/env/.local/scripts/hypr/logging new file mode 100755 index 0000000..6273039 --- /dev/null +++ b/env/.local/scripts/hypr/logging @@ -0,0 +1,134 @@ +#!/usr/bin/env bash + +# Basic logging utility functions that can be used by scripts to log +# to files. This helps keep console clean for TUI's. Will log +# messages to all registered files, which allows each script to +# declare their own logging file, but also print logs into parent +# processes files, for ease of discovery. +# +# Supports warning and error flags. +# +# Errors and warnings get logged to the file and to the console. +# +# +# EXAMPLE SETUP: +# +# source $SCRIPTS/hypr/logging +# THIS=$(basename ${BASH_SOURCE[0]}) +# +# # Setup logging file and label. +# setup-logging "/tmp/$THIS.log" $THIS +# +# function log() { +# logging log --source ${BASH_SOURCE[0]} "$@" +# } +# +# log "My log message." +# log --warning "My warning message." +# log --error "My error message." +# + +LOG_FILE=(${LOG_FILE:-}) +LOG_INVOCATION_ID=${LOG_INVOCATION_ID:-} +LOG_LABEL=(${LOG_LABEL:-}) +SCRIPTS=${SCRIPTS:-$HOME/.local/scripts} + +warn_flag="0" +error_flag="0" + +__msg() { + if [[ -z "$@" ]]; then + echo -e "\e[31m[ERROR]:\e[0m No logs were supplied." + exit 1 + fi + if [[ $warn_flag == "1" ]]; then + echo -e "\e[33m[WARN]:\e[0m $@" + elif [[ $error_flag == "1" ]]; then + echo -e "\e[31m[ERROR]:\e[0m $@" + else + echo "$@" + fi +} + +__ensure_setup() { + if [[ -z $LOG_FILE ]] || [[ -z $LOG_INVOCATION_ID ]] || [[ -z $LOG_LABEL ]]; then + echo -e "\e[31m[ERROR]:\e[0m Logging is not properly setup." + echo "Perhaps you didn't call 'setup-logging' first." + print_logger_env && exit 1 + fi +} + +logging() { + __ensure_setup + + # Reset flags + log_flag="0" + warn_flag="0" + error_flag="0" + source_file="" + args=() + + while [[ $# -gt 0 ]]; do + if [[ $1 == "-w" ]] || [[ $1 =~ ^--warn ]]; then + log_flag="1" + warn_flag="1" + elif [[ $1 == "-e" ]] || [[ $1 =~ ^--error ]]; then + log_flag="1" + error_flag="1" + elif [[ $1 == "-s" ]] || [[ $1 =~ ^--source ]]; then + shift + source_file="$1" + elif [[ $1 == "log" ]]; then + log_flag="1" + else + args+=("$1") + fi + shift + done + + if [[ -z $source_file ]]; then + echo -e "\e[31m[ERROR]:\e[0m Must supply the source file the logs originate from." + exit 1 + fi + + if [[ -z $args ]]; then + echo -e "\e[31m[ERROR]:\e[0m No log message supplied." + exit 1 + fi + + msg="" + # Loop over log files logging message to each file. + for i in "${!LOG_FILE[@]}"; do + prefix="[id: $LOG_INVOCATION_ID][time: $($SCRIPTS/isosec)][label: ${LOG_LABEL[i]}][source: $source_file] : " + msg="$prefix $(__msg ${args[@]})" + echo "$msg" >>${LOG_FILE[i]} + done + + # Also log errors and warning messages to the console. + if [[ $error_flag == "1" ]] || [[ $warn_flag == "1" ]]; then + echo "${msg##* : }" + fi +} + +setup-logging() { + LOG_FILE+=("$1") + LOG_INVOCATION_ID=${LOG_INVOCATION_ID:-$RANDOM} + if [[ -n "$LOG_LABEL" ]]; then + LOG_LABEL+=("${LOG_LABEL[@]}=>$2") + else + LOG_LABEL+=("$2") + fi + export LOG_FILE + export LOG_LABEL + export LOG_INVOCATION_ID +} + +print_logger_env() { + echo "LOG_FILE: ${LOG_FILE[@]}" + echo "LOG_INVOCATION_ID: $LOG_INVOCATION_ID" + echo "LOG_LABEL: ${LOG_LABEL[@]}" +} + +export -f setup-logging +export -f logging +export -f print_logger_env diff --git a/env/.local/scripts/hypr/utils-launcher b/env/.local/scripts/hypr/utils-launcher index 80b2447..39196b3 100755 --- a/env/.local/scripts/hypr/utils-launcher +++ b/env/.local/scripts/hypr/utils-launcher @@ -26,6 +26,8 @@ config_file="" launch_flag="0" rows=() +invocation_id=${RANDOM} +LOG_FILE=${LOG_FILE:-/tmp/$THIS.log} XDG_CONFIG_HOME=${XDG_CONFIG_HOME} SCRIPTS=${SCRIPTS} @@ -39,9 +41,13 @@ while [[ $# -gt 0 ]]; do shift done +log() { + echo "[$invocation_id]:[$($SCRIPTS/isosec)]:[$THIS]: $1" >>$LOG_FILE +} + if [[ -z $XDG_CONFIG_HOME ]]; then - echo "XDG_CONFIG_HOME not set" - echo "using ~/.config" + log "XDG_CONFIG_HOME not set" + log "using ~/.config" XDG_CONFIG_HOME=$HOME/.config fi @@ -76,14 +82,14 @@ generate_rows() { ################################################################################ if [[ -z $config_file ]]; then - echo "No config file set." - echo "Using ~/.config/utils-launcher/config.json" + log "No config file set." + log "Using ~/.config/utils-launcher/config.json" config_file="$XDG_CONFIG_HOME/utils-launcher/config.json" fi if [[ -z $SCRIPTS ]]; then - echo "SCRIPTS not set" - echo "using ~/.local/scripts" + log "SCRIPTS not set" + log "using ~/.local/scripts" SCRIPTS=$HOME/.local/scripts fi @@ -92,7 +98,7 @@ if [[ $launch_flag == "1" ]]; then fi if [[ ! -f $config_file ]]; then - echo "[ERROR]: no config file set" && exit 1 + log "[ERROR]: no config file set" && exit 1 fi file_data=$(cat $config_file) @@ -101,8 +107,6 @@ file_data=$(cat $config_file) [[ -f $SCRIPTS/catppuccin-colors ]] && source $SCRIPTS/catppuccin-colors generate_rows "$file_data" -# sel=$(echo "$file_data" | jq -r '.[] | .name' | fzf --style=full --footer="$(footer)") -echo "ROWS: ${rows[@]}" sel=$( printf "%s\n" "${rows[@]}" | fzf --style=full --footer="$(footer)" --with-nth=2 --delimiter='|' \ @@ -110,17 +114,17 @@ sel=$( --preview='printf "\nName: {2}\nExec: {1}"' ) -echo "Selection: $sel" +log "Selection: $sel" if [[ -n "$sel" ]]; then - # Load the exec command for the selection. - exec_cmd=$(echo $file_data | jq -r ".[] | select(.name == \"$sel\") | .exec") + # Parse the exec command for the selection. + exec_cmd=${sel%%|*} - echo "Exec: '$exec_cmd'" + log "Exec: '$exec_cmd'" if [[ -z $exec_cmd ]]; then - echo "[ERROR]: Command is empty." && exit 1 + log "[ERROR]: Command is empty." && exit 1 fi eval exec uwsm app -- "$exec_cmd" else - echo "No selection." + log "No selection." fi diff --git a/gen b/gen index 6f128a0..1527165 100755 --- a/gen +++ b/gen @@ -40,29 +40,30 @@ generate_run() { local dest="$DEV_ENV/runs/$file" fail_if_exists $dest log "Creating new run: $dest" - printf "#!/usr/bin/env bash\n\n" >$dest - printf "yay \${1:-\"-S --noconfirm\"} # packages\n" >>$dest + cat >"$dest" <<'EOF' +#!/usr/bin/env bash +yay ${1:-"-S --noconfirm"} # packages + +EOF chmod +x $dest } generate_webapp() { - local dest="$DEV_ENV/env/webapps/$file" - + # Check that the destination ends with '.json', fix if not. if [[ ! $dest =~ \.json$ ]]; then dest="$dest.json" fi - fail_if_exists $dest - log "Creating new webapp: $dest" - - printf "{\n" >$dest - printf " \"name\": \"My App\",\n" >>$dest - printf " \"url\": \"https://example.com\",\n" >>$dest - printf " \"icon\": \"https://icon.com\"\n" >>$dest - printf "}" >>$dest + cat >"$dest" <<'EOF' +{ + "name": "My App", + "url": "https://example.com", + "icon": "https://icon.com" +} +EOF } @@ -70,7 +71,29 @@ generate_script() { local dest="$DEV_ENV/env/.local/scripts/$file" fail_if_exists $dest log "Creating new script: $dest" - printf "#!/usr/bin/env bash\n\n" >$dest + cat >"$dest" <<'EOF' +#!/usr/bin/env bash + +SCRIPTS=${SCRIPTS:-$HOME/.local/scripts} +THIS_FILE=${BASH_SOURCE[0]} +THIS=$(basename $THIS_FILE) + +# Logging utility function, use in place of echo. +log() { + logging log --source "$THIS_FILE" "$@" +} + +################################################################################ +# MAIN +################################################################################ + +# Setup logging file and label. +source "$SCRIPTS/hypr/logging" +setup-logging "/tmp/THIS.log" "$THIS" + +log "Starting $THIS..." + +EOF chmod +x $dest echo $dest }