From 6f7d804bd179601efc282f6c31651a362c2c726f Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 19:48:11 +0200 Subject: [PATCH 01/31] change profile directory name --- bash_profile_switcher.sh | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 12346de..140de3d 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -29,7 +29,7 @@ ### GENERAL CONFIGURATION ### # Setup default directory -export SWITCH_PROFILE_DIRECTORY=".bash_profiles" +export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" [ -d "$HOME/$SWITCH_PROFILE_DIRECTORY" ] || mkdir "$HOME/$SWITCH_PROFILE_DIRECTORY" # Setup save profile filename export SWITCH_PROFILE_SAVED=".bash_saved_profile" diff --git a/docker-compose.yml b/docker-compose.yml index 5f5cf3b..41e8fff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,5 +17,5 @@ services: read_only: true - type: bind source: $PWD/tests/profiles/ - target: /root/.bash_profiles/ + target: /root/.bash_profile.d/ read_only: true From 6b19d8372c084ec94418c56bbdfba51fbe202e27 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 19:49:16 +0200 Subject: [PATCH 02/31] make format step --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 1f2c52d..2b6b4b2 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ test: shellcheck bash_profile_switcher.sh docker pull bash:5 ./tests/automated_tests.exp +format: + shfmt -w -i 4 *.sh clean: docker-compose down install: From 52d116f606de8778c56d5e03e668cde93bd41c2d Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:03:20 +0200 Subject: [PATCH 03/31] add function to manage snippets --- bash_profile_switcher.sh | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 140de3d..d073403 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -40,6 +40,45 @@ alias _unload_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CU alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' +_snippet() { + local -a snippet_array + local -r snippet_cmd="$1" + local -r snippet_name="$2" + local exit_status=0 + local IFS=':' + + read -r -a snippet_array <<<"${SWITCH_PROFILE_SNIPPETS:-}" + case "$snippet_cmd" in + push) + echo "${snippet_array[*]}" | grep -qwF "$snippet_name" || snippet_array+=("$snippet_name") + export SWITCH_PROFILE_SNIPPETS="${snippet_array[*]}" + ;; + pop) + for index in "${!snippet_array[@]}"; do + { + echo "${snippet_array[$index]}" | grep -qwF "$snippet_name" && unset "snippet_array[$index]" + } + done + export SWITCH_PROFILE_SNIPPETS="${snippet_array[*]}" + ;; + search) + exit_status=1 + for index in "${!snippet_array[@]}"; do + { + if echo "${snippet_array[$index]}" | grep -qwF "$snippet_name"; then + exit_status=0 + break + fi + } + done + ;; + *) + echo "${SWITCH_PROFILE_SNIPPETS:-}" + ;; + esac + return $exit_status +} + # Create list of profiles from .load files _switch_profile_list() { local PROFILE_LIST From 797bb02add309e871cf1583f53bc5a725dab24fe Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:36:54 +0200 Subject: [PATCH 04/31] rename .load to .profile --- bash_profile_switcher.sh | 12 ++++++------ tests/profiles/ephemeral.load | 1 + tests/profiles/{test1.load => test1.profile} | 0 tests/profiles/{test2.load => test2.profile} | 0 tests/scenarios/09-reload-list.exp | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 tests/profiles/ephemeral.load rename tests/profiles/{test1.load => test1.profile} (100%) rename tests/profiles/{test2.load => test2.profile} (100%) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index d073403..c69bb6e 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -35,7 +35,7 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" export SWITCH_PROFILE_SAVED=".bash_saved_profile" # Setup aliases to manage profiles -alias _load_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.load" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.load"' +alias _load_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile"' alias _unload_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload"' alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' @@ -79,13 +79,13 @@ _snippet() { return $exit_status } -# Create list of profiles from .load files +# Create list of profiles from .profile files _switch_profile_list() { local PROFILE_LIST - # Note: If there are no matching files, echo *.load output literally "*.load" - PROFILE_LIST="$(echo "$HOME/$SWITCH_PROFILE_DIRECTORY/"*.load)" + # Note: If there are no matching files, echo *.profile output literally "*.profile" + PROFILE_LIST="$(echo "$HOME/$SWITCH_PROFILE_DIRECTORY/"*.profile)" PROFILE_LIST="${PROFILE_LIST//$HOME\/$SWITCH_PROFILE_DIRECTORY\//}" - PROFILE_LIST="${PROFILE_LIST//.load/}" + PROFILE_LIST="${PROFILE_LIST//.profile/}" [ "$PROFILE_LIST" = '*' ] && PROFILE_LIST="" echo "$PROFILE_LIST" } @@ -161,7 +161,7 @@ switch_profile() { shift $((OPTIND - 1)) SELECTED_PROFILE="$1" - if [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${SELECTED_PROFILE}.load" ]; then { + if [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${SELECTED_PROFILE}.profile" ]; then { [ $KEEP_ENV -eq 0 ] && _unload_bash_profile if [ $TEMP_PROFILE -eq 0 ]; then _save_bash_profile; else export BASH_NEXT_PROFILE="$SELECTED_PROFILE"; fi exec bash diff --git a/tests/profiles/ephemeral.load b/tests/profiles/ephemeral.load new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/tests/profiles/ephemeral.load @@ -0,0 +1 @@ +true diff --git a/tests/profiles/test1.load b/tests/profiles/test1.profile similarity index 100% rename from tests/profiles/test1.load rename to tests/profiles/test1.profile diff --git a/tests/profiles/test2.load b/tests/profiles/test2.profile similarity index 100% rename from tests/profiles/test2.load rename to tests/profiles/test2.profile diff --git a/tests/scenarios/09-reload-list.exp b/tests/scenarios/09-reload-list.exp index 9ceafde..73efee6 100644 --- a/tests/scenarios/09-reload-list.exp +++ b/tests/scenarios/09-reload-list.exp @@ -1,6 +1,6 @@ set scenario_results($scenario_index) "FAIL - Reload list" -system echo 'true' > ./tests/profiles/ephemeral.load +system echo 'true' > ./tests/profiles/ephemeral.profile send "switch_profile -l\n" expect { @@ -11,4 +11,4 @@ expect { set scenario_results($scenario_index) "PASS - Reload list" set scenario_index [ expr $scenario_index + 1] -system rm -f ./tests/profiles/ephemeral.load +system rm -f ./tests/profiles/ephemeral.profile From d17fb3113419cbaa124379d5b85cf3907f363783 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:49:11 +0200 Subject: [PATCH 05/31] add first test snippet --- tests/profiles/snippets/vartest1.snippet.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 tests/profiles/snippets/vartest1.snippet.sh diff --git a/tests/profiles/snippets/vartest1.snippet.sh b/tests/profiles/snippets/vartest1.snippet.sh new file mode 100755 index 0000000..5393afb --- /dev/null +++ b/tests/profiles/snippets/vartest1.snippet.sh @@ -0,0 +1,17 @@ +# shellcheck shell=bash +SNIPPET_NAME="vartest1" +case "$1" in +load) + export check_var_test1="test1 variable" + _snippet push "$SNIPPET_NAME" 2>/dev/null + ;; +unload) + unset check_var_test1 + _snippet pop "$SNIPPET_NAME" 2>/dev/null + ;; +*) + true + ;; +esac + +return 0 From 5b4a1b4bb5789b853c6222adf07bd022a17dce08 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:51:54 +0200 Subject: [PATCH 06/31] precommit --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b690bad..960440b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,4 +24,4 @@ repos: entry: shellcheck language: system types: [file, shell] - files: ^bash_profile_switcher.sh$ + files: ^(bash_profile_switcher.sh|tests/profiles/snippets/*.sh)$ From 2abce59bec2db27b76c20e9114fb61d892d2d6dd Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:52:22 +0200 Subject: [PATCH 07/31] precommit --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 960440b..f78bb90 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,4 +24,4 @@ repos: entry: shellcheck language: system types: [file, shell] - files: ^(bash_profile_switcher.sh|tests/profiles/snippets/*.sh)$ + files: ^(bash_profile_switcher.sh|tests/profiles/snippets/.*\.sh)$ From 708203ed628bb5141b1a40caa149343eef0227d2 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:52:58 +0200 Subject: [PATCH 08/31] snip --- tests/profiles/snippets/vartest1.snippet.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/profiles/snippets/vartest1.snippet.sh b/tests/profiles/snippets/vartest1.snippet.sh index 5393afb..abe47f5 100755 --- a/tests/profiles/snippets/vartest1.snippet.sh +++ b/tests/profiles/snippets/vartest1.snippet.sh @@ -10,6 +10,7 @@ unload) _snippet pop "$SNIPPET_NAME" 2>/dev/null ;; *) + true true ;; esac From 5862e02f0a4c457b513ee646c4eccfa3f2f53bb7 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:53:17 +0200 Subject: [PATCH 09/31] snip --- tests/profiles/snippets/vartest1.snippet.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/profiles/snippets/vartest1.snippet.sh b/tests/profiles/snippets/vartest1.snippet.sh index abe47f5..5393afb 100755 --- a/tests/profiles/snippets/vartest1.snippet.sh +++ b/tests/profiles/snippets/vartest1.snippet.sh @@ -10,7 +10,6 @@ unload) _snippet pop "$SNIPPET_NAME" 2>/dev/null ;; *) - true true ;; esac From c31cc605dd60cd379b3c346db8e62c803f8d89b5 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sat, 16 Sep 2023 20:54:42 +0200 Subject: [PATCH 10/31] second snippet --- tests/profiles/snippets/vartest2.snippet.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 tests/profiles/snippets/vartest2.snippet.sh diff --git a/tests/profiles/snippets/vartest2.snippet.sh b/tests/profiles/snippets/vartest2.snippet.sh new file mode 100755 index 0000000..99bf651 --- /dev/null +++ b/tests/profiles/snippets/vartest2.snippet.sh @@ -0,0 +1,17 @@ +# shellcheck shell=bash +SNIPPET_NAME="vartest1" +case "$1" in +load) + export check_var_test2="test2 variable" + _snippet push "$SNIPPET_NAME" 2>/dev/null + ;; +unload) + unset check_var_test2 + _snippet pop "$SNIPPET_NAME" 2>/dev/null + ;; +*) + true + ;; +esac + +return 0 From 5828ebf2e9f2713e0bea7f9b42ca58169e86ce91 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sun, 17 Sep 2023 19:05:50 +0200 Subject: [PATCH 11/31] test snippets --- tests/profiles/snippets/varcommon.snippet.sh | 17 +++++++++++++++++ tests/profiles/snippets/vartest1.snippet.sh | 2 ++ tests/profiles/snippets/vartest2.snippet.sh | 2 ++ 3 files changed, 21 insertions(+) create mode 100755 tests/profiles/snippets/varcommon.snippet.sh diff --git a/tests/profiles/snippets/varcommon.snippet.sh b/tests/profiles/snippets/varcommon.snippet.sh new file mode 100755 index 0000000..261f184 --- /dev/null +++ b/tests/profiles/snippets/varcommon.snippet.sh @@ -0,0 +1,17 @@ +# shellcheck shell=bash +SNIPPET_NAME="varcommon" +case "$1" in +load) + export check_var_common="${common_value:-}" + _snippet push "$SNIPPET_NAME" 2>/dev/null + ;; +unload) + unset check_var_common + _snippet pop "$SNIPPET_NAME" 2>/dev/null + ;; +*) + true + ;; +esac + +return 0 diff --git a/tests/profiles/snippets/vartest1.snippet.sh b/tests/profiles/snippets/vartest1.snippet.sh index 5393afb..6b772c3 100755 --- a/tests/profiles/snippets/vartest1.snippet.sh +++ b/tests/profiles/snippets/vartest1.snippet.sh @@ -3,10 +3,12 @@ SNIPPET_NAME="vartest1" case "$1" in load) export check_var_test1="test1 variable" + export common_value="test1 common" _snippet push "$SNIPPET_NAME" 2>/dev/null ;; unload) unset check_var_test1 + unset common_value _snippet pop "$SNIPPET_NAME" 2>/dev/null ;; *) diff --git a/tests/profiles/snippets/vartest2.snippet.sh b/tests/profiles/snippets/vartest2.snippet.sh index 99bf651..49bd512 100755 --- a/tests/profiles/snippets/vartest2.snippet.sh +++ b/tests/profiles/snippets/vartest2.snippet.sh @@ -3,10 +3,12 @@ SNIPPET_NAME="vartest1" case "$1" in load) export check_var_test2="test2 variable" + export common_value="test2 common" _snippet push "$SNIPPET_NAME" 2>/dev/null ;; unload) unset check_var_test2 + unset common_value _snippet pop "$SNIPPET_NAME" 2>/dev/null ;; *) From c9bb33610366dc95602dfb2b4e7d26be96440aa0 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sun, 17 Sep 2023 19:09:03 +0200 Subject: [PATCH 12/31] rename snippets --- tests/profiles/snippets/{varcommon.snippet.sh => varcommon.sh} | 0 tests/profiles/snippets/{vartest1.snippet.sh => vartest1.sh} | 0 tests/profiles/snippets/{vartest2.snippet.sh => vartest2.sh} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/profiles/snippets/{varcommon.snippet.sh => varcommon.sh} (100%) rename tests/profiles/snippets/{vartest1.snippet.sh => vartest1.sh} (100%) rename tests/profiles/snippets/{vartest2.snippet.sh => vartest2.sh} (100%) diff --git a/tests/profiles/snippets/varcommon.snippet.sh b/tests/profiles/snippets/varcommon.sh similarity index 100% rename from tests/profiles/snippets/varcommon.snippet.sh rename to tests/profiles/snippets/varcommon.sh diff --git a/tests/profiles/snippets/vartest1.snippet.sh b/tests/profiles/snippets/vartest1.sh similarity index 100% rename from tests/profiles/snippets/vartest1.snippet.sh rename to tests/profiles/snippets/vartest1.sh diff --git a/tests/profiles/snippets/vartest2.snippet.sh b/tests/profiles/snippets/vartest2.sh similarity index 100% rename from tests/profiles/snippets/vartest2.snippet.sh rename to tests/profiles/snippets/vartest2.sh From 6d46d0c9e8684311801082af12febc85ffd1eed9 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sun, 17 Sep 2023 20:07:10 +0200 Subject: [PATCH 13/31] load snippets --- bash_profile_switcher.sh | 22 ++++++++++++++++++++-- tests/profiles/test1.profile | 7 +++++-- tests/profiles/test2.profile | 4 ++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index c69bb6e..e8cf798 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -35,10 +35,28 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" export SWITCH_PROFILE_SAVED=".bash_saved_profile" # Setup aliases to manage profiles -alias _load_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile"' -alias _unload_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload"' +#alias _load_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile"' +#alias _unload_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload"' alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' +_parse_profile() { + local FILENAME + FILENAME="$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile" + if [ -f "$FILENAME" ]; then + { + while read -r line; do + { + SNIPPET="$(echo "$line" | sed -r -e 's/^[[:blank:]]*([^# ]*)($|[[:blank:]]+#.*$|#.*$)/\1/' -e '/^$/D')" + [ -n "${SNIPPET:+is_set}" ] && [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets/$SNIPPET.sh" ] && echo "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets/$SNIPPET.sh" + } + done <"$FILENAME" + } + fi + return 0 +} +# shellcheck disable=SC2154 +alias _load_bash_profile='for p in $(_parse_profile); do source "$p" load; done' +alias _unload_bash_profile='for p in $(_parse_profile); do source "$p" unload; done' _snippet() { local -a snippet_array diff --git a/tests/profiles/test1.profile b/tests/profiles/test1.profile index 7419198..238deef 100644 --- a/tests/profiles/test1.profile +++ b/tests/profiles/test1.profile @@ -1,2 +1,5 @@ -export check_var_test1="test1 variable" -export check_var_common="test1 common" +# export check_var_test1="test1 variable" + # export check_var_common="test1 common" + + vartest1 + varcommon # prova diff --git a/tests/profiles/test2.profile b/tests/profiles/test2.profile index 5b3d146..1fd92a8 100644 --- a/tests/profiles/test2.profile +++ b/tests/profiles/test2.profile @@ -1,2 +1,2 @@ -export check_var_test2="test2 variable" -export check_var_common="test2 common" +vartest2 +varcommon From 9edb455539e471afffcaf841a1e31a3e5085d214 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Sun, 17 Sep 2023 20:15:10 +0200 Subject: [PATCH 14/31] remove comment --- bash_profile_switcher.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index e8cf798..eda9988 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -35,8 +35,6 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" export SWITCH_PROFILE_SAVED=".bash_saved_profile" # Setup aliases to manage profiles -#alias _load_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile"' -#alias _unload_bash_profile='eval [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload" ] && source "$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.unload"' alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' _parse_profile() { From 92c1b95a2ce1d806638cd3fa9796bdb46942dac0 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Mon, 18 Sep 2023 09:41:15 +0200 Subject: [PATCH 15/31] infere snippet name from bash source and add test from snippet --- bash_profile_switcher.sh | 1 + tests/automated_tests.exp | 1 + tests/profiles/snippets/vartest1.sh | 2 +- tests/profiles/snippets/vartest2.sh | 2 +- tests/profiles/test1.profile | 6 +++--- tests/scenarios/10-check-snippet.exp | 16 ++++++++++++++++ 6 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 tests/scenarios/10-check-snippet.exp diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index eda9988..146e27d 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -33,6 +33,7 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" [ -d "$HOME/$SWITCH_PROFILE_DIRECTORY" ] || mkdir "$HOME/$SWITCH_PROFILE_DIRECTORY" # Setup save profile filename export SWITCH_PROFILE_SAVED=".bash_saved_profile" +export SWITCH_PROFILE_SNIPPETS="" # Setup aliases to manage profiles alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' diff --git a/tests/automated_tests.exp b/tests/automated_tests.exp index 2d54169..7fd46b9 100755 --- a/tests/automated_tests.exp +++ b/tests/automated_tests.exp @@ -35,6 +35,7 @@ source ./tests/scenarios/06-temporary-profile.exp source ./tests/scenarios/07-keep-profile.exp source ./tests/scenarios/08-unexistent-profile.exp source ./tests/scenarios/09-reload-list.exp +source ./tests/scenarios/10-check-snippet.exp send "exit\n" sleep 1 diff --git a/tests/profiles/snippets/vartest1.sh b/tests/profiles/snippets/vartest1.sh index 6b772c3..43da5d9 100755 --- a/tests/profiles/snippets/vartest1.sh +++ b/tests/profiles/snippets/vartest1.sh @@ -1,5 +1,5 @@ # shellcheck shell=bash -SNIPPET_NAME="vartest1" +SNIPPET_NAME="$(basename "${BASH_SOURCE[0]}" .sh)" case "$1" in load) export check_var_test1="test1 variable" diff --git a/tests/profiles/snippets/vartest2.sh b/tests/profiles/snippets/vartest2.sh index 49bd512..43fe50e 100755 --- a/tests/profiles/snippets/vartest2.sh +++ b/tests/profiles/snippets/vartest2.sh @@ -1,5 +1,5 @@ # shellcheck shell=bash -SNIPPET_NAME="vartest1" +SNIPPET_NAME="$(basename "${BASH_SOURCE[0]}" .sh)" case "$1" in load) export check_var_test2="test2 variable" diff --git a/tests/profiles/test1.profile b/tests/profiles/test1.profile index 238deef..ed1d8ca 100644 --- a/tests/profiles/test1.profile +++ b/tests/profiles/test1.profile @@ -1,5 +1,5 @@ -# export check_var_test1="test1 variable" - # export check_var_common="test1 common" +# comment and spaces will be stripped + # out while parsing the configuration vartest1 - varcommon # prova + varcommon # also if you comment the single snippet name diff --git a/tests/scenarios/10-check-snippet.exp b/tests/scenarios/10-check-snippet.exp new file mode 100644 index 0000000..f93b9cc --- /dev/null +++ b/tests/scenarios/10-check-snippet.exp @@ -0,0 +1,16 @@ +set scenario_results($scenario_index) "FAIL - Check snippet" + +send "switch_profile test1\n" +expect { + timeout abort + "#" +} + +send "echo \${SWITCH_PROFILE_SNIPPETS}\n" +expect { + timeout abort + "vartest1:varcommon" +} + +set scenario_results($scenario_index) "PASS - Check snippet" +set scenario_index [ expr $scenario_index + 1] From d191892c440fcfd65718862048b0a909cb8cc6bb Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Mon, 18 Sep 2023 09:50:56 +0200 Subject: [PATCH 16/31] example snippet --- bash_profile_switcher.sh | 1 + snippet-example.sh | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100755 snippet-example.sh diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 146e27d..6016aec 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -31,6 +31,7 @@ # Setup default directory export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" [ -d "$HOME/$SWITCH_PROFILE_DIRECTORY" ] || mkdir "$HOME/$SWITCH_PROFILE_DIRECTORY" +[ -d "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets" ] || mkdir "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets" # Setup save profile filename export SWITCH_PROFILE_SAVED=".bash_saved_profile" export SWITCH_PROFILE_SNIPPETS="" diff --git a/snippet-example.sh b/snippet-example.sh new file mode 100755 index 0000000..fb422e8 --- /dev/null +++ b/snippet-example.sh @@ -0,0 +1,21 @@ +# shellcheck shell=bash +SNIPPET_NAME="$(basename "${BASH_SOURCE[0]}" .sh)" +case "$1" in +load) + # load your settings here >>> + export var1="test1 variable" + # <<< + _snippet push "$SNIPPET_NAME" 2>/dev/null + ;; +unload) + # unload your settings here >>> + export var1="test1 variable" + # <<< + _snippet pop "$SNIPPET_NAME" 2>/dev/null + ;; +*) + true + ;; +esac + +return 0 From fc26c25d4fcc613ad28319b3e56968054c878aca Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Mon, 18 Sep 2023 09:55:03 +0200 Subject: [PATCH 17/31] example --- snippet-example.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippet-example.sh b/snippet-example.sh index fb422e8..ac8f0c9 100755 --- a/snippet-example.sh +++ b/snippet-example.sh @@ -9,7 +9,7 @@ load) ;; unload) # unload your settings here >>> - export var1="test1 variable" + unset var1 # <<< _snippet pop "$SNIPPET_NAME" 2>/dev/null ;; From b85acb6a49c84718a1497dff49fbdea8ba8e1a19 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Mon, 18 Sep 2023 22:20:41 +0200 Subject: [PATCH 18/31] get rid of sed --- bash_profile_switcher.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 6016aec..22bbc31 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -35,28 +35,25 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" # Setup save profile filename export SWITCH_PROFILE_SAVED=".bash_saved_profile" export SWITCH_PROFILE_SNIPPETS="" - # Setup aliases to manage profiles alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' + _parse_profile() { - local FILENAME - FILENAME="$HOME/$SWITCH_PROFILE_DIRECTORY/${BASH_CURRENT_PROFILE}.profile" - if [ -f "$FILENAME" ]; then + local VALUE + local SNIPPET + VALUE="$2" + if [[ "$VALUE" =~ ^[[:blank:]]*([^# ]+)([[:blank:]]|$) ]]; then { - while read -r line; do - { - SNIPPET="$(echo "$line" | sed -r -e 's/^[[:blank:]]*([^# ]*)($|[[:blank:]]+#.*$|#.*$)/\1/' -e '/^$/D')" - [ -n "${SNIPPET:+is_set}" ] && [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets/$SNIPPET.sh" ] && echo "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets/$SNIPPET.sh" - } - done <"$FILENAME" + SNIPPET="${BASH_REMATCH[1]}" + [ -f "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets/$SNIPPET.sh" ] && LOAD_SNIPPETS+=("$HOME/$SWITCH_PROFILE_DIRECTORY/snippets/$SNIPPET.sh") } fi return 0 } # shellcheck disable=SC2154 -alias _load_bash_profile='for p in $(_parse_profile); do source "$p" load; done' -alias _unload_bash_profile='for p in $(_parse_profile); do source "$p" unload; done' +alias _load_bash_profile='for ((n=0;n<${#LOAD_SNIPPETS[@]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' +alias _unload_bash_profile='for ((n=$((${#LOAD_SNIPPETS[@]}-1));n>=0;n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' _snippet() { local -a snippet_array @@ -180,6 +177,9 @@ switch_profile() { SELECTED_PROFILE="$1" if [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${SELECTED_PROFILE}.profile" ]; then { + unset LOAD_SNIPPETS + declare -a LOAD_SNIPPETS + [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" ] && mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" [ $KEEP_ENV -eq 0 ] && _unload_bash_profile if [ $TEMP_PROFILE -eq 0 ]; then _save_bash_profile; else export BASH_NEXT_PROFILE="$SELECTED_PROFILE"; fi exec bash @@ -202,12 +202,22 @@ if [ -z ${BASH_NEXT_PROFILE+is_set} ]; then { { # shellcheck source=/dev/null source "$HOME/$SWITCH_PROFILE_SAVED" - [ -n "${BASH_CURRENT_PROFILE+is_set}" ] && _load_bash_profile + if [ -n "${BASH_CURRENT_PROFILE+is_set}" ]; then + { + unset LOAD_SNIPPETS + declare -a LOAD_SNIPPETS + mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" + _load_bash_profile + } + fi } fi }; else { export BASH_CURRENT_PROFILE="$BASH_NEXT_PROFILE" + unset LOAD_SNIPPETS + declare -a LOAD_SNIPPETS + mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" unset BASH_NEXT_PROFILE _load_bash_profile } From d8d4715eddec595569baf65d6f37a774f13661db Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Tue, 19 Sep 2023 18:14:07 +0200 Subject: [PATCH 19/31] get snippets --- bash_profile_switcher.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 22bbc31..a465c87 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -36,6 +36,7 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" export SWITCH_PROFILE_SAVED=".bash_saved_profile" export SWITCH_PROFILE_SNIPPETS="" # Setup aliases to manage profiles +alias _get_snippets='eval unset LOAD_SNIPPETS; declare -a LOAD_SNIPPETS; mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile"' alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' @@ -52,7 +53,7 @@ _parse_profile() { return 0 } # shellcheck disable=SC2154 -alias _load_bash_profile='for ((n=0;n<${#LOAD_SNIPPETS[@]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' +alias _load_bash_profile='_get_snippets; for ((n=0;n<${#LOAD_SNIPPETS[@]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' alias _unload_bash_profile='for ((n=$((${#LOAD_SNIPPETS[@]}-1));n>=0;n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' _snippet() { @@ -177,9 +178,6 @@ switch_profile() { SELECTED_PROFILE="$1" if [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${SELECTED_PROFILE}.profile" ]; then { - unset LOAD_SNIPPETS - declare -a LOAD_SNIPPETS - [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" ] && mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" [ $KEEP_ENV -eq 0 ] && _unload_bash_profile if [ $TEMP_PROFILE -eq 0 ]; then _save_bash_profile; else export BASH_NEXT_PROFILE="$SELECTED_PROFILE"; fi exec bash @@ -204,9 +202,6 @@ if [ -z ${BASH_NEXT_PROFILE+is_set} ]; then { source "$HOME/$SWITCH_PROFILE_SAVED" if [ -n "${BASH_CURRENT_PROFILE+is_set}" ]; then { - unset LOAD_SNIPPETS - declare -a LOAD_SNIPPETS - mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" _load_bash_profile } fi @@ -215,9 +210,6 @@ if [ -z ${BASH_NEXT_PROFILE+is_set} ]; then { }; else { export BASH_CURRENT_PROFILE="$BASH_NEXT_PROFILE" - unset LOAD_SNIPPETS - declare -a LOAD_SNIPPETS - mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile" unset BASH_NEXT_PROFILE _load_bash_profile } From 3bb686fa8fa30b4062ee81681c9648628375576b Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Tue, 19 Sep 2023 18:29:15 +0200 Subject: [PATCH 20/31] add comments to code --- bash_profile_switcher.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index a465c87..ca2e786 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -32,14 +32,27 @@ export SWITCH_PROFILE_DIRECTORY=".bash_profile.d" [ -d "$HOME/$SWITCH_PROFILE_DIRECTORY" ] || mkdir "$HOME/$SWITCH_PROFILE_DIRECTORY" [ -d "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets" ] || mkdir "$HOME/$SWITCH_PROFILE_DIRECTORY/snippets" + # Setup save profile filename export SWITCH_PROFILE_SAVED=".bash_saved_profile" + +# List of loaded snippets separated by colon like +# snipname1:snipname2:snippetname3 export SWITCH_PROFILE_SNIPPETS="" + # Setup aliases to manage profiles alias _get_snippets='eval unset LOAD_SNIPPETS; declare -a LOAD_SNIPPETS; mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile"' alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' +# shellcheck disable=SC2154 +alias _load_bash_profile='_get_snippets; for ((n=0;n<${#LOAD_SNIPPETS[@]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' +alias _unload_bash_profile='for ((n=$((${#LOAD_SNIPPETS[@]}-1));n>=0;n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' + +# _parse_profile +# To be used with mapfile +# Every line in the file is parsed and checked for a corresponding snippet to be loaded +# It will store the valid snippets in global array LOAD_SNIPPETS _parse_profile() { local VALUE local SNIPPET @@ -52,10 +65,12 @@ _parse_profile() { fi return 0 } -# shellcheck disable=SC2154 -alias _load_bash_profile='_get_snippets; for ((n=0;n<${#LOAD_SNIPPETS[@]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' -alias _unload_bash_profile='for ((n=$((${#LOAD_SNIPPETS[@]}-1));n>=0;n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' +# _snippet +# Manage the status of snippets storing it in SWITCH_PROFILE_SNIPPETS if it has loaded or unloaded. +# - push the snippet name into SWITCH_PROFILE_SNIPPETS only if the value is not already present +# - pop the snippet name from SWITCH_PROFILE_SNIPPETS +# - search if a snippet name is present in SWITCH_PROFILE_SNIPPETS _snippet() { local -a snippet_array local -r snippet_cmd="$1" From 83bb334754511c5700922a47c75f8199649c4333 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Wed, 20 Sep 2023 10:16:05 +0200 Subject: [PATCH 21/31] remove old files --- .gitignore | 2 +- tests/profiles/ephemeral.load | 1 - tests/profiles/test1.unload | 2 -- tests/profiles/test2.unload | 2 -- 4 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 tests/profiles/ephemeral.load delete mode 100644 tests/profiles/test1.unload delete mode 100644 tests/profiles/test2.unload diff --git a/.gitignore b/.gitignore index b413a49..7155de6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ README.md.backup -./tests/profiles/ephemeral.load +./tests/profiles/ephemeral.profile diff --git a/tests/profiles/ephemeral.load b/tests/profiles/ephemeral.load deleted file mode 100644 index 27ba77d..0000000 --- a/tests/profiles/ephemeral.load +++ /dev/null @@ -1 +0,0 @@ -true diff --git a/tests/profiles/test1.unload b/tests/profiles/test1.unload deleted file mode 100644 index 4405046..0000000 --- a/tests/profiles/test1.unload +++ /dev/null @@ -1,2 +0,0 @@ -unset check_var_test1 -unset check_var_common diff --git a/tests/profiles/test2.unload b/tests/profiles/test2.unload deleted file mode 100644 index 936a311..0000000 --- a/tests/profiles/test2.unload +++ /dev/null @@ -1,2 +0,0 @@ -unset check_var_test2 -unset check_var_common From bc702f01210b2940b4389afafee59d770488f3ce Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Wed, 20 Sep 2023 10:25:45 +0200 Subject: [PATCH 22/31] refine test --- tests/automated_tests.exp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/automated_tests.exp b/tests/automated_tests.exp index 7fd46b9..50da98d 100755 --- a/tests/automated_tests.exp +++ b/tests/automated_tests.exp @@ -14,6 +14,7 @@ proc print_results {} { proc abort {} { print_results + sleep 1 send "exit\n" send "exit\n" sleep 1 @@ -37,6 +38,7 @@ source ./tests/scenarios/08-unexistent-profile.exp source ./tests/scenarios/09-reload-list.exp source ./tests/scenarios/10-check-snippet.exp +sleep 1 send "exit\n" sleep 1 print_results From 4b159768d3c01c7c89b1e0fed255c80dac57c8c9 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 00:55:32 +0200 Subject: [PATCH 23/31] don't abuse arrays --- bash_profile_switcher.sh | 35 +++++++++------------------- tests/scenarios/10-check-snippet.exp | 2 +- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index ca2e786..2ea5bf9 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -71,43 +71,30 @@ _parse_profile() { # - push the snippet name into SWITCH_PROFILE_SNIPPETS only if the value is not already present # - pop the snippet name from SWITCH_PROFILE_SNIPPETS # - search if a snippet name is present in SWITCH_PROFILE_SNIPPETS + _snippet() { - local -a snippet_array - local -r snippet_cmd="$1" - local -r snippet_name="$2" - local exit_status=0 - local IFS=':' + local -r snippet_cmd="${1:-}" + local -r snippet_name="${2:-}" + local -r REGEX="(^|.*:)(${snippet_name})(:.*|$)" - read -r -a snippet_array <<<"${SWITCH_PROFILE_SNIPPETS:-}" case "$snippet_cmd" in push) - echo "${snippet_array[*]}" | grep -qwF "$snippet_name" || snippet_array+=("$snippet_name") - export SWITCH_PROFILE_SNIPPETS="${snippet_array[*]}" + if [[ "$SWITCH_PROFILE_SNIPPETS" =~ $REGEX ]]; then return 0; else SWITCH_PROFILE_SNIPPETS="${SWITCH_PROFILE_SNIPPETS}:${snippet_name}"; fi + export SWITCH_PROFILE_SNIPPETS=${SWITCH_PROFILE_SNIPPETS#:} ;; pop) - for index in "${!snippet_array[@]}"; do - { - echo "${snippet_array[$index]}" | grep -qwF "$snippet_name" && unset "snippet_array[$index]" - } - done - export SWITCH_PROFILE_SNIPPETS="${snippet_array[*]}" + if [[ "$SWITCH_PROFILE_SNIPPETS" =~ $REGEX ]]; then SWITCH_PROFILE_SNIPPETS="${BASH_REMATCH[1]%:}:${BASH_REMATCH[3]#:}"; else return 0; fi + SWITCH_PROFILE_SNIPPETS=${SWITCH_PROFILE_SNIPPETS%:} + export SWITCH_PROFILE_SNIPPETS=${SWITCH_PROFILE_SNIPPETS#:} ;; search) - exit_status=1 - for index in "${!snippet_array[@]}"; do - { - if echo "${snippet_array[$index]}" | grep -qwF "$snippet_name"; then - exit_status=0 - break - fi - } - done + if [[ "$SWITCH_PROFILE_SNIPPETS" =~ $REGEX ]]; then return 0; else return 1; fi ;; *) echo "${SWITCH_PROFILE_SNIPPETS:-}" ;; esac - return $exit_status + return 0 } # Create list of profiles from .profile files diff --git a/tests/scenarios/10-check-snippet.exp b/tests/scenarios/10-check-snippet.exp index f93b9cc..5e78bbb 100644 --- a/tests/scenarios/10-check-snippet.exp +++ b/tests/scenarios/10-check-snippet.exp @@ -9,7 +9,7 @@ expect { send "echo \${SWITCH_PROFILE_SNIPPETS}\n" expect { timeout abort - "vartest1:varcommon" + -re "\[^:\]vartest1:varcommon\[^:\]" } set scenario_results($scenario_index) "PASS - Check snippet" From c98b30e7cd78fc904e5e0bf3b95220612fac3ead Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 01:06:45 +0200 Subject: [PATCH 24/31] readability --- bash_profile_switcher.sh | 6 +---- pippo.sh | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100755 pippo.sh diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 2ea5bf9..c764fe6 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -202,11 +202,7 @@ if [ -z ${BASH_NEXT_PROFILE+is_set} ]; then { { # shellcheck source=/dev/null source "$HOME/$SWITCH_PROFILE_SAVED" - if [ -n "${BASH_CURRENT_PROFILE+is_set}" ]; then - { - _load_bash_profile - } - fi + [ -n "${BASH_CURRENT_PROFILE+is_set}" ] && _load_bash_profile } fi }; else diff --git a/pippo.sh b/pippo.sh new file mode 100755 index 0000000..22e14f7 --- /dev/null +++ b/pippo.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -euo pipefail +export PIPPO="pippo:pluto:paperino" +snpt() { + local -r snippet_cmd="${1:-}" + local -r snippet_name="${2:-}" + local -r REGEX="(^|.*:)(${snippet_name})(:.*|$)" + local NEWPIPPO + + case "$snippet_cmd" in + push) + if [[ "$PIPPO" =~ $REGEX ]]; then return 0; else export PIPPO="${PIPPO}:${snippet_name}"; fi + ;; + pop) + if [[ "$PIPPO" =~ $REGEX ]]; then NEWPIPPO="${BASH_REMATCH[1]%:}:${BASH_REMATCH[3]#:}"; else return 0; fi + NEWPIPPO=${NEWPIPPO%:} + export PIPPO=${NEWPIPPO#:} + echo "NEWPIPPO|$NEWPIPPO * PIPPO|$PIPPO" + + ;; + search) + if [[ "$PIPPO" =~ $REGEX ]]; then return 0; else return 1; fi + ;; + *) + echo "${PIPPO:-}" + ;; + esac + return 0 +} + +echo "* 00" +snpt +echo "* 01" +snpt push minnie && echo "XX $PIPPO" +echo "* 02" +snpt push pisolina && echo "XX $PIPPO" +echo "* 03" +snpt search pippo && echo found +echo "* 04" +snpt search gambadilegno || echo notfound +echo "* 05" +snpt pop pisolina && echo "XX $PIPPO" +echo "* 06" +snpt pop pluto && echo "XX $PIPPO" +echo "* 07" +snpt pop pippo && echo "XX $PIPPO" +echo "* 08" +snpt From aedf08d21bfb5fbfbfc434a5933ec4bd9c627f82 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 01:08:15 +0200 Subject: [PATCH 25/31] wrong file --- pippo.sh | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) delete mode 100755 pippo.sh diff --git a/pippo.sh b/pippo.sh deleted file mode 100755 index 22e14f7..0000000 --- a/pippo.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -set -euo pipefail -export PIPPO="pippo:pluto:paperino" -snpt() { - local -r snippet_cmd="${1:-}" - local -r snippet_name="${2:-}" - local -r REGEX="(^|.*:)(${snippet_name})(:.*|$)" - local NEWPIPPO - - case "$snippet_cmd" in - push) - if [[ "$PIPPO" =~ $REGEX ]]; then return 0; else export PIPPO="${PIPPO}:${snippet_name}"; fi - ;; - pop) - if [[ "$PIPPO" =~ $REGEX ]]; then NEWPIPPO="${BASH_REMATCH[1]%:}:${BASH_REMATCH[3]#:}"; else return 0; fi - NEWPIPPO=${NEWPIPPO%:} - export PIPPO=${NEWPIPPO#:} - echo "NEWPIPPO|$NEWPIPPO * PIPPO|$PIPPO" - - ;; - search) - if [[ "$PIPPO" =~ $REGEX ]]; then return 0; else return 1; fi - ;; - *) - echo "${PIPPO:-}" - ;; - esac - return 0 -} - -echo "* 00" -snpt -echo "* 01" -snpt push minnie && echo "XX $PIPPO" -echo "* 02" -snpt push pisolina && echo "XX $PIPPO" -echo "* 03" -snpt search pippo && echo found -echo "* 04" -snpt search gambadilegno || echo notfound -echo "* 05" -snpt pop pisolina && echo "XX $PIPPO" -echo "* 06" -snpt pop pluto && echo "XX $PIPPO" -echo "* 07" -snpt pop pippo && echo "XX $PIPPO" -echo "* 08" -snpt From eb31e12bc036e64acc2c1086742abb03f9896ed2 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 09:39:35 +0200 Subject: [PATCH 26/31] read reverse array --- bash_profile_switcher.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index c764fe6..deed790 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -41,13 +41,13 @@ export SWITCH_PROFILE_SAVED=".bash_saved_profile" export SWITCH_PROFILE_SNIPPETS="" # Setup aliases to manage profiles -alias _get_snippets='eval unset LOAD_SNIPPETS; declare -a LOAD_SNIPPETS; mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile"' alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' +alias _get_snippets='eval unset LOAD_SNIPPETS; declare -a LOAD_SNIPPETS; mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile"' # shellcheck disable=SC2154 -alias _load_bash_profile='_get_snippets; for ((n=0;n<${#LOAD_SNIPPETS[@]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' -alias _unload_bash_profile='for ((n=$((${#LOAD_SNIPPETS[@]}-1));n>=0;n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' +alias _load_bash_profile='_get_snippets; for ((n=0;n<${#LOAD_SNIPPETS[*]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' +alias _unload_bash_profile='for ((n=-1;n>=-${#LOAD_SNIPPETS[*]};n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' # _parse_profile # To be used with mapfile @@ -66,12 +66,11 @@ _parse_profile() { return 0 } -# _snippet +# _snippet [push|pop|search] # Manage the status of snippets storing it in SWITCH_PROFILE_SNIPPETS if it has loaded or unloaded. # - push the snippet name into SWITCH_PROFILE_SNIPPETS only if the value is not already present # - pop the snippet name from SWITCH_PROFILE_SNIPPETS # - search if a snippet name is present in SWITCH_PROFILE_SNIPPETS - _snippet() { local -r snippet_cmd="${1:-}" local -r snippet_name="${2:-}" From f05b4388f39029cf69abb3e5885da56ff6071146 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 10:17:33 +0200 Subject: [PATCH 27/31] inline help --- bash_profile_switcher.sh | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index deed790..b49ea39 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -127,14 +127,39 @@ OPTIONS -h Show help instructions (this help) PROFILE - A profile to load in ~/.bash_profiles. Profile files end with extension '.load' for loading (set variables) and '.unload' for unloading (unset variables) - Current profile is stored in environment variable BASH_CURRENT_PROFILE and in file ~/.bash_saved_profile + A profile to load in ~/$SWITCH_PROFILE_DIRECTORY. Profile files end with extension '.profile' and contains a list of snippets to be loaded. + Current profile is stored in environment variable BASH_CURRENT_PROFILE and in file ~/$SWITCH_PROFILE_SAVED -Example: +SNIPPETS + + Snippets are .sh files located in ~/$SWITCH_PROFILE_DIRECTORY/snippets that accept load or unload as first positional parameter (\$1) + Each snippet will be included with source in your shell. + +EXAMPLE + + Given the following setup ~/$SWITCH_PROFILE_DIRECTORY + ~]$ tree ~/.bash_profile.d/ + $HOME/.bash_profile.d/ + ├── dev.profile + └── snippets + ├── snip1.sh + └── snip2.sh + + ~]$ cat ~/.bash_profile.d/dev.profile + snip1 + snip2 ~]$ switch_profile dev - To load profile dev from ~/.bash_profiles/dev.load and unload it from ~/.bash_profiles/dev.unload + snip1.sh and snip2.sh will be included into your bash shell. + +ADDENDUM + + - Snippets will be loaded in the order the are listed into profile file. + - When you switch into a profile snippets are loaded with source command e.g. 'source snip1 load' + - When you change profile, current snippets are unloaded (except if you use -k) in reverse order + they are listed into profile file with source e.g. 'source snip1 unload' + EOF } From 64f79665eb14b08172a3b6a4059bc8d703eeabb4 Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 12:35:48 +0200 Subject: [PATCH 28/31] fix if for unsetted profile --- bash_profile_switcher.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index b49ea39..511238e 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -226,7 +226,7 @@ if [ -z ${BASH_NEXT_PROFILE+is_set} ]; then { { # shellcheck source=/dev/null source "$HOME/$SWITCH_PROFILE_SAVED" - [ -n "${BASH_CURRENT_PROFILE+is_set}" ] && _load_bash_profile + if [ -n "${BASH_CURRENT_PROFILE+is_set}" ]; then _load_bash_profile; fi } fi }; else From 3763c692c0823923d67dd0bad52f909348577b9d Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 18:26:41 +0200 Subject: [PATCH 29/31] example dir --- snippet-example.sh => examples/snippet-example.sh | 2 ++ 1 file changed, 2 insertions(+) rename snippet-example.sh => examples/snippet-example.sh (79%) diff --git a/snippet-example.sh b/examples/snippet-example.sh similarity index 79% rename from snippet-example.sh rename to examples/snippet-example.sh index ac8f0c9..c5e32d5 100755 --- a/snippet-example.sh +++ b/examples/snippet-example.sh @@ -2,12 +2,14 @@ SNIPPET_NAME="$(basename "${BASH_SOURCE[0]}" .sh)" case "$1" in load) + _snippet search "$SNIPPET_NAME" && return 0 # load your settings here >>> export var1="test1 variable" # <<< _snippet push "$SNIPPET_NAME" 2>/dev/null ;; unload) + _snippet search "$SNIPPET_NAME" || return 0 # unload your settings here >>> unset var1 # <<< From 2a29ce51e28d68cfbfde5a4abae27ea6132d44cd Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 18:46:10 +0200 Subject: [PATCH 30/31] readme --- README.md | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 81d3688..9d0a8d5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ Easily change environment variables and settings using bash ## About This script aim to manage multiple profile files for bash. It's like having multiple `.bashrc` files to load or unload when needed. -All you need to do is to create your custom profile files under `~/.bash_profiles` directory. Each profile must have extension `.load` where you define variables, aliases and so on. You can optionally create files with extension `.unload` to clear what is loaded with a speficic profile. +You need to create your custom profile files under `~/.bash_profile.d` directory. Each profile must have extension `.profile` and it is a plain text file containing a list of "snippets" (one per line) to be loaded into your profile. +Snippets are `.sh` files where you can set variables/aliases/functions or any command you want to execute when you spawn a shell ([snippet example](examples/snippet-example.sh)). ## Installation @@ -13,7 +14,7 @@ _Note_: You can use `make install INSTALL_PATH=` to install the script in ## Usage -Use `switch_profile` function to manage profiles +Use `switch_profile` function to change profile ``` ~]$ switch_profile -h @@ -29,39 +30,36 @@ OPTIONS -l List available profiles -h Show help instructions (this help) - -PROFILE - A profile to load in ~/.bash_profiles. Profile files end with extension '.load' for loading (set variables) and '.unload' for unloading (unset variables) - Current profile is stored in environment variable BASH_CURRENT_PROFILE and in file ~/.bash_saved_profile - -Example: - - ~]$ switch_profile dev - - To load profile dev from ~/.bash_profiles/dev.load and unload it from ~/.bash_profiles/dev.unload ``` ## Example -Create the following profile files in `~/.bash_profiles`: - -> `myprofile.load` - -```bash -export PS1="Funky Prompt:: \w ]\\$ " +As an example take the following directory structure for `~/.bash_profile.d` +``` +.bash_profile.d/ +├── foo.profile +├── bar.profile +└── snippets + ├── tools.sh + ├── cloudvars.sh + └── setpath.sh ``` -> `myprofile.unload` - -```bash -unset PS1 ``` -Then load it with: `switch_profile myprofile` +]$ cat ~/.bash_profile.d/foo.profile +tools +cloudvars +setpath +]$ cat ~/.bash_profile.d/bar.profile +setpath +``` +When you do `switch_profile foo` snippets `tools.sh`,`cloudvars.sh`,`setpath.sh` will be loaded (in the same order they are listed in profile). +On profile change `switch_profile bar` bash will first unload all the snippets applied by `foo` in reverse order then load the snippets listed in `bar`, that is `setpath.sh` +`` ## Issues * Spaces and blank characters are not supported on profile filenames -* Unload files must be written manually to match exactly what you loaded or defined * Be careful when managing special variables like `PATH` ## Test automation From 8b3a384bf0ab3d35c6979eba5344b4fc2d7004de Mon Sep 17 00:00:00 2001 From: Gianluca Mascolo Date: Thu, 21 Sep 2023 18:54:25 +0200 Subject: [PATCH 31/31] avoid usage of variables prefixed with BASH_ because it may be reserved names --- bash_profile_switcher.sh | 18 +++++++++--------- tests/scenarios/05-reset-profile.exp | 4 ++-- tests/scenarios/06-temporary-profile.exp | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/bash_profile_switcher.sh b/bash_profile_switcher.sh index 511238e..9b47b73 100644 --- a/bash_profile_switcher.sh +++ b/bash_profile_switcher.sh @@ -41,10 +41,10 @@ export SWITCH_PROFILE_SAVED=".bash_saved_profile" export SWITCH_PROFILE_SNIPPETS="" # Setup aliases to manage profiles -alias _save_bash_profile='eval echo "export BASH_CURRENT_PROFILE=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' -alias _reset_bash_profile='eval echo "unset BASH_CURRENT_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' +alias _save_bash_profile='eval echo "export SWITCH_PROFILE_CURRENT=$SELECTED_PROFILE" > "$HOME/$SWITCH_PROFILE_SAVED"' +alias _reset_bash_profile='eval echo "unset SWITCH_PROFILE_CURRENT" > "$HOME/$SWITCH_PROFILE_SAVED"' -alias _get_snippets='eval unset LOAD_SNIPPETS; declare -a LOAD_SNIPPETS; mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${BASH_CURRENT_PROFILE}.profile"' +alias _get_snippets='eval unset LOAD_SNIPPETS; declare -a LOAD_SNIPPETS; mapfile -c 1 -C _parse_profile -t <"${HOME}/${SWITCH_PROFILE_DIRECTORY}/${SWITCH_PROFILE_CURRENT}.profile"' # shellcheck disable=SC2154 alias _load_bash_profile='_get_snippets; for ((n=0;n<${#LOAD_SNIPPETS[*]};n++)); do source "${LOAD_SNIPPETS[$n]}" load; done' alias _unload_bash_profile='for ((n=-1;n>=-${#LOAD_SNIPPETS[*]};n--)); do source "${LOAD_SNIPPETS[$n]}" unload; done' @@ -128,7 +128,7 @@ OPTIONS PROFILE A profile to load in ~/$SWITCH_PROFILE_DIRECTORY. Profile files end with extension '.profile' and contains a list of snippets to be loaded. - Current profile is stored in environment variable BASH_CURRENT_PROFILE and in file ~/$SWITCH_PROFILE_SAVED + Current profile is stored in environment variable SWITCH_PROFILE_CURRENT and in file ~/$SWITCH_PROFILE_SAVED SNIPPETS @@ -205,7 +205,7 @@ switch_profile() { SELECTED_PROFILE="$1" if [ -f "${HOME}/${SWITCH_PROFILE_DIRECTORY}/${SELECTED_PROFILE}.profile" ]; then { [ $KEEP_ENV -eq 0 ] && _unload_bash_profile - if [ $TEMP_PROFILE -eq 0 ]; then _save_bash_profile; else export BASH_NEXT_PROFILE="$SELECTED_PROFILE"; fi + if [ $TEMP_PROFILE -eq 0 ]; then _save_bash_profile; else export SWITCH_PROFILE_NEXT="$SELECTED_PROFILE"; fi exec bash }; else { @@ -221,18 +221,18 @@ switch_profile() { ### MAIN SCRIPT ### [ -n "$SWITCH_PROFILE_LIST" ] && complete -o nospace -W "$SWITCH_PROFILE_LIST" switch_profile -if [ -z ${BASH_NEXT_PROFILE+is_set} ]; then { +if [ -z ${SWITCH_PROFILE_NEXT+is_set} ]; then { if [ -f "$HOME/$SWITCH_PROFILE_SAVED" ]; then { # shellcheck source=/dev/null source "$HOME/$SWITCH_PROFILE_SAVED" - if [ -n "${BASH_CURRENT_PROFILE+is_set}" ]; then _load_bash_profile; fi + if [ -n "${SWITCH_PROFILE_CURRENT+is_set}" ]; then _load_bash_profile; fi } fi }; else { - export BASH_CURRENT_PROFILE="$BASH_NEXT_PROFILE" - unset BASH_NEXT_PROFILE + export SWITCH_PROFILE_CURRENT="$SWITCH_PROFILE_NEXT" + unset SWITCH_PROFILE_NEXT _load_bash_profile } fi diff --git a/tests/scenarios/05-reset-profile.exp b/tests/scenarios/05-reset-profile.exp index 91dd9b6..51903ff 100644 --- a/tests/scenarios/05-reset-profile.exp +++ b/tests/scenarios/05-reset-profile.exp @@ -10,7 +10,7 @@ expect { send "cat ~/.bash_saved_profile\n" expect { timeout abort - "export BASH_CURRENT_PROFILE=test1" + "export SWITCH_PROFILE_CURRENT=test1" } send "switch_profile -d\n" @@ -22,7 +22,7 @@ expect { send "cat ~/.bash_saved_profile\n" expect { timeout abort - "unset BASH_CURRENT_PROFILE" + "unset SWITCH_PROFILE_CURRENT" } set scenario_results($scenario_index) "PASS - Reset saved profile" diff --git a/tests/scenarios/06-temporary-profile.exp b/tests/scenarios/06-temporary-profile.exp index 608710d..fe33763 100644 --- a/tests/scenarios/06-temporary-profile.exp +++ b/tests/scenarios/06-temporary-profile.exp @@ -13,7 +13,7 @@ expect { } # Check we are using test1 -send "echo profile:\$BASH_CURRENT_PROFILE\n" +send "echo profile:\$SWITCH_PROFILE_CURRENT\n" expect { timeout abort "profile:test1" @@ -22,7 +22,7 @@ expect { send "cat ~/.bash_saved_profile\n" expect { timeout abort - "unset BASH_CURRENT_PROFILE" + "unset SWITCH_PROFILE_CURRENT" } set scenario_results($scenario_index) "PASS - Temporary profile check"