]> git.corax.cc Git - toolbox/commitdiff
toolbox.sh: Make command-not-found errors more helpful
authorMatthias Kruk <m@m10k.eu>
Sat, 9 Jul 2022 02:50:06 +0000 (11:50 +0900)
committerMatthias Kruk <m@m10k.eu>
Sat, 9 Jul 2022 02:50:06 +0000 (11:50 +0900)
Command-not-found errors often occur because the user forgot to
include a module. In such cases, it would be helpful if the default
error message included suggestions for modules to include.

This commit adds a `command_not_found_handle()` function that
overrides bash's default behavior: aside of the usual error message,
this function will print all module names that the missing function
may be part of (as determined by its name) to stderr.

toolbox.sh

index f690b01d09c18e410922540ef96ab078cbf1d296..b26729996a19e322be3afbbf42c4475cd0394904 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 # toolbox.sh - Framework for modular bash scripts
-# Copyright (C) 2021 Matthias Kruk
+# Copyright (C) 2021-2022 Matthias Kruk
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@ __toolbox_init() {
        readonly -f have
        readonly -f _try_include
        readonly -f include
+       readonly -f command_not_found_handle
 
        return 0
 }
@@ -108,6 +109,40 @@ include() {
        return 0
 }
 
+command_not_found_handle() {
+       local command="$1"
+       # local args=("${@:2}") # not used
+
+       local searchpath
+       declare -A candidates
+
+       # Display the same message that bash usually would
+       echo "bash: $command: command not found" 1>&2
+
+       for searchpath in "${__TOOLBOX_MODULEPATH[@]}"; do
+               local module
+
+               while read -r module; do
+                       local module_name
+                       local prefix
+
+                       module_name="${module#"$searchpath"/}"
+                       module_name="${module_name%.sh}"
+                       prefix="${module_name//\//_}"
+
+                       if [[ "$command" == "$prefix"* ]]; then
+                               candidates["$module_name"]="$module"
+                       fi
+               done < <(find -L "$searchpath" -type f -iname "*.sh")
+       done
+
+       if (( ${#candidates[@]} > 0 )); then
+               echo "Did you forget to include a module? Possible candidates are: ${!candidates[*]}" 1>&2
+       fi
+
+       return 127
+}
+
 {
        if ! compgen -v | grep "^__TOOLBOX_INCLUDED$" &> /dev/null; then
                if ! __toolbox_init; then