From 6fe5e4fa170cbb1efa4ed5b791ad01d3843a6fc4 Mon Sep 17 00:00:00 2001 From: Hunter Jozwiak Date: Tue, 4 Nov 2025 18:01:49 -0500 Subject: [PATCH] When launching the script, actually source the right things. If I try to launch it via ~/projects/audiogame-manager/audiogame-manager.sh it will crap out because it isn't able to source its include files; it erroneously thinks they're in the current directory as I am, which is no exactly true unless I physically go to the audiogame manager directory. This also fixes launching from the desktop icon. --- CLAUDE.md | 6 +++++- audiogame-manager.sh | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2864314..73e414e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -104,7 +104,10 @@ for f in .includes/*.sh; do bash -n "$f"; done - Examples: `get_wine_bottle()`, `process_launcher_flags()`, `download_file()` - Never use: `getWineBottle()`, `processLauncherFlags()`, `downloadFile()` - **Shebang**: Use `#!/bin/bash` for all bash scripts -- **Sourcing pattern**: Use modular sourcing: `. "${0%/*}/.includes/file.sh"` +- **Sourcing pattern**: + - **Main script** (`audiogame-manager.sh`): Use `source "${scriptDir}/.includes/file.sh"` (scriptDir is defined at line 4) + - **Subdirectory scripts** (game-scripts/, wine/, speech/): Use `source "${0%/*}/../.includes/file.sh"` + - **CRITICAL**: Never use relative paths like `source .includes/file.sh` - these fail when the current working directory differs from the script location - **Indentation**: Use consistent indentation (tabs or spaces, follow existing file patterns) - When fixing code, correct any indentation inconsistencies to match the established style @@ -194,6 +197,7 @@ The project has undergone a significant refactor to modularize functionality. ** 2. **Variable scope**: Added `export game` in main script so `.includes/bottle.sh` functions can access it 3. **Installation logic**: Completed the `-I` option implementation for noninteractive game installation 4. **Code deduplication**: Removed duplicate `check_news` and launcher logic from `update.sh` +5. **Include sourcing**: Fixed all relative path sourcing (e.g., `source .includes/bottle.sh`) to use `${scriptDir}` to ensure desktop launchers and execution from any working directory works correctly ### Critical Variable Handling - **`$game` variable**: Must be exported when set (line 489 in main script) for bottle.sh functions to work diff --git a/audiogame-manager.sh b/audiogame-manager.sh index 48c5143..b8ceaab 100755 --- a/audiogame-manager.sh +++ b/audiogame-manager.sh @@ -235,7 +235,7 @@ game_installer() { # remove games game_removal() { - source .includes/bottle.sh + source "${scriptDir}/.includes/bottle.sh" # Modern wine is unified - no architecture-specific wine executables needed mapfile -t lines < <(sed -e '/^$/d' -e '/^[[:space:]]*#/d' "${configFile}" 2> /dev/null) if [[ ${#lines} -eq 0 ]]; then @@ -273,7 +273,7 @@ game_removal() { create_game_array "$selectedGame" if [[ ${#game[@]} -gt 0 ]]; then # Set up wine environment for this game - source .includes/bottle.sh + source "${scriptDir}/.includes/bottle.sh" get_bottle "${game[0]}" if ! agm_yesno "Confirm Removal" "Audio Game Removal" "Are you sure you want to remove \"${game[2]}\"?"; then @@ -303,7 +303,7 @@ game_removal() { # kill games that are stuck kill_game() { - source .includes/bottle.sh + source "${scriptDir}/.includes/bottle.sh" # Modern wine is unified - no architecture-specific wine executables needed mapfile -t lines < <(sed '/^$/d' "${configFile}" 2> /dev/null) if [[ ${#lines} -eq 0 ]]; then @@ -447,7 +447,7 @@ create_game_array() { # Update NVDA controller client DLLs in wine bottles update_nvda_dlls() { # Ensure we have the replacement DLLs - source .includes/functions.sh + source "${scriptDir}/.includes/functions.sh" download "${nvdaControllerClientDll}" "${nvdaControllerClient64Dll}" # Update wine64 bottle (most common) @@ -493,7 +493,7 @@ update_nvda_dlls() { game_launcher() { # For use by update scripts that want to source functions in this file. [[ "$agmNoLaunch" == "true" ]] && return - source .includes/bottle.sh + source "${scriptDir}/.includes/bottle.sh" # Start nvda2speechd if available if [[ -x ${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd ]]; then @@ -522,7 +522,7 @@ game_launcher() { if [[ $menuCode -eq 1 ]] || [[ $menuCode -eq 255 ]]; then exit 0 elif [[ $menuCode -eq 3 ]]; then - source .includes/help.sh # Make available in this function + source "${scriptDir}/.includes/help.sh" # Make available in this function documentation "$game" "$(echo "$game" | cut -d '|' -f2)" fi @@ -588,7 +588,7 @@ else fi # Source dialog interface early for progress display -source .includes/dialog-interface.sh +source "${scriptDir}/.includes/dialog-interface.sh" # If display isn't set assume we are launching from console and an X environment is running using display :0 if [[ -z "$DISPLAY" ]]; then @@ -633,12 +633,12 @@ export nvda2speechdBinary="${ipfsGateway}/ipfs/QmPxhoNsoFoJC7bCfioBBCcK8tEoSoYpm # Source helper functions -source .includes/bottle.sh # Also sourced in functions that need it -source .includes/desktop.sh +source "${scriptDir}/.includes/bottle.sh" # Also sourced in functions that need it +source "${scriptDir}/.includes/desktop.sh" # dialog-interface.sh already sourced earlier -source .includes/functions.sh -source .includes/help.sh -source .includes/update.sh +source "${scriptDir}/.includes/functions.sh" +source "${scriptDir}/.includes/help.sh" +source "${scriptDir}/.includes/update.sh" # Check minimum requirements check_requirements || exit 1 @@ -685,7 +685,7 @@ args="${!command[*]}" args="${args//[[:space:]]/}" while getopts "${args}" i ; do case "$i" in - c) ./.includes/checkup.sh;; + c) "${scriptDir}/.includes/checkup.sh";; C) clear_cache;; D) desktop_launcher;; d) @@ -711,7 +711,7 @@ while getopts "${args}" i ; do r) game_removal;; S) defaultRate="${OPTARG}";; t) - gameCount=$(find ".install" -type f -iname "*.sh" | wc -l) + gameCount=$(find "${scriptDir}/.install" -type f -iname "*.sh" | wc -l) agm_infobox "Linux Game Manager" "Linux Game Manager" "There are currently ${gameCount} games available." exit 0 ;; @@ -729,9 +729,9 @@ if [[ "$noninteractiveInstall" == "true" ]]; then [[ ${#game} -lt 1 ]] && exit 0 # Install the specified game noninteractively - if [[ -f ".install/${game}.sh" ]]; then + if [[ -f "${scriptDir}/.install/${game}.sh" ]]; then export LANG="en_US.UTF-8" - . ".install/${game}.sh" + . "${scriptDir}/.install/${game}.sh" # Show success message agm_msgbox "Installation Complete" "Audio Game Installer" "Game \"${game}\" has been successfully installed." else