From b607d6e1cc26c21c8adb792689cb5b597fab24c1 Mon Sep 17 00:00:00 2001 From: Cynthia Coan Date: Sat, 3 Aug 2019 14:07:01 -0600 Subject: [PATCH] sync local changes to sash * greatly speed up sash-parse * split out sash-trap from sash-err-stack * add tests * add sash-parse level CLI. --- CHANGELOG.md | 10 + CONTRIBUTING.md | 1 + LICENSE | 2 +- README.md | 18 +- sash-command-handler.sh | 47 ++++ sash-libs/README.md | 13 +- sash-libs/sash-err-stack/README.md | 6 +- sash-libs/sash-err-stack/sash-err-stack.sh | 117 +++++----- .../test-can-be-sourced-in-err-mode.sh | 9 + .../tests/test-cases/test-err-mode-mixup.sh | 19 ++ .../test-cases/test-source-multiple-times.sh | 5 + .../sash-err-stack/tests/test-err-stack.bats | 18 ++ sash-libs/sash-parse/README.md | 7 +- sash-libs/sash-parse/sash-parse.sh | 212 ++++++++---------- .../tests/test-cases/sash-parse-all.sh | 23 ++ .../test-cases/sash-parse-duplicate-flag.sh | 10 + .../test-cases/sash-parse-invalid-flags.sh | 21 ++ sash-libs/sash-parse/tests/test-parse.bats | 30 +++ sash-libs/sash-trap/README.md | 53 +++++ sash-libs/sash-trap/sash-trap.sh | 33 +++ .../test-add-multiple-to-empty-trap.sh | 16 ++ .../test-cases/test-add-to-empty-trap.sh | 14 ++ .../tests/test-cases/test-simple-get-tt.sh | 16 ++ .../test-cases/test-simple-quote-get-tt.sh | 10 + sash-libs/sash-trap/tests/test-trap.bats | 29 +++ sash.sh | 8 +- sash-add.sh => subcommands/sash-add.sh | 15 +- .../sash-package.sh | 21 +- sash-show.sh => subcommands/sash-show.sh | 14 +- 29 files changed, 596 insertions(+), 201 deletions(-) create mode 100755 sash-command-handler.sh create mode 100755 sash-libs/sash-err-stack/tests/test-cases/test-can-be-sourced-in-err-mode.sh create mode 100755 sash-libs/sash-err-stack/tests/test-cases/test-err-mode-mixup.sh create mode 100755 sash-libs/sash-err-stack/tests/test-cases/test-source-multiple-times.sh create mode 100755 sash-libs/sash-parse/tests/test-cases/sash-parse-all.sh create mode 100755 sash-libs/sash-parse/tests/test-cases/sash-parse-duplicate-flag.sh create mode 100755 sash-libs/sash-parse/tests/test-cases/sash-parse-invalid-flags.sh create mode 100644 sash-libs/sash-parse/tests/test-parse.bats create mode 100644 sash-libs/sash-trap/README.md create mode 100755 sash-libs/sash-trap/sash-trap.sh create mode 100755 sash-libs/sash-trap/tests/test-cases/test-add-multiple-to-empty-trap.sh create mode 100755 sash-libs/sash-trap/tests/test-cases/test-add-to-empty-trap.sh create mode 100755 sash-libs/sash-trap/tests/test-cases/test-simple-get-tt.sh create mode 100755 sash-libs/sash-trap/tests/test-cases/test-simple-quote-get-tt.sh create mode 100644 sash-libs/sash-trap/tests/test-trap.bats rename sash-add.sh => subcommands/sash-add.sh (97%) rename sash-package.sh => subcommands/sash-package.sh (95%) rename sash-show.sh => subcommands/sash-show.sh (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e93435..942a27f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## Unreleased + +* Split out trap functionality to: `sash-trap` +* Add Tests for `sash-err-stack` +* Add Tests for `sash-parse` +* Add Tests for `sash-trap` +* Speed up `sash-parse` by multiple times. +* Create: `sash ` commands. +* Basic Documentation for: `sash package` in README. + ## 1.2.0 - (February 23rd, 2019) * Don't source `sash-parse.sh` before plugins load as plugins can overwrite that. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3dbc76c..51031f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,7 @@ I want to make contributing to this project as easy and transparent as possible. ## Pull Requests ## + I actively welcome your pull requests. 1. Fork the repo and create your branch from `master`. diff --git a/LICENSE b/LICENSE index a54d400..2850d06 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2018 Security Insanity +Copyright (c) 2019 Security Insanity Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 5562b42..176c251 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,13 @@ categories if you didn't manually create them first. ## Usage ## -### sash_add ### +### sash add ### Whenever you need to add something to your modularized bashrc instead of manually `mkdir && vim`'ing a file reach for `sash_add`: ```bash -ecoan@kappa:~$ sash_add +ecoan@kappa:~$ sash add Please Choose a Category: 1) /home/CORP.INSTRUCTURE.COM/ecoan/.bash/plugins/utilities 2) /home/CORP.INSTRUCTURE.COM/ecoan/.bash/plugins/work @@ -70,7 +70,7 @@ to type the content you want to add the bashrc, and one for you to type comments (without the annoying '#' at the beginning of the line for long comments) so you can know what it is when coming back to it later. -### sash_show ### +### sash show ### If you're like me you've probably created a lot of individual files under a specific subcategory. To the point where you have so many files you don't want to manually cat them all out. Enter sash_show. @@ -78,7 +78,7 @@ Sash show allows you to get a materialized view of an entire sub category so tha content is in it. ```bash -ecoan@kappa:~$ sash_show +ecoan@kappa:~$ sash show Please Choose a Category: 1) /home/CORP.INSTRUCTURE.COM/ecoan/.bash/plugins/utilities 2) /home/CORP.INSTRUCTURE.COM/ecoan/.bash/plugins/work @@ -96,7 +96,7 @@ Please Choose a SubCategory: # adding some content to sash with multiple lines # for testing export SASH_TEST=1 -ecoan@kappa:~$ sash_show utilities/test +ecoan@kappa:~$ sash show utilities test ############################################################### # Content from: /home/CORP.INSTRUCTURE.COM/ecoan/.bash/plugins/utilities/test//test.sh @@ -108,6 +108,14 @@ ecoan@kappa:~$ sash_show utilities/test export SASH_TEST=1 ``` +### sash package ### + +sash package is a tool for distributing parts (a category or subcategory) to +other users. Not only that it signs the package using keybase for you so people +can validate that it came from you. + +Simply run: `sash package`. + ### sash_trace ### If you aren't able to find out where a particular command is executing (or you want to see which diff --git a/sash-command-handler.sh b/sash-command-handler.sh new file mode 100755 index 0000000..aec0313 --- /dev/null +++ b/sash-command-handler.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +source "$SASH_DIR/subcommands/sash-add.sh" +source "$SASH_DIR/subcommands/sash-package.sh" +source "$SASH_DIR/subcommands/sash-show.sh" + +SASH_ARGS=("h|help") + +sash() { + __sash_parse_args "$*" "${SASH_ARGS[@]}" || { + printf 'Failure to parse arguments!\nRemember argument flags should not be between sash and subcommand.' + return 10 + } + + local split_stdin=($(__sash_split_str "${__sash_parse_results[__STDIN]}" " ")) + + if [[ "${split_stdin[0]}" == "add" ]]; then + sash:add + return $? + fi + if [[ "${split_stdin[0]}" == "show" ]]; then + sash:show "${split_stdin[@]:1}" + return $? + fi + if [[ "${split_stdin[0]}" == "package" ]]; then + sash:package "${split_stdin[@]:1}" + return $? + fi + + echo " +Welcome to S.A.S.H.! + +S.A.S.H. offers the following subcommands: + + * \`add\` - add something to your bashrc + (and automatically source it). + * \`show (category) (sub-category)\` - show the contents of a paritcular + subcategory. + * \`package\` - package up a particular category + or subcategory for distribution to + others. + +NOTE: anything between: \`()\` above denotes optional arguments. +If you don't provide them, and they're needed, you will be asked inline. +" + return 0 +} diff --git a/sash-libs/README.md b/sash-libs/README.md index 8f54700..a1e5722 100644 --- a/sash-libs/README.md +++ b/sash-libs/README.md @@ -16,7 +16,8 @@ problems for other scripts around you. However, you still want the benefits `set -e` provides in order to ensure your script doesn't keep running. This is where `sash-err-stack` fits in. -Dependencies: None +Dependencies: + * Sash-Trap ## Sash-Parse ## @@ -36,3 +37,13 @@ one you might expect inside of a full blown language (such as Go, Rust, etc.) Dependencies: * Sash-Err-Stack + * Sash-Trap (dependency of Sash-Err-Stack) + +## Sash-Trap ## + +`sash-trap` is a library built for "safely-handling" traps. More specifically +built to get around the fact that the `trap` command by default, stomps all +over a command that was previously in trap. Making it impossible, to actually +recursively set traps without everyone knowing how to properly add to a trap. + +Dependencies: None diff --git a/sash-libs/sash-err-stack/README.md b/sash-libs/sash-err-stack/README.md index 89c66f7..86bb6a9 100644 --- a/sash-libs/sash-err-stack/README.md +++ b/sash-libs/sash-err-stack/README.md @@ -35,6 +35,10 @@ __sash_guard_errors() That's it! Simply call each one of these functions whenever you want to either allow errors, or disallow errors for the runtime of your function. +It should be noted: We check for the error mode being correct at the return of +every function. So even if you call a function that messes with the global error +mode, we will set it back before control is returned to your function. + ### Notes ### Sash-Err-Stack depends very, very heavily on the presence of the RETURN trap being @@ -42,4 +46,4 @@ fired. However, by default trap overwrites the entire trap. Meaning if someone e clears the return trap we're swell out of luck. If this happens Undefined Behavior will happen, so you should always ensure traps -are properly set, and unset. +are properly set, and unset. To help with this, I recommend looking at `sash-trap`. diff --git a/sash-libs/sash-err-stack/sash-err-stack.sh b/sash-libs/sash-err-stack/sash-err-stack.sh index 678f08c..6726266 100755 --- a/sash-libs/sash-err-stack/sash-err-stack.sh +++ b/sash-libs/sash-err-stack/sash-err-stack.sh @@ -10,50 +10,36 @@ # S.A.S.H. is the main way to add things to your ~/.bashrc and still # maintain structure. -declare -f __sash_pop_err_mode_stack >/dev/null -__sash_intermediate_check="$?" +_sash_initial_err_mode="" -if [[ "$__sash_intermediate_check" == "1" ]]; then +if [[ "$-" =~ "e" ]]; then + _sash_initial_err_mode="0" +else + _sash_initial_err_mode="1" +fi -# _sash_get_trapped_text(signal: String) -# -# Modifies Variables: None -# -# parses trap output to get you the command for a signal. -_sash_get_trapped_text() { - local signal="$1" - echo "$(trap -p "$signal" | sed "s/trap -- '//g; s/' $signal$//g; s/\\\''//g")" -} +set +e -# _sash_safe_add_to_trap(signal: String, command: String) -# -# Modifies Variables: None -# -# safely adds a command to a trap. -_sash_safe_add_to_trap() { - local command_to_add="$1" - local signal="$2" +declare -f _sash_safe_add_to_trap >/dev/null +__sash_trap_intermediate_check="$?" - if [[ "x$(trap -p "$signal")" == "x" ]]; then - trap "$command_to_add" "$signal" +if [[ "$__sash_trap_intermediate_check" == "1" ]]; then + if [[ "x$SASH_TRAP_DIR" == "x" ]]; then + source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../sash-trap/sash-trap.sh" else - local trapped_text="$(_sash_get_trapped_text "$signal")" - echo "$trapped_text" | grep "^.*;" > /dev/null 2>&1 - if [[ "$?" == "0" ]]; then - trap "$trapped_text $command_to_add;" "$signal" - else - trap "$trapped_text; $command_to_add;" "$signal" - fi + source "$SASH_TRAP_DIR/sash-trap.sh" fi -} +fi + +unset __sash_trap_intermediate_check + + +declare -f __sash_pop_err_mode_stack >/dev/null +__sash_intermediate_check="$?" + +if [[ "$__sash_intermediate_check" == "1" ]]; then _sash_global_err_mode_stack=() -_sash_initial_err_mode="" -if [[ "$-" =~ "e" ]]; then - _initial_err_mode="0" -else - _initial_err_mode="1" -fi # __sash_reset_initial_stack() # @@ -79,10 +65,9 @@ __sash_reset_initial_stack() { # # Pushes onto the error stack. __sash_push_err_mode_stack() { - local func_name="$1" - local err_mode="$2" - _sash_global_err_mode_stack=("${_sash_global_err_mode_stack[@]}" "$func_name|$err_mode") - if [[ "$err_mode" == "1" ]]; then + _sash_global_err_mode_stack=("${_sash_global_err_mode_stack[@]}" "$1|$2") + + if [[ "$2" == "1" ]]; then set -e else set +e @@ -99,34 +84,39 @@ __sash_push_err_mode_stack() { # Should be called when a function exits. Checks to see # if the function exiting had an artificial error_state, and unsets it. __sash_pop_err_mode_stack() { - local func_name="${FUNCNAME[1]}" - local new_arr=() - local func_iter= - for func_iter in "${_sash_global_err_mode_stack[@]}"; do - local func_iter_inner_arr=(${func_iter//|/\ }) - if [[ "${func_iter_inner_arr[0]}" == "$func_name" ]]; then - local was_enabled_err="${func_iter_inner_arr[1]}" - if [[ "$was_enabled_err" == "1" ]]; then - set +e - else - set -e - fi + local readonly func_name="${FUNCNAME[1]}" + + local readonly stack_size="${#_sash_global_err_mode_stack[@]}" + local readonly stack_le_index=$(( stack_size - 1 )) + if [[ "$stack_size" == "0" ]]; then + return 0 + fi + + local readonly stack_last_element="${_sash_global_err_mode_stack[$stack_le_index]}" + local readonly stack_split_name=(${stack_last_element//|/\ }) + if [[ "${stack_split_name[0]}" == "$func_name" ]]; then + if [[ "$stack_size" == "1" ]]; then + __sash_reset_initial_stack + _sash_global_err_mode_stack=() + return 0 + fi + + if [[ "${stack_split_name[1]}" == "1" ]]; then + set +e else - new_arr=("${new_arr[@]}" "$func_iter") + set -e fi - done - _sash_global_err_mode_stack=("${new_arr[@]}") - if [[ "${#_sash_global_err_mode_stack[@]}" == "0" ]]; then - __sash_reset_initial_stack + + _sash_global_err_mode_stack=(${_sash_global_err_mode_stack[@]:0:$stack_le_index}) else - local last_elem="${_sash_global_err_mode_stack[-1]}" - local inner_split=(${last_elem//|/\ }) - if [[ "${inner_split[1]}" == "1" ]]; then + if [[ "${stack_split_name[1]}" == "1" ]]; then set -e else set +e fi fi + + return 0 } set -o functrace @@ -139,8 +129,7 @@ _sash_safe_add_to_trap "__sash_pop_err_mode_stack" "RETURN" # # sets the error mode to be off for the runtime of this function. __sash_allow_errors() { - local func_name="${FUNCNAME[1]}" - __sash_push_err_mode_stack "$func_name" "0" + __sash_push_err_mode_stack "${FUNCNAME[1]}" "0" } # __sash_guard_errors() @@ -150,9 +139,9 @@ __sash_allow_errors() { # # sets the error mode to be on for the runtime of this function. __sash_guard_errors() { - local func_name="${FUNCNAME[1]}" - __sash_push_err_mode_stack "$func_name" "1" + __sash_push_err_mode_stack "${FUNCNAME[1]}" "1" } fi unset __sash_intermediate_check +__sash_reset_initial_stack diff --git a/sash-libs/sash-err-stack/tests/test-cases/test-can-be-sourced-in-err-mode.sh b/sash-libs/sash-err-stack/tests/test-cases/test-can-be-sourced-in-err-mode.sh new file mode 100755 index 0000000..38e2d19 --- /dev/null +++ b/sash-libs/sash-err-stack/tests/test-cases/test-can-be-sourced-in-err-mode.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-err-stack.sh" + +false +echo "hey" diff --git a/sash-libs/sash-err-stack/tests/test-cases/test-err-mode-mixup.sh b/sash-libs/sash-err-stack/tests/test-cases/test-err-mode-mixup.sh new file mode 100755 index 0000000..b9b5587 --- /dev/null +++ b/sash-libs/sash-err-stack/tests/test-cases/test-err-mode-mixup.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-err-stack.sh" + +function messWithGlobalErrorMode() { + set +e + false + echo "hey" +} + +function guard() { + __sash_guard_errors + messWithGlobalErrorMode + false + echo "hello world" +} + +guard diff --git a/sash-libs/sash-err-stack/tests/test-cases/test-source-multiple-times.sh b/sash-libs/sash-err-stack/tests/test-cases/test-source-multiple-times.sh new file mode 100755 index 0000000..a95d109 --- /dev/null +++ b/sash-libs/sash-err-stack/tests/test-cases/test-source-multiple-times.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-err-stack.sh" +source "$SCRIPT_DIR/../../sash-err-stack.sh" diff --git a/sash-libs/sash-err-stack/tests/test-err-stack.bats b/sash-libs/sash-err-stack/tests/test-err-stack.bats index fe32591..0d29c7d 100644 --- a/sash-libs/sash-err-stack/tests/test-err-stack.bats +++ b/sash-libs/sash-err-stack/tests/test-err-stack.bats @@ -23,3 +23,21 @@ [ "$status" -eq "0" ] [ "${lines[0]}" = "hey" ] } + +@test "sash can be sourced multiple times" { + run $BATS_TEST_DIRNAME/test-cases/test-source-multiple-times.sh + [ "$status" -eq "0" ] +} + +@test "sash recovers from error mode mixup" { + run $BATS_TEST_DIRNAME/test-cases/test-err-mode-mixup.sh + [ "$status" -eq "1" ] + [ "${lines[0]}" = "hey" ] + [ "${#lines[@]}" = "1" ] +} + +@test "sash can source when error mode is set to true" { + run $BATS_TEST_DIRNAME/test-cases/test-can-be-sourced-in-err-mode.sh + [ "$status" -eq "1" ] + [ "${#lines[@]}" = "0" ] +} diff --git a/sash-libs/sash-parse/README.md b/sash-libs/sash-parse/README.md index f75ec8c..55fd9e4 100644 --- a/sash-libs/sash-parse/README.md +++ b/sash-libs/sash-parse/README.md @@ -19,7 +19,7 @@ An example of all the flag types we support with sash-parse are below: Not to mention sash-parse also supports "STDIN" text which is text that appears after all flags. So for example: -``` +```bash $ ARR=("a|apples") $ __sash_parse_args "-a=test $(echo "sup")" "${ARR[@]}" $ echo "${__sash_parse_results[__STDIN]}" @@ -36,7 +36,7 @@ file that you can then read yourself. ## API ## -``` +```bash # __sash_parse_args(to_parse: String, flags: Array) -> Int # # Modifies Variables: @@ -53,11 +53,12 @@ file that you can then read yourself. # 3 - User Spacing Error. # 4 - Got arg when expecting value. # 5 - Unknown Argument +__sash_parse_args() ``` An actual example: -``` +```bash $ ARR=("a|apples" "b|bacon" "c|choco" "d|dark-choco" "e|eclair" "flags" "going" "home" "in" "j|jackets") $ __sash_parse_args "-a -b 10 -c \"is good\" -d=hey -e=\"a value with spaces\" --flags --going 10 --home \"or are they\" --in=10 --jackets=\"possibly maybe\"" "${ARR[@]}" $ echo "${!__sash_parse_results[@]}" diff --git a/sash-libs/sash-parse/sash-parse.sh b/sash-libs/sash-parse/sash-parse.sh index 51d2494..c90c968 100755 --- a/sash-libs/sash-parse/sash-parse.sh +++ b/sash-libs/sash-parse/sash-parse.sh @@ -29,12 +29,19 @@ # S.A.S.H. is the main way to add things to your ~/.bashrc and still # maintain structure. -if [[ "x$SASH_ERR_DIR" == "x" ]]; then - source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../sash-err-stack/sash-err-stack.sh" -else - source "$SASH_ERR_DIR/sash-err-stack.sh" +declare -f __sash_pop_err_mode_stack >/dev/null +__sash_parse_intermediate_check="$?" + +if [[ "$__sash_parse_intermediate_check" == "1" ]]; then + if [[ "x$SASH_ERR_DIR" == "x" ]]; then + source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../sash-err-stack/sash-err-stack.sh" + else + source "$SASH_ERR_DIR/sash-err-stack.sh" + fi fi +unset __sash_parse_intermediate_check + # __sash_strip_quotes(to_strip: String) -> String # # to_strip: @@ -43,13 +50,13 @@ __sash_strip_quotes() { __sash_guard_errors local to_strip="$1" - if [[ "$to_strip" =~ ^\".*$ ]]; then - to_strip="$(echo "$to_strip" | cut -c 2-)" + if [[ "$to_strip" =~ ^\" ]]; then + to_strip="$(printf '%s' "$to_strip" | cut -c 2-)" fi - if [[ "$to_strip" =~ ^.*\"$ ]]; then - to_strip="$(echo "$to_strip" | rev | cut -c 2- | rev)" + if [[ "$to_strip" =~ \"$ ]]; then + to_strip="$(printf '%s' "$to_strip" | rev | cut -c 2- | rev)" fi - echo "$to_strip" + printf '%s' "$to_strip" } # __sash_split_str(string_to_split: String, split_by: String) -> Array @@ -61,31 +68,16 @@ __sash_strip_quotes() { __sash_split_str() { __sash_guard_errors - local to_split="$1" - local split_by="$2" - - local trapped_sigint="$(_sash_get_trapped_text SIGINT)" - local trapped_sigquit="$(_sash_get_trapped_text SIGQUIT)" - - local SAVEIFS="$IFS" - _sash_safe_add_to_trap "IFS=$SAVEIFS" "SIGINT" - _sash_safe_add_to_trap "IFS=$SAVEIFS" "SIGQUIT" - IFS=$split_by - local split - read -a split <<< "$to_split" - IFS=$SAVEIFS - if [[ "x$trapped_sigint" != "x" ]]; then - trap "$trapped_sigint" SIGINT - else - trap - SIGINT - fi - if [[ "x$trapped_sigquit" != "x" ]]; then - trap "$trapped_sigquit" SIGQUIT - else - trap - SIGQUIT - fi + local readonly to_split="$1" + local readonly split_by="$2" - printf '%s ' "${split[@]}" + ( \ + SAVE_IFS="$IFS" && \ + IFS="$split_by" && \ + read -a split_text <<< "$to_split" && \ + IFS="$SAVE_IFS" && \ + printf '%s ' "${split_text[@]}" \ + ) } # __sash_check_duplicate__key(key_to_check: String, known_flags: Array) -> Int @@ -99,48 +91,44 @@ __sash_split_str() { __sash_check_duplicate_key() { __sash_guard_errors - local key_to_check="$1" + local readonly key_to_check="$1" + local split_provided_key= + local has_one= shift - local flags=("$@") - local iter + local readonly flags=("$@") + local iter= - local split_provided_key=($(__sash_split_str "$key_to_check" "|")) + if [[ "$key_to_check" =~ \| ]]; then + split_provided_key=($(__sash_split_str "$key_to_check" "|")) + has_one="false" + else + split_provided_key=("$key_to_check") + has_one="true" + fi - # For Each Flag We Know about. for iter in "${flags[@]}"; do - # Split the known flag up. - local split_known_flag=($(__sash_split_str "$iter" "|")) - # If the known flag only had it's long arg provided. - if [[ "${#split_known_flag[@]}" == "1" ]]; then - if [[ "${#split_provided_key[@]}" == "1" ]]; then - # If the key we're checking against only had it's long arg provided. - if [[ "${split_known_flag[0]}" == "${split_provided_key[0]}" ]]; then + if [[ "$iter" =~ \| ]]; then + local readonly split_known_flag=($(__sash_split_str "$iter" "|")) + + if [[ "$has_one" == "true" ]]; then + if [[ "${split_provided_key[0]}" == "${split_known_flag[1]}" ]]; then return 1 fi else - # Otherwise, Check the long key only. - if [[ "${split_known_flag[0]}" == "${split_provided_key[1]}" ]]; then + if [[ "${split_provided_key[0]}" == "${split_known_flag[0]}" ]] || [[ "${split_provided_key[1]}" == "${split_known_flag[1]}" ]]; then return 1 fi fi - else - # If the key we're checking against only has a long arg. - if [[ "${#split_provided_key[@]}" == "1" ]]; then - # Only check the long arg. - if [[ "${split_known_flag[1]}" == "${split_provided_key[0]}" ]]; then + if [[ "$has_one" == "true" ]]; then + if [[ "$iter" == "${split_provided_key[0]}" ]]; then return 1 fi else - # Otherwise check both short, and long. - if [[ "${split_known_flag[0]}" == "${split_provided_key[0]}" ]]; then - return 1 - fi - if [[ "${split_known_flag[1]}" == "${split_provided_key[1]}" ]]; then + if [[ "$iter" == "${split_provided_key[1]}" ]]; then return 1 fi fi - fi done @@ -158,38 +146,33 @@ __sash_find_key_for_arg() { local key_to_attempt_a_match="$1" # Properly match: `-d=arg` arguments. - local split_by_equals=($(__sash_split_str "$key_to_attempt_a_match" "=")) - key_to_attempt_a_match="${split_by_equals[0]}" + if [[ "$key_to_attempt_a_match" =~ = ]]; then + local readonly split_by_equals=($(__sash_split_str "$key_to_attempt_a_match" "=")) + key_to_attempt_a_match="${split_by_equals[0]}" + fi + shift - local flags=("$@") - local iter + local readonly flags=("$@") + local iter= # For Each Flag We Know about. for iter in "${flags[@]}"; do # Split the known flag up. - local split_known_flags=($(__sash_split_str "$iter" "|")) + if [[ "$iter" =~ \| ]]; then + local readonly split_known_flags=($(__sash_split_str "$iter" "|")) - if [[ "${#split_known_flags[@]}" == "1" ]]; then - if [[ "$key_to_attempt_a_match" =~ ^\-\-.*$ ]]; then - if [[ "$key_to_attempt_a_match" == "--${split_known_flags[0]}" ]]; then - echo "${split_known_flags[0]}" - return 0 - fi - else - # This arg doesn't have a short flag and one was provided. - continue + if [[ "$key_to_attempt_a_match" == "--${split_known_flags[1]}" ]]; then + printf '%s' "${split_known_flags[1]}" + return 0 + fi + if [[ "$key_to_attempt_a_match" == "-${split_known_flags[0]}" ]]; then + printf '%s' "${split_known_flags[1]}" + return 0 fi else - if [[ "$key_to_attempt_a_match" =~ ^\-\-.*$ ]]; then - if [[ "$key_to_attempt_a_match" == "--${split_known_flags[1]}" ]]; then - echo "${split_known_flags[1]}" - return 0 - fi - else - if [[ "$key_to_attempt_a_match" == "-${split_known_flags[0]}" ]]; then - echo "${split_known_flags[1]}" - return 0 - fi + if [[ "$key_to_attempt_a_match" == "--${iter}" ]]; then + printf '%s' "${iter}" + return 0 fi fi done @@ -210,17 +193,24 @@ __sash_find_key_for_arg() { # 0 - No Error # 1 - Flag Provided was invalid in some way. # 2 - Subset of error code 1, flag was duplicated. -# 3 - User Spacing Error. +# 3 - Unused. # 4 - Got arg when expecting value. # 5 - Unknown Argument __sash_parse_args() { __sash_allow_errors - local to_parse_str="$1" - local to_parse=($(__sash_split_str "$to_parse_str" " ")) + unset __sash_parse_results + declare -A -g __sash_parse_results + + local readonly to_parse_str="$1" + local readonly to_parse=($(__sash_split_str "$to_parse_str" " ")) # easiest way to parse the array is to just shift away the first arg. shift + # Check that we weren't just passed a string with an empty array. + if [[ "x$1" == "x" ]]; then + return 0 + fi local flags=("$@") local provided_flag @@ -228,21 +218,21 @@ __sash_parse_args() { local sash_known_flags=() for provided_flag in "${flags[@]}"; do - if [[ ! "$provided_flag" =~ [A-Za-z|-]+ ]]; then - echo "Invalid Argument Flag, Unknown Chars: [ $provided_flag ]!" >&2 + if [[ ! "$provided_flag" =~ [A-Z0-9a-z\-]+ ]]; then + printf '%s\n' "Invalid Argument Flag, Unknown Chars: [ $provided_flag ]!" >&2 return 1 fi - local count_of_pipe="$(echo "$provided_flag" | tr -cd '|' | wc -c)" + local count_of_pipe="$(printf '%s' "$provided_flag" | tr -cd '|' | wc -c)" if [[ "$count_of_pipe" != "0" && "$count_of_pipe" != "1" ]]; then - echo "Invalid Argument Flag, Too Many Pipes: [ $provided_flag ], Count: [ $count_of_pipe ]!" >&2 + printf '%s\n' "Invalid Argument Flag, Too Many Pipes: [ $provided_flag ], Count: [ $count_of_pipe ]!" >&2 return 1 fi __sash_check_duplicate_key "$provided_flag" "${sash_known_flags[@]}" local retV=$? if [[ "$retV" != "0" ]]; then - echo "Duplicate Flag: [ $provided_flag ]!" >&2 + printf '%s\n' "Duplicate Flag: [ $provided_flag ]!" >&2 return 2 fi @@ -263,9 +253,6 @@ __sash_parse_args() { local value_to_write_to="" local str_buffer="" - unset __sash_parse_results - declare -A -g __sash_parse_results - local current_user_arg for current_user_arg in "${to_parse[@]}"; do if [[ "$state" == "3" ]]; then @@ -274,21 +261,16 @@ __sash_parse_args() { fi if [[ "$state" == "2" ]]; then - if [[ "$current_user_arg" =~ .*\".* ]]; then - if [[ "$current_user_arg" =~ ^.*\"$ ]]; then - local stripped="$(__sash_strip_quotes "$current_user_arg")" - str_buffer="$str_buffer $stripped" - - # Append to array - __sash_parse_results["$value_to_write_to"]="$str_buffer" - str_buffer="" - value_to_write_to="" - state=0 - continue - else - echo "Ran into unknown state at str: [ $current_user_arg ]! Please seperate quoted strings from the next value with a space!" >&2 - return 3 - fi + if [[ "$current_user_arg" =~ \"$ ]]; then + local stripped="$(__sash_strip_quotes "$current_user_arg")" + str_buffer="$str_buffer $stripped" + + # Append to array + __sash_parse_results["$value_to_write_to"]="$str_buffer" + str_buffer="" + value_to_write_to="" + state=0 + continue else # If we don't contain a quote just add to buffer. str_buffer="$str_buffer $current_user_arg" @@ -297,8 +279,8 @@ __sash_parse_args() { fi if [[ "$state" == "1" ]]; then - if [[ ! "$current_user_arg" =~ ^\-.*$ ]]; then - if [[ "$current_user_arg" =~ ^\".*$ ]]; then + if [[ ! "$current_user_arg" =~ ^\- ]]; then + if [[ "$current_user_arg" =~ ^\" ]]; then if [[ "$current_user_arg" =~ ^\".*\"$ ]]; then # If we end with a quote we have a full string. local stripped="$(__sash_strip_quotes "$current_user_arg")" @@ -322,7 +304,7 @@ __sash_parse_args() { fi fi - if [[ "$current_user_arg" =~ ^\-.* ]]; then + if [[ "$current_user_arg" =~ ^\- ]]; then if [[ "$state" == "1" ]]; then __sash_parse_results["$value_to_write_to"]="0" state=0 @@ -332,7 +314,7 @@ __sash_parse_args() { local key_to_write_to="$(__sash_find_key_for_arg "$current_user_arg" "${sash_known_flags[@]}")" if [[ "x$key_to_write_to" == "x" ]]; then - echo "Unknown Arg: [ $current_user_arg ]!" >&2 + printf '%s\n' "Unknown Arg: [ $current_user_arg ]!" >&2 return 5 fi @@ -361,9 +343,9 @@ __sash_parse_args() { fi done - if [[ "$equal_sign_buff" =~ ^\".*$ ]]; then + if [[ "$equal_sign_buff" =~ ^\" ]]; then local stripped="$(__sash_strip_quotes "$equal_sign_buff")" - if [[ "$equal_sign_buff" =~ ^\".*\"$ ]]; then + if [[ "$equal_sign_buff" =~ \"$ ]]; then # We have a full string. __sash_parse_results["$key_to_write_to"]="$stripped" continue @@ -381,7 +363,7 @@ __sash_parse_args() { fi else # No Start of an arg, must be in extra values passed in. - state=4 + state=3 if [[ "x$str_buffer" == "x" ]]; then str_buffer="$current_user_arg" else diff --git a/sash-libs/sash-parse/tests/test-cases/sash-parse-all.sh b/sash-libs/sash-parse/tests/test-cases/sash-parse-all.sh new file mode 100755 index 0000000..ebaad82 --- /dev/null +++ b/sash-libs/sash-parse/tests/test-cases/sash-parse-all.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../../sash-err-stack/sash-err-stack.sh" +source "$SCRIPT_DIR/../../sash-parse.sh" + +set -e + +ARR=("a|apples" "b|bacon" "c|choco" "d|dark-choco" "e|eclair" "flags" "going" "home" "in" "j|jackets") +__sash_parse_args "-a -b 10 -c \"is good\" -d=hey -e=\"a value with spaces\" --flags --going 10 --home \"or are they\" --in=10 --jackets=\"possibly maybe\" here is some extra flags" "${ARR[@]}" + +echo "${!__sash_parse_results[@]}" | grep "jackets" | grep "apples" | grep "__STDIN" | grep "dark-choco" | grep "in" | grep "flags" | grep "going" | grep "choco" | grep "bacon" | grep "eclair" | grep "home" >/dev/null 2>&1 +echo "${__sash_parse_results[apples]}" +echo "${__sash_parse_results[bacon]}" +echo "${__sash_parse_results[choco]}" +echo "${__sash_parse_results[dark-choco]}" +echo "${__sash_parse_results[eclair]}" +echo "${__sash_parse_results[flags]}" +echo "${__sash_parse_results[going]}" +echo "${__sash_parse_results[home]}" +echo "${__sash_parse_results[in]}" +echo "${__sash_parse_results[jackets]}" +echo "${__sash_parse_results[__STDIN]}" diff --git a/sash-libs/sash-parse/tests/test-cases/sash-parse-duplicate-flag.sh b/sash-libs/sash-parse/tests/test-cases/sash-parse-duplicate-flag.sh new file mode 100755 index 0000000..fc7defd --- /dev/null +++ b/sash-libs/sash-parse/tests/test-cases/sash-parse-duplicate-flag.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../../sash-err-stack/sash-err-stack.sh" +source "$SCRIPT_DIR/../../sash-parse.sh" + +set -e + +ARR=("a|aa" "b|bb" "a|aa") +__sash_parse_args "-a 10" "${ARR[@]}" diff --git a/sash-libs/sash-parse/tests/test-cases/sash-parse-invalid-flags.sh b/sash-libs/sash-parse/tests/test-cases/sash-parse-invalid-flags.sh new file mode 100755 index 0000000..a264bf1 --- /dev/null +++ b/sash-libs/sash-parse/tests/test-cases/sash-parse-invalid-flags.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../../sash-err-stack/sash-err-stack.sh" +source "$SCRIPT_DIR/../../sash-parse.sh" + +ARR=("@|@@") +__sash_parse_args "-@ 10" "${ARR[@]}" +retV=$? +if [[ "$retV" != "1" ]]; then + echo "@ wasn't marked as invalid!" >&2 + exit 10 +fi + +ARR=("a|apples|allples") +__sash_parse_args "-a 10" "${ARR[@]}" +retV=$? +if [[ "$retV" != "1" ]]; then + echo "too many pipes wasn't marked as invalid!" >&2 + exit 10 +fi diff --git a/sash-libs/sash-parse/tests/test-parse.bats b/sash-libs/sash-parse/tests/test-parse.bats new file mode 100644 index 0000000..a5fbc94 --- /dev/null +++ b/sash-libs/sash-parse/tests/test-parse.bats @@ -0,0 +1,30 @@ +#!/usr/bin/env bats + +@test "__sash_parse_args can parse all manner of flags, and stdin" { + run $BATS_TEST_DIRNAME/test-cases/sash-parse-all.sh + [ "$status" -eq "0" ] + [ "${lines[0]}" = "0" ] + [ "${lines[1]}" = "10" ] + [ "${lines[2]}" = "is good" ] + [ "${lines[3]}" = "hey" ] + [ "${lines[4]}" = "a value with spaces" ] + [ "${lines[5]}" = "0" ] + [ "${lines[6]}" = "10" ] + [ "${lines[7]}" = "or are they" ] + [ "${lines[8]}" = "10" ] + [ "${lines[9]}" = "possibly maybe" ] + [ "${lines[10]}" = "here is some extra flags" ] +} + +@test "__sash_parse_args rejects invalid flags" { + run $BATS_TEST_DIRNAME/test-cases/sash-parse-invalid-flags.sh + [ "$status" -eq "0" ] + [ "${lines[0]}" = "Invalid Argument Flag, Unknown Chars: [ @|@@ ]!" ] + [ "${lines[1]}" = "Invalid Argument Flag, Too Many Pipes: [ a|apples|allples ], Count: [ 2 ]!" ] +} + +@test "__sash_parse_args rejects duplicate flags" { + run $BATS_TEST_DIRNAME/test-cases/sash-parse-duplicate-flag.sh + [ "$status" -eq "2" ] + [ "${lines[0]}" = "Duplicate Flag: [ a|aa ]!" ] +} diff --git a/sash-libs/sash-trap/README.md b/sash-libs/sash-trap/README.md new file mode 100644 index 0000000..b44fe8b --- /dev/null +++ b/sash-libs/sash-trap/README.md @@ -0,0 +1,53 @@ +# Sash-Trap # + +sash-trap gives you the ability to "safely" add to traps, recursively. `trap` +ends up overwriting everything which can be quite unpleasent when you're being +called from a script that needs traps (and you have to respect their traps). + +sash-trap works around that by automatically detecting previously set traps, +and "safely" adding to them by seperating commands with: `;` (even if the +user didn't add one themselves.) + +## Supported Architectures ## + +* Bash v3 compatible, but only tested with Bash v4. + +## API ## + +```bash +# _sash_get_trapped_text(signal: String) +# +# Modifies Variables: None +# +# parses trap output to get you the command for a signal. +_sash_get_trapped_text() + +# _sash_safe_add_to_trap(command: String, signal: String) +# +# Modifies Variables: None +# +# safely adds a command to a trap. +# +# NOTE: command should not end with a: `;` +_sash_safe_add_to_trap() +``` + +That's it! Nothing complex. Just the signal you want to add too, +and the command you want to add. Note: If you plan on removing +it later. Simply grab the original trapped text with: +`_sash_get_trapped_text` before calling `_sash_safe_add_to_trap`. + +E.g. something like: + +``` +to_restore=$(_sash_get_trapped_text "SIGINT") +_sash_safe_add_to_trap "SIGINT" "printf '%s' 'sigint hit'" + +(echo 'blah blah') + +if [[ "x$to_restore" != "x" ]]; then # Can't trap an empty string. + trap "$to_restore" SIGINT +else + trap - SIGINT +fi +``` diff --git a/sash-libs/sash-trap/sash-trap.sh b/sash-libs/sash-trap/sash-trap.sh new file mode 100755 index 0000000..1d42bc7 --- /dev/null +++ b/sash-libs/sash-trap/sash-trap.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# _sash_get_trapped_text(signal: String) +# +# Modifies Variables: None +# +# parses trap output to get you the command for a signal. +_sash_get_trapped_text() { + printf '%s' "$(trap -p "$1" | sed "s/trap -- '//g; s/' $1$//g; s/\\\''//g")" +} + +# _sash_safe_add_to_trap(command: String, signal: String) +# +# Modifies Variables: None +# +# safely adds a command to a trap. +# +# NOTE: command should not end with a: `;` +_sash_safe_add_to_trap() { + local command_to_add="$1" + local signal="$2" + + if [[ "x$(trap -p "$signal")" == "x" ]]; then + trap "$command_to_add" "$signal" + else + local trapped_text="$(_sash_get_trapped_text "$signal")" + if [[ ! "$trapped_text" =~ \;$ ]]; then + trap "$trapped_text; $command_to_add;" "$signal" + else + trap "$trapped_text $command_to_add;" "$signal" + fi + fi +} diff --git a/sash-libs/sash-trap/tests/test-cases/test-add-multiple-to-empty-trap.sh b/sash-libs/sash-trap/tests/test-cases/test-add-multiple-to-empty-trap.sh new file mode 100755 index 0000000..f53e079 --- /dev/null +++ b/sash-libs/sash-trap/tests/test-cases/test-add-multiple-to-empty-trap.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-trap.sh" + +function onTrap() { + echo "onTrap" +} + +( \ + trap - "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + kill -s SIGALRM $BASHPID \ +) diff --git a/sash-libs/sash-trap/tests/test-cases/test-add-to-empty-trap.sh b/sash-libs/sash-trap/tests/test-cases/test-add-to-empty-trap.sh new file mode 100755 index 0000000..8de8119 --- /dev/null +++ b/sash-libs/sash-trap/tests/test-cases/test-add-to-empty-trap.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-trap.sh" + +function onTrap() { + echo "onTrap" +} + +( \ + trap - "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + kill -s SIGALRM $BASHPID \ +) diff --git a/sash-libs/sash-trap/tests/test-cases/test-simple-get-tt.sh b/sash-libs/sash-trap/tests/test-cases/test-simple-get-tt.sh new file mode 100755 index 0000000..fd0e23b --- /dev/null +++ b/sash-libs/sash-trap/tests/test-cases/test-simple-get-tt.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-trap.sh" + +function onTrap() { + echo "onTrap" +} + +( \ + trap - "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + _sash_safe_add_to_trap "onTrap" "SIGALRM" && \ + _sash_get_trapped_text "SIGALRM" +) diff --git a/sash-libs/sash-trap/tests/test-cases/test-simple-quote-get-tt.sh b/sash-libs/sash-trap/tests/test-cases/test-simple-quote-get-tt.sh new file mode 100755 index 0000000..6c1bd11 --- /dev/null +++ b/sash-libs/sash-trap/tests/test-cases/test-simple-quote-get-tt.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SCRIPT_DIR/../../sash-trap.sh" + +( \ + trap - "SIGALRM" && \ + _sash_safe_add_to_trap "echo 'hey \"hello\" \\\"sup\\\"'" "SIGALRM" && \ + _sash_get_trapped_text "SIGALRM" +) diff --git a/sash-libs/sash-trap/tests/test-trap.bats b/sash-libs/sash-trap/tests/test-trap.bats new file mode 100644 index 0000000..ce1d185 --- /dev/null +++ b/sash-libs/sash-trap/tests/test-trap.bats @@ -0,0 +1,29 @@ +#!/usr/bin/env bats + +@test "_sash_safe_add_to_trap can add to an empty trap" { + run $BATS_TEST_DIRNAME/test-cases/test-add-to-empty-trap.sh + [ "$status" -eq "0" ] + [ "${lines[0]}" = "onTrap" ] + [ "${#lines[@]}" = "1" ] +} + +@test "_sash_safe_add_to_trap can add to an empty trap multiple times" { + run $BATS_TEST_DIRNAME/test-cases/test-add-multiple-to-empty-trap.sh + [ "$status" -eq "0" ] + [ "${lines[0]}" = "onTrap" ] + [ "${lines[1]}" = "onTrap" ] + [ "${lines[2]}" = "onTrap" ] + [ "${#lines[@]}" = "3" ] +} + +@test "_sash_get_trapped_text can print out a trap" { + run $BATS_TEST_DIRNAME/test-cases/test-simple-get-tt.sh + [ "$status" -eq "0" ] + [ "${lines[0]}" = "onTrap; onTrap; onTrap;" ] +} + +@test "_sash_get_trapped_text can print out a quoted trap" { + run $BATS_TEST_DIRNAME/test-cases/test-simple-quote-get-tt.sh + [ "$status" -eq "0" ] + [ "${lines[0]}" = "echo 'hey \"hello\" \\\"sup\\\"'" ] +} diff --git a/sash.sh b/sash.sh index 5fd9852..84dc749 100755 --- a/sash.sh +++ b/sash.sh @@ -12,8 +12,9 @@ # Subgroups are things within that, e.g. "Rust", and "Ruby" would be subgroups in "languages" EDITOR=${EDITOR:-vim} -SASH_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +export SASH_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$SASH_DIR/sash-libs/sash-trap/sash-trap.sh" source "$SASH_DIR/sash-libs/sash-err-stack/sash-err-stack.sh" source "$SASH_DIR/sash-utils/sash-utils.sh" @@ -100,9 +101,6 @@ if [[ -d "$HOME/.bash/plugins/post" ]]; then fi source "$SASH_DIR/sash-libs/sash-parse/sash-parse.sh" - -source "$SASH_DIR/sash-add.sh" -source "$SASH_DIR/sash-show.sh" -source "$SASH_DIR/sash-package.sh" +source "$SASH_DIR/sash-command-handler.sh" export SASH_RUNNING=1 diff --git a/sash-add.sh b/subcommands/sash-add.sh similarity index 97% rename from sash-add.sh rename to subcommands/sash-add.sh index 055946c..dd24e30 100755 --- a/sash-add.sh +++ b/subcommands/sash-add.sh @@ -25,14 +25,14 @@ _sash_create_or_choose_subcategory() { fi } -# sash_add() -> None +# sash:add() -> None # # Modifies Variables: # - _sash_add_filename # # allows the user to add content to their ~/.bashrc in a structured # and sensible way. -sash_add() { +sash:add() { __sash_guard_errors echo "Please Choose a Category: " @@ -42,6 +42,7 @@ sash_add() { mkdir -p "$HOME/.bash/plugins/$_sash_add_filename" category="$HOME/.bash/plugins/$_sash_add_filename" fi + local is_post="0" if [[ "$category" == "$HOME/.bash/plugins/post" ]]; then is_post="1" @@ -50,14 +51,17 @@ sash_add() { local subcategory="$(_sash_create_or_choose_subcategory $category)" subcategory="${subcategory#./}" fi + if ! _sash_get_multiline_input "# Please insert what you want to add to your bashrc below:" ""; then exit 1 fi local content_to_add="$sash_multiline_content" + if ! _sash_get_multiline_input "Please type what you want to be commented above this."; then exit 1 fi local content_to_comment="$sash_multiline_content" + echo "Current Files you can append to are:" if [[ "$is_post" == "1" ]]; then for _sash_show_existing_filename in $category/*; do @@ -108,3 +112,10 @@ sash_add() { echo "[+] Added, and sourced!" } +# sash_add() +# +# alias to sash:add +sash_add() { + sash:add + return $? +} diff --git a/sash-package.sh b/subcommands/sash-package.sh similarity index 95% rename from sash-package.sh rename to subcommands/sash-package.sh index 4d13ea9..33b3596 100755 --- a/sash-package.sh +++ b/subcommands/sash-package.sh @@ -120,6 +120,11 @@ _sash_package_category() { return 0 } +# __sash_append_to_root_of_tar_xz(tarxz_file: string, file: string) -> None +# +# Modifies Globals: None +# +# append a particular file to a .tar.xz file. __sash_append_to_root_of_tar_xz() { __sash_guard_errors @@ -135,12 +140,12 @@ __sash_append_to_root_of_tar_xz() { mv "$my_dir/tmp.tar.xz" "$tarxz_file" } -# sash_package(args: Array) -> Int +# sash:package(args: Array) -> Int # -# sash_package will package up a category, or sub category for you to distribute to your +# sash:package will package up a category, or sub category for you to distribute to your # friends. Note: Sash package will give you an option to filter out content for each file # incase of secrets, unless you specify: `--package-without-checks`. -sash_package() { +sash:package() { __sash_guard_errors local arguments="${@}" @@ -166,12 +171,14 @@ sash_package() { if [[ "${__sash_parse_results[package-without-checks]}" == "0" ]]; then run_checks="0" fi + if [[ "x${__sash_parse_results[category]}" == "x" ]]; then echo "[/] Please Choose a Category to Package: " category="$(_sash_choose_a_directory "$HOME/.bash/plugins/")" else category="$HOME/.bash/plugins/${__sash_parse_results[category]}" fi + if [[ ! -d "$category" ]]; then echo -e "${white}[${red}-${white}]${restore} Category: [$1] doesn't exist!" fi @@ -236,3 +243,11 @@ sash_package() { rm "sig.usr" fi } + +# sash_package() +# +# alias to sash:package +sash_package() { + sash:package "$@" + return $? +} diff --git a/sash-show.sh b/subcommands/sash-show.sh similarity index 93% rename from sash-show.sh rename to subcommands/sash-show.sh index 1a3e240..94e47b4 100755 --- a/sash-show.sh +++ b/subcommands/sash-show.sh @@ -45,14 +45,17 @@ _sash_materialize_view() { # Modifies Variables: None # # Implements the sash_show command. -sash_show() { +sash:show() { __sash_guard_errors + _args=$(__sash_split_str "$1" " ") + if [[ -n "$1" ]]; then local full_category="$HOME/.bash/plugins/$1" if [[ ! -d $full_category ]]; then echo -e "${white}[${red}-${white}]${restore} Category: [$1] doesn't exist!" fi + if [[ -n "$2" ]]; then _sash_materialize_view "$full_category" "$2" else @@ -64,8 +67,10 @@ sash_show() { _sash_materialize_view "$full_category" "$choice" fi fi + return fi + echo "Please Choose a Category:" local category="$(_sash_choose_a_directory "$HOME/.bash/plugins/" 1)" if [[ "$category" == "$HOME/.bash/plugins/post" ]]; then @@ -76,3 +81,10 @@ sash_show() { _sash_materialize_view "$category" "$choice" fi } + +# sash_show(category: Option, subcategory: Option) -> String +# +# alias to sash:show +sash_show() { + sash:show "$@" +}