Compare commits

...

10 commits
v0.0.9 ... main

Author SHA1 Message Date
Manuele Sarfatti
afcb9056ec Simpler Carbon example 2025-05-21 10:51:56 +02:00
Manuele Sarfatti
db9229cbd0 Release v1.1.0 2025-05-20 17:33:19 +02:00
Manuele Sarfatti
ce6bfcd04c Ask -> Request, while Seek makes the answer optional 2025-05-20 17:33:11 +02:00
Manuele Sarfatti
5ff6a50d32 Improve build output 2025-05-11 19:02:10 +02:00
Manuele Sarfatti
c39b85e2a6 Release v1.0.0 2025-05-11 18:53:19 +02:00
Manuele Sarfatti
175c4b9cca 1.0 build steps 2025-05-11 18:53:12 +02:00
Manuele Sarfatti
169efb7b7f Release v1.0.0 2025-05-11 18:31:28 +02:00
Manuele Sarfatti
06d06f73f2 💥 1.0
Fix Demo link, add GH release from Make and more
2025-05-11 18:30:57 +02:00
Manuele Sarfatti
881d91b43b Fix Demo README section 2025-05-11 17:11:55 +02:00
Manuele Sarfatti
16c840efff "Remove unneeded image" 2025-05-11 16:17:56 +02:00
11 changed files with 142 additions and 72 deletions

View file

@ -4,6 +4,7 @@ OUT_DIR = dist
OUTPUT = $(OUT_DIR)/beddu.sh OUTPUT = $(OUT_DIR)/beddu.sh
SRC_DIR = src SRC_DIR = src
DEMO_DIR = demo DEMO_DIR = demo
README = README.md
YEAR = $(shell date +%Y) YEAR = $(shell date +%Y)
IP = $(shell curl -s ipinfo.io/ip) IP = $(shell curl -s ipinfo.io/ip)
@ -29,35 +30,48 @@ demo: build
_release: _release:
@if [ -z "$(filter-out $@,$(MAKECMDGOALS))" ]; then \ @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; \ exit 1; \
fi fi
$(eval VERSION := $(filter-out $@,$(MAKECMDGOALS))) $(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 \ @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; \ exit 1; \
fi; \ fi; \
$(MAKE) build; \ $(MAKE) build
sed -i '' "s/# Version: .*/# Version: $(VERSION)/" $(OUTPUT); \ @echo ""
git add $(OUTPUT); \ @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 commit -m "Release $(VERSION)"; \
git tag -a "$(VERSION)" -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 # Get the last version tag and increment the appropriate part
release-patch: release-patch:
@echo ""
@LAST_VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"); \ @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}'); \ NEW_VERSION=$$(echo $$LAST_VERSION | awk -F. '{print $$1"."$$2"."$$3+1}'); \
echo "Bumping patch version from $$LAST_VERSION to $$NEW_VERSION"; \ echo "Bumping patch version from $$LAST_VERSION to $$NEW_VERSION"; \
$(MAKE) _release $$NEW_VERSION $(MAKE) _release $$NEW_VERSION
release-minor: release-minor:
@echo ""
@LAST_VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"); \ @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"}'); \ NEW_VERSION=$$(echo $$LAST_VERSION | awk -F. '{print $$1"."$$2+1".0"}'); \
echo "Bumping minor version from $$LAST_VERSION to $$NEW_VERSION"; \ echo "Bumping minor version from $$LAST_VERSION to $$NEW_VERSION"; \
$(MAKE) _release $$NEW_VERSION $(MAKE) _release $$NEW_VERSION
release-major: release-major:
@echo ""
@LAST_VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"); \ @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"}'); \ NEW_VERSION=$$(echo $$LAST_VERSION | awk -F. '{print "v"$$2+1".0.0"}'); \
echo "Bumping major version from $$LAST_VERSION to $$NEW_VERSION"; \ echo "Bumping major version from $$LAST_VERSION to $$NEW_VERSION"; \
@ -67,6 +81,7 @@ release-major:
@: @:
$(OUTPUT): $(ALL_SRC_FILES) $(OUTPUT): $(ALL_SRC_FILES)
@echo ""
@mkdir -p $(OUT_DIR) @mkdir -p $(OUT_DIR)
@echo '#!/usr/bin/env bash' > $(OUTPUT) @echo '#!/usr/bin/env bash' > $(OUTPUT)
@echo '# shellcheck disable=all' >> $(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); \ grep -v '^\s*#\|^source \|^SCRIPT_DIR=\|^readonly BEDDU_.*_LOADED\|^\[\[ \$$BEDDU_.*_LOADED \]\]' "$$file" | sed '/^[[:space:]]*$$/d' | sed 's/#[a-zA-Z0-9 ]*$$//' >> $(OUTPUT); \
done done
@chmod +x $(OUTPUT) @chmod +x $(OUTPUT)
@echo "\nBuild complete: \033[32m$(OUTPUT)\033[0m" @echo "\033[32m✔\033[0m Build complete: \033[32m$(OUTPUT)\033[0m"
clean: clean:
@echo ""
@rm -rf $(OUT_DIR) @rm -rf $(OUT_DIR)
@echo "\nClean up completed." @echo "\033[32m✔\033[0m Clean up completed."

