diff --git a/Makefile b/Makefile index adf36b9..b1f4812 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ OUT_DIR = dist OUTPUT = $(OUT_DIR)/beddu.sh SRC_DIR = src DEMO_DIR = demo +README = README.md YEAR = $(shell date +%Y) IP = $(shell curl -s ipinfo.io/ip) @@ -29,35 +30,48 @@ demo: build _release: @if [ -z "$(filter-out $@,$(MAKECMDGOALS))" ]; then \ - echo "Error: Please specify a version number (e.g. make release v0.0.5)"; \ + echo "❗User Error: Please specify a version number (e.g. make _release v0.0.5)"; \ exit 1; \ fi $(eval VERSION := $(filter-out $@,$(MAKECMDGOALS))) + @if [ "$$(git branch --show-current)" != "main" ]; then \ + echo "❗User Error: Releases can only be made from the main branch"; \ + exit 1; \ + fi @if ! git diff-index --quiet HEAD --; then \ - echo "Error: Git working directory is not clean. Please commit or stash your changes first."; \ + echo "❗User Error: Git working directory is not clean. Please commit or stash your changes first."; \ exit 1; \ fi; \ - $(MAKE) build; \ - sed -i '' "s/# Version: .*/# Version: $(VERSION)/" $(OUTPUT); \ - git add $(OUTPUT); \ + $(MAKE) build + @echo "" + @sed -i '' "s/# Version: .*/# Version: $(VERSION)/" $(OUTPUT); \ + sed -i '' -E "s/v[0-9]+\.[0-9]+\.[0-9]+/$(VERSION)/" $(README) + @git add $(OUTPUT) $(README); \ git commit -m "Release $(VERSION)"; \ git tag -a "$(VERSION)" -m "Release $(VERSION)" - @echo "\nRelease complete: \033[32m$(VERSION)\033[0m" + @echo "" + @git push --follow-tags + @echo "" + @gh release create "$(VERSION)" --generate-notes --title "⚡ $(VERSION)" "$(OUTPUT)#beddu.sh" + @echo "\n\033[32m✔︎\033[0m Release complete: \033[32m$(VERSION)\033[0m" # Get the last version tag and increment the appropriate part release-patch: + @echo "" @LAST_VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"); \ NEW_VERSION=$$(echo $$LAST_VERSION | awk -F. '{print $$1"."$$2"."$$3+1}'); \ echo "Bumping patch version from $$LAST_VERSION to $$NEW_VERSION"; \ $(MAKE) _release $$NEW_VERSION release-minor: + @echo "" @LAST_VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"); \ NEW_VERSION=$$(echo $$LAST_VERSION | awk -F. '{print $$1"."$$2+1".0"}'); \ echo "Bumping minor version from $$LAST_VERSION to $$NEW_VERSION"; \ $(MAKE) _release $$NEW_VERSION release-major: + @echo "" @LAST_VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"); \ NEW_VERSION=$$(echo $$LAST_VERSION | awk -F. '{print "v"$$2+1".0.0"}'); \ echo "Bumping major version from $$LAST_VERSION to $$NEW_VERSION"; \ @@ -67,6 +81,7 @@ release-major: @: $(OUTPUT): $(ALL_SRC_FILES) + @echo "" @mkdir -p $(OUT_DIR) @echo '#!/usr/bin/env bash' > $(OUTPUT) @echo '# shellcheck disable=all' >> $(OUTPUT) @@ -83,8 +98,9 @@ $(OUTPUT): $(ALL_SRC_FILES) grep -v '^\s*#\|^source \|^SCRIPT_DIR=\|^readonly BEDDU_.*_LOADED\|^\[\[ \$$BEDDU_.*_LOADED \]\]' "$$file" | sed '/^[[:space:]]*$$/d' | sed 's/#[a-zA-Z0-9 ]*$$//' >> $(OUTPUT); \ done @chmod +x $(OUTPUT) - @echo "\nBuild complete: \033[32m$(OUTPUT)\033[0m" + @echo "\033[32m✔︎\033[0m Build complete: \033[32m$(OUTPUT)\033[0m" clean: + @echo "" @rm -rf $(OUT_DIR) - @echo "\nClean up completed." \ No newline at end of file + @echo "\033[32m✔︎\033[0m Clean up completed." \ No newline at end of file diff --git a/README.md b/README.md index facdb86..9ce4972 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Beddu +# Beddu 💅🏻 A lightweight bash framework for interactive scripts with pretty output. @@ -22,21 +22,17 @@ And you will easily be able to build things like: - **Visual Indicators**: Spinners, checkmarks, and error symbols - **Line Manipulation**: Replace previous output for dynamic updates -## Installation +## Installation and Usage -Clone the repository or download `beddu.sh` to your project: +**Beddu** is meant to be sourced in your own script. + +1. Download the latest release (currently: **v1.1.0**) of `beddu.sh` to your project: ```bash -# Clone the repository -git clone https://github.com/mjsarfatti/beddu.git - -# Or just download the compiled script -curl -O https://raw.githubusercontent.com/mjsarfatti/beddu/main/beddu.sh +$ curl -O https://raw.githubusercontent.com/mjsarfatti/beddu/refs/tags/v1.1.0/dist/beddu.sh ``` -## Usage - -Source the `beddu.sh` file in your script: +2. Source the `beddu.sh` file in your script: ```bash #!/usr/bin/env bash @@ -46,9 +42,18 @@ source "/path/to/beddu.sh" pen bold blue "Hello, world!" ``` +## Demo + +To see it in action, clone the repository, then run `make demo`. This will run the same interactive demo that you can see in the video above (please note that a 12MB wikimedia.org random file will be downloaded during the demo to showcase the functionality - a prompt will let you delete it at the end): + +```bash +$ git clone https://github.com/mjsarfatti/beddu.git +$ make demo +``` + ## Examples -More can be seen by looking at the [demo](./beddu.sh) file, but here is a quick overview: +More can be seen by looking at the [demo](./demo/demo.sh) file, but here is a quick overview: ### Text Formatting and Colors @@ -73,10 +78,15 @@ pen "This is $(pen yellow "yellow"), and this is $(pen bold "bold")" ### Interactive Functions ```bash -# Ask for input -ask name "What's your name?" +# Kindly ask for input (empty answer is accepted) +seek name "What's your name?" pen "Hello, $name!" +# Firmly ask for input (empty answer NOT accepted) +request name "No really, what's your name?" +pen "There you go, $name!" + + # Yes/no confirmation (defaults to "yes") if confirm "Continue?"; then pen green "Continuing..." @@ -114,14 +124,6 @@ sleep 1 check "Task completed!" # We can directly `check`, `warn`, or `throw` after a `spin` call - the message will always replace the spin line ``` -## Demo - -To see it in action paste the following command in your terminal: - -```bash -curl -s https://raw.githubusercontent.com/mjsarfatti/beddu/main/demo/demo.sh | bash -``` - ## Function Reference ### Text Formatting @@ -134,7 +136,8 @@ curl -s https://raw.githubusercontent.com/mjsarfatti/beddu/main/demo/demo.sh | b ### User Interaction -- `ask [retval] PROMPT` - Get text input from user, saves the answer in `$retval` +- `seek [retval] PROMPT` - Get (optional) text input from user, saves the answer in `$retval` +- `request [retval] PROMPT` - Like above, but doesn't accept an empty response, saves the answer in `$retval` - `confirm [OPTIONS] PROMPT` - Get yes/no input - `--default-yes` - Set default answer to "yes" (default behavior) - `--default-no` - Set default answer to "no" diff --git a/demo/asciinema.png b/demo/asciinema.png new file mode 100644 index 0000000..3e56468 Binary files /dev/null and b/demo/asciinema.png differ diff --git a/demo/carbon.png b/demo/carbon.png index 3e9a4e1..1271e27 100644 Binary files a/demo/carbon.png and b/demo/carbon.png differ diff --git a/demo/carbon.sh b/demo/carbon.sh index 09a425e..21723a8 100755 --- a/demo/carbon.sh +++ b/demo/carbon.sh @@ -2,20 +2,17 @@ . beddu.sh -line -pen purple "Hello, I'm your IP helper, here to help you will all your IP needs." -line +pen purple "Hello, I'm your IP helper, here for all your IP needs!" -choose action "What would you like to do?" "Get my IP" "Get my location" +choose ACTION "What would you like to do?" "Get my IP" "Get my location" -case "$action" in +case "$ACTION" in "Get my IP") - run --out ip curl ipinfo.io/ip - line; pen "Your IP is $ip" + run --out IP curl ipinfo.io/ip + pen "Your IP is $IP" ;; - "Get my location") - run --out location curl -s ipinfo.io/loc - line; pen "Your coordinates are $location" + "Get my LOCATION") + run --out LOCATION curl -s ipinfo.io/loc + pen "Your coordinates are $LOCATION" ;; esac - diff --git a/demo/demo.sh b/demo/demo.sh index b7086e5..7467257 100755 --- a/demo/demo.sh +++ b/demo/demo.sh @@ -102,7 +102,7 @@ demo() { pen $_pink italic "-- Interactive functions --" line - ask name "How can I call you?" + request name "How can I call you?" pen "Hello, $(pen bold cyan "${name:?}")" line diff --git a/dist/beddu.sh b/dist/beddu.sh index 00a24ce..9c7ac14 100755 --- a/dist/beddu.sh +++ b/dist/beddu.sh @@ -2,7 +2,7 @@ # shellcheck disable=all # # beddu.sh - A lightweight bash framework for interactive scripts and pretty output -# Version: v0.0.9 +# Version: v1.1.0 # # Copyright © 2025 Manuele Sarfatti # Licensed under the MIT license @@ -190,29 +190,6 @@ warn() { pen italic "$@" } -ask() { - local -n outvar="$1" - local prompt - local answer - prompt=$( - pen -n blue "${_q:-?} " - pen "${2}" - pen -n blue "${_a:-❯} " - ) - show_cursor - while true; do - read -r -p "$prompt" answer - case "$answer" in - "") - echo - warn "Please type your answer." - ;; - *) break ;; - esac - done - outvar="$answer" -} - choose() { local -n outvar="$1" local prompt @@ -309,3 +286,40 @@ confirm() { esac done } + +request() { + local -n outvar="$1" + local prompt + local answer + prompt=$( + pen -n blue "${_q:-?} " + pen "${2}" + pen -n blue "${_a:-❯} " + ) + show_cursor + while true; do + read -r -p "$prompt" answer + case "$answer" in + "") + echo + warn "Please type your answer." + ;; + *) break ;; + esac + done + outvar="$answer" +} + +seek() { + local -n outvar="$1" + local prompt + local answer + prompt=$( + pen -n blue "${_q:-?} " + pen "${2}" + pen -n blue "${_a:-❯} " + ) + show_cursor + read -r -p "$prompt" answer + outvar="$answer" +} diff --git a/images/SCR-20250507-taln.png b/images/SCR-20250507-taln.png deleted file mode 100644 index 5924a80..0000000 Binary files a/images/SCR-20250507-taln.png and /dev/null differ diff --git a/images/SCR-20250507-tbbw.png b/images/SCR-20250507-tbbw.png deleted file mode 100644 index 740e30a..0000000 Binary files a/images/SCR-20250507-tbbw.png and /dev/null differ diff --git a/src/03.prompt/ask.sh b/src/03.prompt/request.sh similarity index 82% rename from src/03.prompt/ask.sh rename to src/03.prompt/request.sh index a7c87cc..2130412 100644 --- a/src/03.prompt/ask.sh +++ b/src/03.prompt/request.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # shellcheck disable=SC1091 -# ask.sh - Get free text input from the user +# request.sh - Get required text input from the user [[ $BEDDU_ASK_LOADED ]] && return readonly BEDDU_ASK_LOADED=true @@ -11,14 +11,14 @@ source "$SCRIPT_DIR/../00.utils/movements.sh" source "$SCRIPT_DIR/../01.core/pen.sh" source "$SCRIPT_DIR/../02.ui/warn.sh" -# Ask a question and get a free text answer from the user +# Ask a question and require a free text answer from the user # # Usage: -# ask outvar text +# request outvar text # Example: -# ask name "What is your name?" +# request name "What is your name?" # echo "Hello, $name!" -ask() { +request() { local -n outvar="$1" # Declare nameref local prompt local answer diff --git a/src/03.prompt/seek.sh b/src/03.prompt/seek.sh new file mode 100644 index 0000000..a5e770f --- /dev/null +++ b/src/03.prompt/seek.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1091 +# seek.sh - Get free text input from the user + +[[ $BEDDU_ASK_LOADED ]] && return +readonly BEDDU_ASK_LOADED=true + +SCRIPT_DIR="$(dirname -- "${BASH_SOURCE[0]}")" +source "$SCRIPT_DIR/../00.utils/_symbols.sh" +source "$SCRIPT_DIR/../00.utils/movements.sh" +source "$SCRIPT_DIR/../01.core/pen.sh" +source "$SCRIPT_DIR/../02.ui/warn.sh" + +# Ask a question and get a free text answer from the user +# +# Usage: +# seek outvar text +# Example: +# seek name "What is your name?" +# echo "Hello, $name!" +seek() { + local -n outvar="$1" # Declare nameref + local prompt + local answer + + # Set prompt with default indicator + prompt=$( + pen -n blue "${_q:-?} " + pen "${2}" + pen -n blue "${_a:-❯} " + ) + + show_cursor + + # Get response + read -r -p "$prompt" answer + + # shellcheck disable=SC2034 + outvar="$answer" +}