🐛 Print user messages to stderr (#27)
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful

Previously, any messages only intended for the user (status messages,
warnings, errors) were sent over stdout. The actual emoji items are also
sent to the pickers over stdout so they would sometimes pick up the
messages and show them as an option to pick. If history is enabled, we
then also save the falsely included items there to forever display as an
option.

This commit changes internal messages to all be sent over stderr
instead, so they should not be picked up by any external programs we
hand off to.
This commit is contained in:
Marty Oehme 2024-01-11 10:58:11 +01:00
parent 7b5b3e6e46
commit e14010eb53
Signed by: Marty
GPG key ID: EDBF2ED917B2EF6A
3 changed files with 56 additions and 7 deletions

View file

@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Always download from newest emoji list url - Always download from newest emoji list url
- Pass selection to custom typing tools through stdin - Pass selection to custom typing tools through stdin
- Pass info messages to stderr to avoid passing to picker tools
<!-- ### Security --> <!-- ### Security -->

19
bemoji
View file

@ -59,6 +59,11 @@ version() {
exit exit
} }
msg() {
# Outputs a message to stderr, to be used for info, warning and error messages.
printf "%s\n" "$1" >&2
}
parse_cli() { parse_cli() {
while getopts cD:ef:hnpP:tv-: arg "$@"; do while getopts cD:ef:hnpP:tv-: arg "$@"; do
case "$arg" in case "$arg" in
@ -130,7 +135,7 @@ prepare_db() {
if [ -n "$BEMOJI_DOWNLOAD_LIST" ]; then if [ -n "$BEMOJI_DOWNLOAD_LIST" ]; then
# Populate default lists # Populate default lists
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'none'; then if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'none'; then
printf "Not downloading a default emoji list.\n" msg "Not downloading a default emoji list."
return return
elif echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'all'; then elif echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'all'; then
dl_default_emoji dl_default_emoji
@ -158,19 +163,19 @@ dl_default_emoji() {
local emojis local emojis
emojis=$(curl -sSL "https://unicode.org/Public/emoji/latest/emoji-test.txt") emojis=$(curl -sSL "https://unicode.org/Public/emoji/latest/emoji-test.txt")
printf "%s" "$emojis" | sed -ne 's/^.*; fully-qualified.*# \(\S*\) \S* \(.*$\)/\1 \2/gp' >"$bm_db_location/emojis.txt" printf "%s" "$emojis" | sed -ne 's/^.*; fully-qualified.*# \(\S*\) \S* \(.*$\)/\1 \2/gp' >"$bm_db_location/emojis.txt"
printf "Downloaded default emoji set.\n" msg "Downloaded default emoji set."
} }
dl_math_symbols() { dl_math_symbols() {
curl -sSL "https://unicode.org/Public/math/latest/MathClassEx-15.txt" | curl -sSL "https://unicode.org/Public/math/latest/MathClassEx-15.txt" |
grep -ve '^#' | cut -d';' -f3,7 | sed -e 's/;/ /' >"$bm_db_location/math.txt" grep -ve '^#' | cut -d';' -f3,7 | sed -e 's/;/ /' >"$bm_db_location/math.txt"
printf "Downloaded math symbols set.\n" msg "Downloaded math symbols set."
} }
dl_nerd_symbols() { dl_nerd_symbols() {
local nerd all local nerd all
nerd=$(curl -sSL "https://raw.githubusercontent.com/ryanoasis/nerd-fonts/master/css/nerd-fonts-generated.css") nerd=$(curl -sSL "https://raw.githubusercontent.com/ryanoasis/nerd-fonts/master/css/nerd-fonts-generated.css")
all+=$(printf "%s" "$nerd" | sed -ne '/\.nf-/p' -e '/\s*[^_]content:/p' | sed -e 'N;s/^\.nf-\(.*\):before.* content: \"\\\(.*\)\";/\\U\2 \1/') all+=$(printf "%s" "$nerd" | sed -ne '/\.nf-/p' -e '/\s*[^_]content:/p' | sed -e 'N;s/^\.nf-\(.*\):before.* content: \"\\\(.*\)\";/\\U\2 \1/')
echo -e "$all" > "$bm_db_location/nerdfont.txt" echo -e "$all" > "$bm_db_location/nerdfont.txt"
printf "Downloaded nerdfont symbols set.\n" msg "Downloaded nerdfont symbols set."
} }
gather_emojis() { gather_emojis() {
@ -231,7 +236,7 @@ _clipper() {
elif [ -n "$DISPLAY" ] && command -v xsel >/dev/null 2>&1; then elif [ -n "$DISPLAY" ] && command -v xsel >/dev/null 2>&1; then
xsel -b xsel -b
else else
printf "No suitable clipboard tool found." msg "No suitable clipboard tool found."
exit 1 exit 1
fi fi
} }
@ -250,7 +255,7 @@ _typer() {
elif [ -n "$DISPLAY" ] && command -v xdotool >/dev/null 2>&1; then elif [ -n "$DISPLAY" ] && command -v xdotool >/dev/null 2>&1; then
xdotool type --delay 30 "$totype" xdotool type --delay 30 "$totype"
else else
printf "No suitable typing tool found." msg "No suitable typing tool found."
exit 1 exit 1
fi fi
} }
@ -270,7 +275,7 @@ _picker() {
fi fi
done done
printf "No suitable picker tool found." 1>&2 msg "No suitable picker tool found."
exit 1 exit 1
} }

43
test/bemoji_errors.bats Normal file
View file

@ -0,0 +1,43 @@
#!/usr/bin/env bash
setup_file() {
# make bemoji executable from anywhere relative to current testfile
TEST_DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
PATH="$TEST_DIR/..:$PATH"
}
setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
# set up small default set of test emoji for each test
export BEMOJI_DB_LOCATION="$BATS_TEST_TMPDIR/database"
export BEMOJI_HISTORY_LOCATION="$BATS_TEST_TMPDIR/history"
mkdir -p "$BEMOJI_DB_LOCATION" "$BEMOJI_HISTORY_LOCATION"
cat "$BATS_TEST_DIRNAME/resources/test_emoji.txt" > "$BEMOJI_DB_LOCATION/emoji.txt"
# these tests require stdout to be separated from stderr
# such run flags were only introduced in recent bats version
bats_require_minimum_version 1.5.0
}
@test "Prints clipper error to stderr" {
BEMOJI_PICKER_CMD="echo hi" run --separate-stderr bemoji 3>&-
assert_output ""
output="$stderr"
assert_output "No suitable clipboard tool found."
}
@test "Prints picker error to stderr" {
run --separate-stderr bemoji 3>&-
assert_output ""
output="$stderr"
assert_output "No suitable picker tool found."
}
@test "Prints typer error to stderr" {
BEMOJI_PICKER_CMD="echo hi" run --separate-stderr bemoji -t 3>&-
assert_output ""
output="$stderr"
assert_output "No suitable typing tool found."
}