From 0471a20c7cf5440bb5180f815254cc30873acbd9 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Wed, 22 Sep 2021 13:00:36 -0700 Subject: [PATCH 1/3] lib/helpers: new function `_bash-it-find-in-ancestor()` New function to do a search looking for a sibling to a parent of the current directory, for example to find `../../.git` to indicate that `$PWD` is inside a git repository. --- lib/helpers.bash | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index fbc6aa88..26f1c3a6 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -849,3 +849,21 @@ then fi } fi + +function _bash-it-find-in-ancestor() ( + # We're deliberately using a subshell for this entire function for simplicity. + # By using a subshell, we can use ${PWD} without special handling, and can + # just `cd ..` to move up the directory heirarchy. + # Let the shell do the work. + local kin + while [[ "${PWD}" != '/' ]]; do + for kin in "$@"; do + if [[ -r "${PWD}/${kin}" ]]; then + printf '%s' "${PWD}" + return "$?" + fi + done + command cd .. || return "$?" + done + return 1 +) From 7ed12083f26ce95cb9018bf6688fdba2e96514dc Mon Sep 17 00:00:00 2001 From: John D Pell Date: Wed, 22 Sep 2021 15:29:47 -0700 Subject: [PATCH 2/3] gradle: adopt `_bash_it_find_in_ancestor()` --- completion/available/gradle.completion.bash | 14 +++----------- plugins/available/gradle.plugin.bash | 15 +++------------ 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/completion/available/gradle.completion.bash b/completion/available/gradle.completion.bash index 786450a6..35971d50 100644 --- a/completion/available/gradle.completion.bash +++ b/completion/available/gradle.completion.bash @@ -22,17 +22,9 @@ # Avoid inaccurate completions for subproject tasks COMP_WORDBREAKS=$(echo "$COMP_WORDBREAKS" | sed -e 's/://g') -__gradle-set-project-root-dir() { - local dir="${PWD}" - project_root_dir="${PWD}" - while [[ $dir != '/' ]]; do - if [[ -f "$dir/settings.gradle" || -f "$dir/gradlew" ]]; then - project_root_dir=$dir - return 0 - fi - dir="$(dirname "$dir")" - done - return 1 +function __gradle-set-project-root-dir() { + project_root_dir="$(_bash-it-find-in-ancestor "settings.gradle" "gradlew")" + return "$?" } __gradle-init-cache-dir() { diff --git a/plugins/available/gradle.plugin.bash b/plugins/available/gradle.plugin.bash index 6267bd84..8dec1313 100644 --- a/plugins/available/gradle.plugin.bash +++ b/plugins/available/gradle.plugin.bash @@ -3,19 +3,10 @@ about-plugin 'Add a gw command to use gradle wrapper if present, else use system function gw() { local file="gradlew" - local curr_path="${PWD}" - local result="gradle" + local result - # Search recursively upwards for file. - until [[ "${curr_path}" == "/" ]]; do - if [[ -e "${curr_path}/${file}" ]]; then - result="${curr_path}/${file}" - break - else - curr_path=$(dirname "${curr_path}") - fi - done + result="$(_bash-it-find-in-ancestor "${file}")" # Call gradle - "${result}" $* + "${result:-gradle}" $* } From e8966ea2a58efe6c3d6337e4deff15c7b8a55d45 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Wed, 22 Sep 2021 13:10:19 -0700 Subject: [PATCH 3/3] lib/helpers: cite `_bash-it-find-in-ancestor()` Add `composure.sh` citation with examples and rewrite internal comments to describe the code flow. --- lib/helpers.bash | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/helpers.bash b/lib/helpers.bash index 26f1c3a6..94df885d 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -850,12 +850,21 @@ then } fi +# `_bash-it-find-in-ancestor` uses the shell's ability to run a function in +# a subshell to simplify our search to a simple `cd ..` and `[[ -r $1 ]]` +# without any external dependencies. Let the shell do what it's good at. function _bash-it-find-in-ancestor() ( - # We're deliberately using a subshell for this entire function for simplicity. - # By using a subshell, we can use ${PWD} without special handling, and can - # just `cd ..` to move up the directory heirarchy. - # Let the shell do the work. + about 'searches parents of the current directory for any of the specified file names' + group 'helpers' + param '*: names of files or folders to search for' + returns '0: prints path of closest matching ancestor directory to stdout' + returns '1: no match found' + returns '2: improper usage of shell builtin' # uncommon + example '_bash-it-find-in-ancestor .git .hg' + example '_bash-it-find-in-ancestor GNUmakefile Makefile makefile' + local kin + # To keep things simple, we do not search the root dir. while [[ "${PWD}" != '/' ]]; do for kin in "$@"; do if [[ -r "${PWD}/${kin}" ]]; then