From 6e03a726a6ba26c7c08937b29318b840dbc1b30b Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 6 Apr 2021 02:04:04 +0300 Subject: [PATCH 01/21] helpers: Split some processing code out of _bash-it-describe --- lib/helpers.bash | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/helpers.bash b/lib/helpers.bash index 94df885d42..e85961cdef 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -492,6 +492,25 @@ _bash-it-reload() { popd &> /dev/null || return } +_bash-it-process-component () +{ + _about 'internal function used to process component name and check if its enabled' + _param '1: full path to available component file' + _example '$ _bash-it-process-component "${BASH_IT}/plugins/available/git.plugin.bash' + + # Check for both the old format without the load priority, and the extended format with the priority + declare enabled_files enabled_file + enabled_file="${f##*/}" + enabled_file_clean=$(echo "$enabled_file" | sed -e 's/\(.*\)\..*\.bash/\1/g') + enabled_files=$(sort <(compgen -G "${BASH_IT}/enabled/*$BASH_IT_LOAD_PRIORITY_SEPARATOR${enabled_file}") <(compgen -G "${BASH_IT}/$subdirectory/enabled/${enabled_file}") <(compgen -G "${BASH_IT}/$subdirectory/enabled/*$BASH_IT_LOAD_PRIORITY_SEPARATOR${enabled_file}") | wc -l) + + if [ "$enabled_files" -gt 0 ]; then + enabled='x' + else + enabled=' ' + fi +} + _bash-it-describe () { _about 'summarizes available bash_it components' @@ -511,17 +530,8 @@ _bash-it-describe () printf "%-20s%-10s%s\n" "$column_header" 'Enabled?' 'Description' for f in "${BASH_IT}/$subdirectory/available/"*.bash do - # Check for both the old format without the load priority, and the extended format with the priority - declare enabled_files enabled_file - enabled_file="${f##*/}" - enabled_files=$(sort <(compgen -G "${BASH_IT}/enabled/*$BASH_IT_LOAD_PRIORITY_SEPARATOR${enabled_file}") <(compgen -G "${BASH_IT}/$subdirectory/enabled/${enabled_file}") <(compgen -G "${BASH_IT}/$subdirectory/enabled/*$BASH_IT_LOAD_PRIORITY_SEPARATOR${enabled_file}") | wc -l) - - if [ $enabled_files -gt 0 ]; then - enabled='x' - else - enabled=' ' - fi - printf "%-20s%-10s%s\n" "$(basename $f | sed -e 's/\(.*\)\..*\.bash/\1/g')" " [$enabled]" "$(cat $f | metafor about-$file_type)" + _bash-it-process-component "$f" + printf "%-20s%-10s%s\n" "$enabled_file_clean" " [$enabled]" "$(cat $f | metafor about-$file_type)" done printf '\n%s\n' "to enable $preposition $file_type, do:" printf '%s\n' "$ bash-it enable $file_type <$file_type name> [$file_type name]... -or- $ bash-it enable $file_type all" From ffeb770593cef6a9c7b63a09c0fc16a1f6f6f13f Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 6 Apr 2021 02:05:46 +0300 Subject: [PATCH 02/21] helpers: Print type when using disable all --- lib/helpers.bash | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/helpers.bash b/lib/helpers.bash index e85961cdef..5865c61048 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -633,7 +633,11 @@ _disable-thing () _bash-it-clean-component-cache "${file_type}" - printf '%s\n' "$file_entity disabled." + if [ "$file_entity" = "all" ]; then + printf '%s\n' "$file_entity $(_bash-it-pluralize-component "$file_type") disabled." + else + printf '%s\n' "$file_entity disabled." + fi } _enable-plugin () From 41cba9d7e40ae1bea969f997dca5bacaf94d1597 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 6 Apr 2021 02:06:31 +0300 Subject: [PATCH 03/21] helpers: Add enable-plugin and enable-alias aliases --- lib/helpers.bash | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index 5865c61048..5f31a0fa31 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -650,6 +650,12 @@ _enable-plugin () _enable-thing "plugins" "plugin" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_PLUGIN } +_enable-plugins () +{ + _about 'alias of _enable-plugin' + _enable-plugin "$@" +} + _enable-alias () { _about 'enables bash_it alias' @@ -660,6 +666,12 @@ _enable-alias () _enable-thing "aliases" "alias" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_ALIAS } +_enable-aliases () +{ + _about 'alias of _enable-alias' + _enable-alias "$@" +} + _enable-completion () { _about 'enables bash_it completion' From eaa2f829bddb73782d612bf6a8320055b77f8f90 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sat, 13 Feb 2021 17:18:17 +0200 Subject: [PATCH 04/21] completion: Add bash-it profile subcommand --- completion/available/bash-it.completion.bash | 32 +++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/completion/available/bash-it.completion.bash b/completion/available/bash-it.completion.bash index 4fdd72d65e..024554ebfa 100644 --- a/completion/available/bash-it.completion.bash +++ b/completion/available/bash-it.completion.bash @@ -57,6 +57,18 @@ _bash-it-comp-list-available() COMPREPLY=( $(compgen -W "${enabled_things}" -- ${cur}) ) } +_bash-it-comp-list-profiles() +{ + local profiles + + profiles=$(for f in `compgen -G "${BASH_IT}/profiles/*.bash_it" | sort -d`; + do + basename $f | sed -e 's/.bash_it//g' + done) + + COMPREPLY=( $(compgen -W "${profiles}" -- ${cur}) ) +} + _bash-it-comp() { local cur prev opts @@ -65,7 +77,7 @@ _bash-it-comp() prev="${COMP_WORDS[COMP_CWORD-1]}" chose_opt="${COMP_WORDS[1]}" file_type="${COMP_WORDS[2]}" - opts="disable enable help migrate reload restart doctor search show update version" + opts="disable enable help migrate reload restart profile doctor search show update version" case "${chose_opt}" in show) local show_args="aliases completions plugins" @@ -82,6 +94,24 @@ _bash-it-comp() return 0 fi ;; + profile) + case "${file_type}" in + load) + if [[ "load" == "$prev" ]]; then + _bash-it-comp-list-profiles + fi + return 0 + ;; + save) + return 0 + ;; + *) + local profile_args="load save" + COMPREPLY=( $(compgen -W "${profile_args}" -- ${cur}) ) + return 0 + ;; + esac + ;; doctor) local doctor_args="errors warnings all" COMPREPLY=( $(compgen -W "${doctor_args}" -- ${cur}) ) From 956ca517f4d0f9f9bc4fb8891b8796e5788f9ef2 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 6 Apr 2021 02:19:11 +0300 Subject: [PATCH 05/21] profiles: Add new default profile --- profiles/default.bash_it | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 profiles/default.bash_it diff --git a/profiles/default.bash_it b/profiles/default.bash_it new file mode 100644 index 0000000000..5e4f4631d5 --- /dev/null +++ b/profiles/default.bash_it @@ -0,0 +1,12 @@ +# This is the default profile of Bash-it + +# plugins +plugins alias-completion +plugins base + +# completion +completion bash-it +completion system + +# aliases +aliases general From 7f60b73a2ac7dedbfc6ddad2e77f51c134475062 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sat, 13 Feb 2021 17:20:18 +0200 Subject: [PATCH 06/21] helpers: Add new bash-it profile subcommand --- lib/helpers.bash | 132 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index 5f31a0fa31..681f4630a3 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -108,6 +108,7 @@ bash-it () example '$ bash-it version' example '$ bash-it reload' example '$ bash-it restart' + example '$ bash-it profile save|load my_profile' example '$ bash-it doctor errors|warnings|all' typeset verb=${1:-} shift @@ -126,6 +127,8 @@ bash-it () func=_help-$component;; doctor) func=_bash-it-doctor-$component;; + profile) + func=_bash-it-profile-$component;; search) _bash-it-search $component "$@" return;; @@ -457,6 +460,124 @@ _bash-it-doctor-() { _bash-it-doctor-all } +_bash-it-profile-save() { + _about 'saves the current configuration to the "profile" directory' + _group 'lib' + + local name=$1 + while [ -z "$1" ]; do + read -r -e -p "Please enter the name of the profile to save: " name + case $name in + "") + echo -e "\033[91mPlease choose a name.\033[m" + ;; + *) + break + ;; + esac + done + + local profile_path="${BASH_IT}/profiles/${name}.bash_it" + if [ -f "$profile_path" ]; then + echo -e "\033[0;33mProfile \"$name\" already exists.\033[m" + while true; do + read -r -e -n 1 -p "Would you like to overwrite existing profile? [y/N] " RESP + case $RESP in + [yY]) + echo -e "\033[0;32mOverwriting profile \"$name\"...\033[m" + rm "$profile_path" + break + ;; + [nN] | "") + echo -e "\033[91mAborting profile save...\033[m" + return 1 + ;; + *) + echo -e "\033[91mPlease choose y or n.\033[m" + ;; + esac + done + fi + + echo "# This file is auto generated by Bash-it. Do not edit manually!" > "$profile_path" + for subdirectory in "plugins" "completion" "aliases"; do + echo "Saving $subdirectory configuration..." + echo "" >> "$profile_path" + echo "# $subdirectory" >> "$profile_path" + for f in "${BASH_IT}/$subdirectory/available/"*.bash; do + _bash-it-process-component "$f" + if [ "$enabled" == "x" ]; then + echo "$subdirectory $enabled_file_clean" >> "$profile_path" + fi + done + done + echo "All done!" + echo "" + echo "Profile location: $profile_path" + echo "Load the profile by invoking \"bash-it profile load $name\"" +} + +_bash-it-profile-load-parse-profile() { + _about 'Internal function used to parse the profile file' + _param '1: path to the profile file' + _param '2: dry run- only check integrity of the profile file' + _example '$ _bash-it-profile-load-parse-profile "profile.bash_it" "dry"' + + local num=0 + while read -r -a line; do + num=$((num + 1)) + # Ignore comments and empty lines + [[ -z "${line[*]}" || "${line[*]}" =~ ^#.* ]] && continue + local enable_func="_enable-${line[0]}" + local subdirectory=${line[0]} + local component=${line[1]} + + typeset to_enable=$(command ls "${BASH_IT}/$subdirectory/available/$component".*bash 2>/dev/null | head -1) + # Ignore botched lines + if [[ -z "$to_enable" ]]; then + echo -e "\033[91mBad line(#$num) in profile, aborting load...\033[m" + local bad="bad line" + break + fi + # Do not actually modify config on dry run + [[ -z $2 ]] || continue + # Actually enable the component + $enable_func "$component" + done < "$1" + + # Make sure to propagate the error + [[ -z $bad ]] +} + +_bash-it-profile-load() { + _about 'loads a configuration from the "profile" directory' + _group 'lib' + + local name="$1" + if [[ -z $name ]]; then + echo -e "\033[91mPlease specify profile name to load, not changing configuration...\033" + return 1 + fi + + local profile_path="${BASH_IT}/profiles/$name.bash_it" + if [[ ! -f "$profile_path" ]]; then + echo -e "\033[91mCould not find profile \"$name\", not changing configuration...\033" + return 1 + fi + + echo "Trying to parse profile \"$name\"..." + if _bash-it-profile-load-parse-profile "$profile_path" "dry"; then + echo "Profile \"$name\" parsed successfully!" + echo "Disabling current configuration..." + _disable-all + echo "" + echo "Enabling configuration based on profile..." + _bash-it-profile-load-parse-profile "$profile_path" + echo "" + echo "Profile \"$name\" enabled!" + fi +} + _bash-it-restart() { _about 'restarts the shell in order to fully reload it' _group 'lib' @@ -550,6 +671,17 @@ _on-disable-callback() _command_exists $callback && $callback } +_disable-all () +{ + _about 'disables all bash_it components' + _example '$ _disable-all' + _group 'lib' + + _disable-plugin "all" + _disable-alias "all" + _disable-completion "all" +} + _disable-plugin () { _about 'disables bash_it plugin' From cea95d72b39c6ce03202a640045514682ebbf1fd Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Wed, 14 Apr 2021 14:29:32 +0300 Subject: [PATCH 07/21] lib: helpers: Rename _bash-it-process-component to _bash-it-determine-component-status-from-path --- lib/helpers.bash | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/helpers.bash b/lib/helpers.bash index 681f4630a3..52f5e4a1ae 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -505,7 +505,7 @@ _bash-it-profile-save() { echo "" >> "$profile_path" echo "# $subdirectory" >> "$profile_path" for f in "${BASH_IT}/$subdirectory/available/"*.bash; do - _bash-it-process-component "$f" + _bash-it-determine-component-status-from-path "$f" if [ "$enabled" == "x" ]; then echo "$subdirectory $enabled_file_clean" >> "$profile_path" fi @@ -613,11 +613,11 @@ _bash-it-reload() { popd &> /dev/null || return } -_bash-it-process-component () +_bash-it-determine-component-status-from-path () { _about 'internal function used to process component name and check if its enabled' _param '1: full path to available component file' - _example '$ _bash-it-process-component "${BASH_IT}/plugins/available/git.plugin.bash' + _example '$ _bash-it-determine-component-status-from-path "${BASH_IT}/plugins/available/git.plugin.bash' # Check for both the old format without the load priority, and the extended format with the priority declare enabled_files enabled_file @@ -651,7 +651,7 @@ _bash-it-describe () printf "%-20s%-10s%s\n" "$column_header" 'Enabled?' 'Description' for f in "${BASH_IT}/$subdirectory/available/"*.bash do - _bash-it-process-component "$f" + _bash-it-determine-component-status-from-path "$f" printf "%-20s%-10s%s\n" "$enabled_file_clean" " [$enabled]" "$(cat $f | metafor about-$file_type)" done printf '\n%s\n' "to enable $preposition $file_type, do:" From 2e3fe0a1ea1d63e2d119f36d6213f0eb2cdfe44d Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sun, 18 Apr 2021 22:15:07 +0300 Subject: [PATCH 08/21] install: Load log file --- install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install.sh b/install.sh index 5d2f883e90..e56af003cb 100755 --- a/install.sh +++ b/install.sh @@ -208,6 +208,8 @@ export BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE='' source "${BASH_IT}"/vendor/github.com/erichs/composure/composure.sh # shellcheck source=./lib/utilities.bash source "$BASH_IT/lib/utilities.bash" +# shellcheck source=./lib/log.bash +source "${BASH_IT}/lib/log.bash" cite _about _param _example _group _author _version # shellcheck source=./lib/helpers.bash source "$BASH_IT/lib/helpers.bash" From f78139fc05e43b214027874897a46418e802e215 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sun, 18 Apr 2021 22:16:17 +0300 Subject: [PATCH 09/21] install: Use new profile load command --- install.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/install.sh b/install.sh index e56af003cb..2bb78a3f64 100755 --- a/install.sh +++ b/install.sh @@ -221,12 +221,7 @@ if [[ -n $interactive && -z "${silent}" ]]; then done else echo "" - echo -e "\033[0;32mEnabling reasonable defaults\033[0m" - _enable-completion bash-it - _enable-completion system - _enable-plugin base - _enable-plugin alias-completion - _enable-alias general + _bash-it-profile-load "default" fi echo "" From df560ca04af89923b68ae6aa2526f36a303e7332 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sun, 18 Apr 2021 21:53:34 +0300 Subject: [PATCH 10/21] docs: Add profile command docs --- docs/commands/index.rst | 1 + docs/commands/profile.rst | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 docs/commands/profile.rst diff --git a/docs/commands/index.rst b/docs/commands/index.rst index 3eee3b3ac6..3890a1392e 100644 --- a/docs/commands/index.rst +++ b/docs/commands/index.rst @@ -13,3 +13,4 @@ You should be familiar with them in order to fully utilize Bash-it. search reload doctor + profile diff --git a/docs/commands/profile.rst b/docs/commands/profile.rst new file mode 100644 index 0000000000..67ca9b5b5c --- /dev/null +++ b/docs/commands/profile.rst @@ -0,0 +1,31 @@ +.. _profile: + +Bash-it Profile +--------------- + +Have you ever wanted to port your *Bash-it* configuration into another machine? + +If you did, then ``bash-it profile`` is for you! + +This command can save and load custom *"profile"* files, that can be later +used to load and recreate your configuration, in any machine you would like |:smile:| + +When porting your configuration into a new machine, you just need to save your current profile, copy the resulting *"profile"* file, and load it in the other machine. + +Example +^^^^^^^ + +.. code-block:: bash + + # Saves your current profile + bash-it profile save my_profile + # Load the default profile, which is the one used in the default installation. + bash-it profile load default + + # Do whatever you want: + # Disable stuff + bash-it disable ... + # Enable stuff + bash-it enable ... + # If you want to get back into your original configuration, you can do it easily + bash-it profile load my_profile From d4ec41bef79842a49be9edb65d48b38c883b26bb Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sun, 18 Apr 2021 23:00:37 +0300 Subject: [PATCH 11/21] helpers: Add useful log in case of empty config --- lib/helpers.bash | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/helpers.bash b/lib/helpers.bash index 52f5e4a1ae..52dec3b69e 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -499,18 +499,30 @@ _bash-it-profile-save() { done fi + local something_exists echo "# This file is auto generated by Bash-it. Do not edit manually!" > "$profile_path" for subdirectory in "plugins" "completion" "aliases"; do + local component_exists="" echo "Saving $subdirectory configuration..." - echo "" >> "$profile_path" - echo "# $subdirectory" >> "$profile_path" for f in "${BASH_IT}/$subdirectory/available/"*.bash; do _bash-it-determine-component-status-from-path "$f" if [ "$enabled" == "x" ]; then + if [ -z "$component_exists" ]; then + # This is the first component of this type, print the header + component_exists="yes" + something_exists="yes" + echo "" >> "$profile_path" + echo "# $subdirectory" >> "$profile_path" + fi echo "$subdirectory $enabled_file_clean" >> "$profile_path" fi done done + if [ -z "$something_exists" ]; then + echo "It seems like no configuration was enabled.." + echo "Make sure to double check that this is the wanted behavior." + fi + echo "All done!" echo "" echo "Profile location: $profile_path" From b2ee5f96a52634863cb12b064853aa71457ae854 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Sun, 18 Apr 2021 23:00:56 +0300 Subject: [PATCH 12/21] test: helpers: Add profile command tests --- .../profiles/test-bad-component.bash_it | 12 ++ .../bash_it/profiles/test-bad-type.bash_it | 12 ++ test/lib/helpers.bats | 108 ++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 test/fixtures/bash_it/profiles/test-bad-component.bash_it create mode 100644 test/fixtures/bash_it/profiles/test-bad-type.bash_it diff --git a/test/fixtures/bash_it/profiles/test-bad-component.bash_it b/test/fixtures/bash_it/profiles/test-bad-component.bash_it new file mode 100644 index 0000000000..8640265cf2 --- /dev/null +++ b/test/fixtures/bash_it/profiles/test-bad-component.bash_it @@ -0,0 +1,12 @@ +# plugins +plugins alias-completion +plugins base + +# completion +completion bash-it +completion system + +# aliases +aliases general +# Bad component +aliases bla diff --git a/test/fixtures/bash_it/profiles/test-bad-type.bash_it b/test/fixtures/bash_it/profiles/test-bad-type.bash_it new file mode 100644 index 0000000000..ed2d23732f --- /dev/null +++ b/test/fixtures/bash_it/profiles/test-bad-type.bash_it @@ -0,0 +1,12 @@ +# plugins +plugins alias-completion +plugins base +# Bad type +pluugins alias-completion + +# completion +completion bash-it +completion system + +# aliases +aliases general diff --git a/test/lib/helpers.bats b/test/lib/helpers.bats index 7f6664e04f..c2f11c3c56 100644 --- a/test/lib/helpers.bats +++ b/test/lib/helpers.bats @@ -13,11 +13,24 @@ load ../../plugins/available/base.plugin function local_setup { setup_test_fixture + + # Copy the test fixture to the Bash-it folder + if command -v rsync &> /dev/null; then + rsync -a "$BASH_IT/test/fixtures/bash_it/" "$BASH_IT/" + else + find "$BASH_IT/test/fixtures/bash_it" \ + -mindepth 1 -maxdepth 1 \ + -exec cp -r {} "$BASH_IT/" \; + fi } # TODO Create global __is_enabled function # TODO Create global __get_base_name function # TODO Create global __get_enabled_name function +@test "bash-it: verify that the test fixture is available" { + assert_file_exist "$BASH_IT/profiles/test-bad-component.bash_it" + assert_file_exist "$BASH_IT/profiles/test-bad-type.bash_it" +} @test "helpers: _command_exists function exists" { run type -a _command_exists &> /dev/null @@ -283,6 +296,101 @@ function local_setup { assert_link_exist "$BASH_IT/enabled/225---nvm.plugin.bash" } +@test "helper: profile load command sanity" { + run _bash-it-profile-load "default" + + assert_link_exist "$BASH_IT/enabled/150---general.aliases.bash" + assert_link_exist "$BASH_IT/enabled/250---base.plugin.bash" + assert_link_exist "$BASH_IT/enabled/365---alias-completion.plugin.bash" + assert_link_exist "$BASH_IT/enabled/350---bash-it.completion.bash" + assert_link_exist "$BASH_IT/enabled/350---system.completion.bash" +} + +@test "helper: profile save command sanity" { + run _enable-plugin "nvm" + + run _bash-it-profile-save "test" + assert_line -n 0 "Saving plugins configuration..." + assert_line -n 1 "Saving completion configuration..." + assert_line -n 2 "Saving aliases configuration..." + assert_line -n 3 "All done!" +} + +@test "helper: profile save creates valid file with only plugin enabled" { + run _enable-plugin "nvm" + + run _bash-it-profile-save "test" + run cat "$BASH_IT/profiles/test.bash_it" + assert_line -n 0 "# This file is auto generated by Bash-it. Do not edit manually!" + assert_line -n 1 "# plugins" + assert_line -n 2 "plugins nvm" +} + +@test "helper: profile save creates valid file with only completion enabled" { + run _enable-completion "bash-it" + + run _bash-it-profile-save "test" + run cat "$BASH_IT/profiles/test.bash_it" + assert_line -n 0 "# This file is auto generated by Bash-it. Do not edit manually!" + assert_line -n 1 "# completion" + assert_line -n 2 "completion bash-it" +} + +@test "helper: profile save creates valid file with only aliases enabled" { + run _enable-alias "general" + + run _bash-it-profile-save "test" + run cat "$BASH_IT/profiles/test.bash_it" + assert_line -n 0 "# This file is auto generated by Bash-it. Do not edit manually!" + assert_line -n 1 "# aliases" + assert_line -n 2 "aliases general" +} + +@test "helper: profile edge case, empty configuration" { + run _bash-it-profile-save "test" + assert_line -n 3 "It seems like no configuration was enabled.." + assert_line -n 4 "Make sure to double check that this is the wanted behavior." + + run _enable-alias "general" + run _enable-plugin "base" + run _enable-plugin "alias-completion" + run _enable-completion "bash-it" + run _enable-completion "system" + + run _bash-it-profile-load "test" + assert_link_not_exist "$BASH_IT/enabled/150---general.aliases.bash" + assert_link_not_exist "$BASH_IT/enabled/250---base.plugin.bash" + assert_link_not_exist "$BASH_IT/enabled/365---alias-completion.plugin.bash" + assert_link_not_exist "$BASH_IT/enabled/350---bash-it.completion.bash" + assert_link_not_exist "$BASH_IT/enabled/350---system.completion.bash" +} + +@test "helper: profile save and load" { + run _enable-alias "general" + run _enable-plugin "base" + run _enable-plugin "alias-completion" + run _enable-completion "bash-it" + run _enable-completion "system" + + run _bash-it-profile-save "test" + assert_success + + run _disable-alias "general" + assert_link_not_exist "$BASH_IT/enabled/150---general.aliases.bash" + run _bash-it-profile-load "test" + assert_link_exist "$BASH_IT/enabled/150---general.aliases.bash" +} + +@test "helper: profile load corrupted profile file: bad component" { + run _bash-it-profile-load "test-bad-component" + assert_line -n 1 -p "Bad line(#12) in profile, aborting load..." +} + +@test "helper: profile load corrupted profile file: bad subdirectory" { + run _bash-it-profile-load "test-bad-type" + assert_line -n 1 -p "Bad line(#5) in profile, aborting load..." +} + @test "helpers: migrate plugins and completions that share the same name" { ln -s $BASH_IT/completion/available/dirs.completion.bash $BASH_IT/completion/enabled/350---dirs.completion.bash assert_link_exist "$BASH_IT/completion/enabled/350---dirs.completion.bash" From c710fc783a33b35ca74b2ec3f07966d171cdf9aa Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 15:45:42 +0300 Subject: [PATCH 13/21] gitignore: Ignore new profiles --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index a17b6e8242..8e6f12a106 100755 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,8 @@ bats enabled/* /enabled tmp/ + +# Do not save profiles +profiles/* +# apart from the default one +!profiles/default.bash_it From 6a923760d8608b71200cc9465739b45bbcc8b41c Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 15:53:20 +0300 Subject: [PATCH 14/21] helpers: Add help message for bash-it profile --- lib/helpers.bash | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index 52dec3b69e..be06b9cec2 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -972,6 +972,17 @@ _help-plugins() rm $grouplist 2> /dev/null } +_help-profile () { + _about 'help message for profile command' + _group 'lib' + + echo "Manages profiles of bash it." + echo "Use 'bash-it profile list' to see all available profiles." + echo "Use 'bash-it profile save foo' to save the current configuration into a profile named 'foo'." + echo "Use 'bash-it profile load foo' to load an existing profile named 'foo'." + echo "Use 'bash-it profile rm foo' to remove an existing profile named 'foo'." +} + _help-update () { _about 'help message for update command' _group 'lib' From 81b17f795bf2e13d85eeec5ec4d3caff9e7e8ff1 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 16:05:01 +0300 Subject: [PATCH 15/21] helpers: Add bash-it profile list --- lib/helpers.bash | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index be06b9cec2..686d782d8d 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -561,6 +561,18 @@ _bash-it-profile-load-parse-profile() { [[ -z $bad ]] } +_bash-it-profile-list() { + about 'lists all profiles from the "profiles" directory' + _group 'lib' + + echo "Available profiles:" + for profile in "${BASH_IT}/profiles"/*.bash_it; do + profile="${profile##*/}" + echo "${profile/.bash_it/}" + done +} +} + _bash-it-profile-load() { _about 'loads a configuration from the "profile" directory' _group 'lib' From 337e188d2591239695f35720cda1f9057c57c85d Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 16:12:19 +0300 Subject: [PATCH 16/21] helpers: Add bash-it profile rm --- lib/helpers.bash | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index 686d782d8d..9006cc14bb 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -571,6 +571,24 @@ _bash-it-profile-list() { echo "${profile/.bash_it/}" done } + +_bash-it-profile-rm() { + about 'Removes a profile from the "profiles" directory' + _group 'lib' + local name="$1" + if [[ -z $name ]]; then + echo -e "\033[91mPlease specify profile name to remove...\033[m" + return 1 + fi + + local profile_path="${BASH_IT}/profiles/$name.bash_it" + if [[ ! -f "$profile_path" ]]; then + echo -e "\033[91mCould not find profile \"$name\"...\033[m" + return 1 + fi + + command rm "$profile_path" + echo "Removed profile \"$name\" successfully!" } _bash-it-profile-load() { From 1ae407150cfd7c8a41d51e142ff23d00d5842d18 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 16:12:50 +0300 Subject: [PATCH 17/21] helpers: Improve bash-it profile messages --- lib/helpers.bash | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/helpers.bash b/lib/helpers.bash index 9006cc14bb..b5fa41a340 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -108,7 +108,7 @@ bash-it () example '$ bash-it version' example '$ bash-it reload' example '$ bash-it restart' - example '$ bash-it profile save|load my_profile' + example '$ bash-it profile list|save|load|rm [profile_name]' example '$ bash-it doctor errors|warnings|all' typeset verb=${1:-} shift @@ -592,18 +592,18 @@ _bash-it-profile-rm() { } _bash-it-profile-load() { - _about 'loads a configuration from the "profile" directory' + _about 'loads a configuration from the "profiles" directory' _group 'lib' local name="$1" if [[ -z $name ]]; then - echo -e "\033[91mPlease specify profile name to load, not changing configuration...\033" + echo -e "\033[91mPlease specify profile name to load, not changing configuration...\033[m" return 1 fi local profile_path="${BASH_IT}/profiles/$name.bash_it" if [[ ! -f "$profile_path" ]]; then - echo -e "\033[91mCould not find profile \"$name\", not changing configuration...\033" + echo -e "\033[91mCould not find profile \"$name\", not changing configuration...\033[m" return 1 fi From e1017513d065683a540fb91ea15bb8430dc53d81 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 16:20:02 +0300 Subject: [PATCH 18/21] helpers: Disallow removing the default profile with bash-it profile rm --- lib/helpers.bash | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/helpers.bash b/lib/helpers.bash index b5fa41a340..7772b4f931 100755 --- a/lib/helpers.bash +++ b/lib/helpers.bash @@ -581,6 +581,12 @@ _bash-it-profile-rm() { return 1 fi + # Users should not be allowed to delete the default profile + if [[ $name == "default" ]]; then + echo -e "\033[91mCan not remove the default profile...\033[m" + return 1 + fi + local profile_path="${BASH_IT}/profiles/$name.bash_it" if [[ ! -f "$profile_path" ]]; then echo -e "\033[91mCould not find profile \"$name\"...\033[m" From 7fc003b7d6e65f3d08a4b2840613ac5ccb33060e Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 16:26:44 +0300 Subject: [PATCH 19/21] completion: Add completion for bash-it profile rm/list --- completion/available/bash-it.completion.bash | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/completion/available/bash-it.completion.bash b/completion/available/bash-it.completion.bash index 024554ebfa..18cd241aa2 100644 --- a/completion/available/bash-it.completion.bash +++ b/completion/available/bash-it.completion.bash @@ -102,11 +102,20 @@ _bash-it-comp() fi return 0 ;; + rm) + if [[ "rm" == "$prev" ]]; then + _bash-it-comp-list-profiles + fi + return 0 + ;; save) return 0 ;; + list) + return 0 + ;; *) - local profile_args="load save" + local profile_args="load save list rm" COMPREPLY=( $(compgen -W "${profile_args}" -- ${cur}) ) return 0 ;; From 4c4b138671282aa28d74cc3406d24d346edb2797 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 28 Sep 2021 16:43:07 +0300 Subject: [PATCH 20/21] tests: Add more bash-it profile tests --- test/lib/helpers.bats | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/lib/helpers.bats b/test/lib/helpers.bats index c2f11c3c56..d876d882fa 100644 --- a/test/lib/helpers.bats +++ b/test/lib/helpers.bats @@ -314,6 +314,7 @@ function local_setup { assert_line -n 1 "Saving completion configuration..." assert_line -n 2 "Saving aliases configuration..." assert_line -n 3 "All done!" + assert_file_exist "$BASH_IT/profiles/test.bash_it" } @test "helper: profile save creates valid file with only plugin enabled" { @@ -391,6 +392,53 @@ function local_setup { assert_line -n 1 -p "Bad line(#5) in profile, aborting load..." } +@test "helper: profile rm sanity" { + run _bash-it-profile-save "test" + assert_file_exist "$BASH_IT/profiles/test.bash_it" + run _bash-it-profile-rm "test" + assert_line -n 0 "Removed profile \"test\" successfully!" + assert_file_not_exist "$BASH_IT/profiles/test.bash_it" +} + +@test "helper: profile rm no params" { + run _bash-it-profile-rm "" + assert_line -n 0 -p "Please specify profile name to remove..." +} + +@test "helper: profile load no params" { + run _bash-it-profile-load "" + assert_line -n 0 -p "Please specify profile name to load, not changing configuration..." +} + +@test "helper: profile rm default" { + run _bash-it-profile-rm "default" + assert_line -n 0 -p "Can not remove the default profile..." + assert_file_exist "$BASH_IT/profiles/default.bash_it" +} + +@test "helper: profile rm bad profile name" { + run _bash-it-profile-rm "notexisting" + assert_line -n 0 -p "Could not find profile \"notexisting\"..." +} + +@test "helper: profile list sanity" { + run _bash-it-profile-list + assert_line -n 0 "Available profiles:" + assert_line -n 1 "default" +} + +@test "helper: profile list more profiles" { + run _bash-it-profile-save "cactus" + run _bash-it-profile-save "another" + run _bash-it-profile-save "brother" + run _bash-it-profile-list + assert_line -n 0 "Available profiles:" + assert_line -n 4 "default" + assert_line -n 3 "cactus" + assert_line -n 1 "another" + assert_line -n 2 "brother" +} + @test "helpers: migrate plugins and completions that share the same name" { ln -s $BASH_IT/completion/available/dirs.completion.bash $BASH_IT/completion/enabled/350---dirs.completion.bash assert_link_exist "$BASH_IT/completion/enabled/350---dirs.completion.bash" From cd38f32d9558bc61c268d530e68caaf8708e5077 Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Tue, 6 Apr 2021 02:35:32 +0300 Subject: [PATCH 21/21] test: Fix completion tests and add profile completion ones --- test/completion/bash-it.completion.bats | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/test/completion/bash-it.completion.bats b/test/completion/bash-it.completion.bats index eaa4423d31..fbf0a3fa1a 100644 --- a/test/completion/bash-it.completion.bats +++ b/test/completion/bash-it.completion.bats @@ -80,32 +80,42 @@ function __check_completion () { @test "completion bash-it: show options" { run __check_completion 'bash-it ' - assert_line -n 0 "disable enable help migrate reload restart doctor search show update version" + assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version" } @test "completion bash-it: bash-ti - show options" { run __check_completion 'bash-ti ' - assert_line -n 0 "disable enable help migrate reload restart doctor search show update version" + assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version" } @test "completion bash-it: shit - show options" { run __check_completion 'shit ' - assert_line -n 0 "disable enable help migrate reload restart doctor search show update version" + assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version" } @test "completion bash-it: bashit - show options" { run __check_completion 'bashit ' - assert_line -n 0 "disable enable help migrate reload restart doctor search show update version" + assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version" } @test "completion bash-it: batshit - show options" { run __check_completion 'batshit ' - assert_line -n 0 "disable enable help migrate reload restart doctor search show update version" + assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version" } @test "completion bash-it: bash_it - show options" { run __check_completion 'bash_it ' - assert_line -n 0 "disable enable help migrate reload restart doctor search show update version" + assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version" +} + +@test "completion bash-it: profile - show options" { + run __check_completion 'bash-it profile ' + assert_line -n 0 "load save list rm" +} + +@test "completion bash-it: profile load - show options" { + run __check_completion 'bash-it profile load ' + assert_line -n 0 "default" } @test "completion bash-it: show - show options" {