View file

@ -1,4 +1,4 @@
# Beddu # Beddu 💅🏻
A lightweight bash framework for interactive scripts with pretty output. 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 - **Visual Indicators**: Spinners, checkmarks, and error symbols
- **Line Manipulation**: Replace previous output for dynamic updates - **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 ```bash
# Clone the repository $ curl -O https://raw.githubusercontent.com/mjsarfatti/beddu/refs/tags/v1.1.0/dist/beddu.sh
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
``` ```
## Usage 2. Source the `beddu.sh` file in your script:
Source the `beddu.sh` file in your script:
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
@ -46,9 +42,18 @@ source "/path/to/beddu.sh"
pen bold blue "Hello, world!" 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 ## 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 ### Text Formatting and Colors
@ -73,10 +78,15 @@ pen "This is $(pen yellow "yellow"), and this is $(pen bold "bold")"
### Interactive Functions ### Interactive Functions
```bash ```bash
# Ask for input # Kindly ask for input (empty answer is accepted)
ask name "What's your name?" seek name "What's your name?"
pen "Hello, $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") # Yes/no confirmation (defaults to "yes")
if confirm "Continue?"; then if confirm "Continue?"; then
pen green "Continuing..." 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 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 ## Function Reference
### Text Formatting ### Text Formatting
@ -134,7 +136,8 @@ curl -s https://raw.githubusercontent.com/mjsarfatti/beddu/main/demo/demo.sh | b
### User Interaction ### 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 - `confirm [OPTIONS] PROMPT` - Get yes/no input
- `--default-yes` - Set default answer to "yes" (default behavior) - `--default-yes` - Set default answer to "yes" (default behavior)
- `--default-no` - Set default answer to "no" - `--default-no` - Set default answer to "no"

BIN
demo/asciinema.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 185 KiB

Before After
Before After

View file

@ -2,20 +2,17 @@
. beddu.sh . beddu.sh
line pen purple "Hello, I'm your IP helper, here for all your IP needs!"
pen purple "Hello, I'm your IP helper, here to help you will all your IP needs."
line
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") "Get my IP")
run --out ip curl ipinfo.io/ip run --out IP curl ipinfo.io/ip
line; pen "Your IP is $ip" pen "Your IP is $IP"
;; ;;
"Get my location") "Get my LOCATION")
run --out location curl -s ipinfo.io/loc run --out LOCATION curl -s ipinfo.io/loc
line; pen "Your coordinates are $location" pen "Your coordinates are $LOCATION"
;; ;;
esac esac

View file

@ -102,7 +102,7 @@ demo() {
pen $_pink italic "-- Interactive functions --" pen $_pink italic "-- Interactive functions --"
line line
ask name "How can I call you?" request name "How can I call you?"
pen "Hello, $(pen bold cyan "${name:?}")" pen "Hello, $(pen bold cyan "${name:?}")"
line line

62
dist/beddu.sh vendored
View file

@ -2,7 +2,7 @@
# shellcheck disable=all # shellcheck disable=all
# #
# beddu.sh - A lightweight bash framework for interactive scripts and pretty output # beddu.sh - A lightweight bash framework for interactive scripts and pretty output
# Version: v0.0.9 # Version: v1.1.0
# #
# Copyright © 2025 Manuele Sarfatti # Copyright © 2025 Manuele Sarfatti
# Licensed under the MIT license # Licensed under the MIT license
@ -190,29 +190,6 @@ warn() {
pen italic "$@" 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() { choose() {
local -n outvar="$1" local -n outvar="$1"
local prompt local prompt
@ -309,3 +286,40 @@ confirm() {
esac esac
done 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"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# shellcheck disable=SC1091 # 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 [[ $BEDDU_ASK_LOADED ]] && return
readonly BEDDU_ASK_LOADED=true 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/../01.core/pen.sh"
source "$SCRIPT_DIR/../02.ui/warn.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: # Usage:
# ask outvar text # request outvar text
# Example: # Example:
# ask name "What is your name?" # request name "What is your name?"
# echo "Hello, $name!" # echo "Hello, $name!"
ask() { request() {
local -n outvar="$1" # Declare nameref local -n outvar="$1" # Declare nameref
local prompt local prompt
local answer local answer

40
src/03.prompt/seek.sh Normal file
View file

@ -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"
}