Skip to content

Commit

Permalink
improvements to TTY and STDIN reporting
Browse files Browse the repository at this point in the history
- add `debug-terminal-(stdin|tty)`
- simplify `get-terminal-*-support` checks
- `IFS=''` to `IFS=` as they are equivalent
- get-terminal-theme: add `--ignore-cache` option
- echo-file: correctly handle bat theme in cases where theme could not be detected, such as inside `ssh -T`
  • Loading branch information
balupton committed Oct 25, 2024
1 parent 0dfebda commit 613cec8
Show file tree
Hide file tree
Showing 15 changed files with 374 additions and 223 deletions.
2 changes: 1 addition & 1 deletion commands.beta/echo-revolving-screen
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function echo_revolving_screen() (
clear_screen=$'\e[H\e[J'

local input total_lines=0 status wrapped lines=0
while IFS='' read -r input || test -n "$input"; do
while IFS= read -r input || test -n "$input"; do
eval_capture --statusvar=status --outputvar=wrapped \
-- gfold --width="$option_columns" <<<"$input"
#-- echo-wrap --width="$option_columns" -- "$input"
Expand Down
2 changes: 0 additions & 2 deletions commands.deprecated/is-match
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/usr/bin/env bash

# deprecated, use [echo-regexp -q --regexp=<pattern> -- <input>] instead

function is_match_test() (
source "$DOROTHY/sources/bash.bash"
echo-style --h1="TEST: $0"
Expand Down
112 changes: 112 additions & 0 deletions commands/debug-terminal-stdin
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env bash
# trunk-ignore-all(shellcheck/SC2319)

function debug_terminal_stdin() (
source "$DOROTHY/sources/bash.bash"

# dependencies
setup-util-file --quiet

# =====================================

local file
file="$(fs-temp --directory='debug-tty-stdin' --file --extension='txt')"

function r {
local details="$1" status result
__print_lines "$details"
__print_lines '' "$details" >>"$file"
file /dev/stdin >>"$file" || :
file /proc/self/fd/0 >>"$file" || :
file /dev/fd/0 >>"$file" || :

status=0
read -t 0 || status=$?
__print_lines "read -t 0: $status" >>"$file"

status=0
[[ -t 0 ]] || status=$?
__print_lines "[[ -t 0 ]]: $status" >>"$file"

status=0
[[ -p /dev/stdin ]] || status=$?
__print_lines "[[ -p /dev/stdin ]]: $status" >>"$file"

status=0
[[ -c /dev/stdin ]] || status=$?
__print_lines "[[ -c /dev/stdin ]]: $status" >>"$file"

status=0
[[ -r /dev/stdin ]] || status=$?
__print_lines "[[ -r /dev/stdin ]]: $status" >>"$file"

status=0
[[ -w /dev/stdin ]] || status=$?
__print_lines "[[ -w /dev/stdin ]]: $status" >>"$file"

result=''
status=0
read -t 5 -rei def result || status=$?
__print_lines "read -rei: $status: $result" >>"$file"

}
function s {
__print_lines 'custom'
#__print_line
#:
}
function b {
r "BACKGROUND TASK: $1" &
wait $!
}

# STANDARD

__print_line
r 'DIRECT'

__print_line
{ s; } | r 'PIPE'
__print_line
{
sleep 1
s
} | r 'DELAYED PIPE'

__print_line
r 'REDIRECTION' < <(s)
__print_line
r 'DELAYED REDIRECTION' < <(
sleep 1
s
)

# BACKGROUND

__print_line
b 'DIRECT'

__print_line
{ s; } | b 'PIPE'
__print_line
{
sleep 1
s
} | b 'DELAYED PIPE' || :

__print_line
b 'REDIRECTION' < <(s)
__print_line
b 'DELAYED REDIRECTION' < <(
sleep 1
s
)

__print_lines '' 'DONE'
echo-file -- "$file"
)

# fire if invoked standalone
if test "$0" = "${BASH_SOURCE[0]}"; then
debug_terminal_stdin "$@"
fi
192 changes: 192 additions & 0 deletions commands/debug-terminal-tty
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#!/usr/bin/env bash

function debug_terminal_tty() (
source "$DOROTHY/sources/bash.bash"

# =====================================

function __act {
# $-
__print_lines "\$- = $-"

# tty:
# alpine doesn't support the [-p] argument
if ! is-apk && __command_exists -- ps; then
__print_lines '' 'tty:'
ps -p "$$" -o tty= || :
fi

# lsof:
if __command_exists -- lsof; then
__print_lines '' 'lsof:'
lsof -p $$ || :
fi

# /dev/fd/*
__print_lines '' '/dev/fd/*:'
ls -l /dev/fd/* || :
file /dev/fd/* || :

# /dev/pts/*
if test -e /dev/pts; then
__print_lines '' '/dev/pts/*:'
ls -l /dev/pts/* || :
file /dev/pts/* || :
fi

# realpath /dev/fd/*
__print_lines '' 'realpath /dev/fd/*:'
fs-realpath -- /dev/fd/* || :

# proc:
# https://stackoverflow.com/a/54668834/130638
if ls /proc/$$/fdinfo/* >/dev/null 2>&1 || grep -q 'flags: 00$' /proc/$$/fdinfo/0; then
__print_lines '' proc_pass
else
__print_lines '' proc_fail
fi

# attempts at detection

# -c /dev/stdin to handle background in ssh -T
# note that if everything is captured, such as eval_capture with stdin modification, then this appears true
( ([[ -n ${SSH_CONNECTION-} && -n ${SSH_CLIENT-} && -z ${SSH_TTY-} ]] && __print_lines is_actually_ssh_T) || __print_lines is_not_actually_ssh_T) || :
( ([[ (-p /dev/stdin || -c /dev/stdin) && -p /dev/stdout && -p /dev/stderr ]] && ! (: >/dev/stdin) && __print_lines is_ssh_T_or_all_custom) || __print_lines is_neither_ssh_T_or_all_custom) || :
( (! [[ -c /dev/stdin ]] && (: >/dev/stdin) && __print_lines is_CI) || __print_lines is_not_CI) || :

( (tty -s && __print_lines tty_s_pass) || __print_lines tty_s_fail) || :

( (test -t 0 && __print_lines test_t_stdin_pass) || __print_lines test_t_stdin_fail) || :
( (test -t 1 && __print_lines test_t_stdout_pass) || __print_lines test_t_stdout_fail) || :
( (test -t 2 && __print_lines test_t_stderr_pass) || __print_lines test_t_stderr_fail) || :

( (test -p /dev/stdin && __print_lines test_p_stdin_pass) || __print_lines test_p_stdin_fail) || :
( (test -p /dev/stdout && __print_lines test_p_stdout_pass) || __print_lines test_p_stdout_fail) || :
( (test -p /dev/stderr && __print_lines test_p_stderr_pass) || __print_lines test_p_stderr_fail) || :
( (test -p /dev/tty && __print_lines test_p_tty_pass) || __print_lines test_p_tty_fail) || :

( (test -c /dev/stdin && __print_lines test_c_stdin_pass) || __print_lines test_c_stdin_fail) || :
( (test -c /dev/stdout && __print_lines test_c_stdout_pass) || __print_lines test_c_stdout_fail) || :
( (test -c /dev/stderr && __print_lines test_c_stderr_pass) || __print_lines test_c_stderr_fail) || :
( (test -c /dev/tty && __print_lines test_c_tty_pass) || __print_lines test_c_tty_fail) || :

# check if reading is even possible (If TIMEOUT is 0, read returns immediately, without trying to read any data, returning success only if input is available on the specified file descriptor.)
( (read -t 0 && __print_lines read_default_pass) || __print_lines read_default_fail) || :
( (read -t 0 </dev/stdin && __print_lines read_stdin_pass) || __print_lines read_stdin_fail) || :
( (read -t 0 </dev/stdout && __print_lines read_stdout_pass) || __print_lines read_stdout_fail) || :
( (read -t 0 </dev/stderr && __print_lines read_stderr_pass) || __print_lines read_stderr_fail) || :
( (read -t 0 </dev/tty && __print_lines read_tty_pass) || __print_lines read_tty_fail) || :

# don't use exec, don't use printf, they interefered with the read-key tests, as read-key would read [exec]
# : is the same check but it is superior because it is a proper noop, unlike exec and printf

( (: </dev/stdin && __print_lines noop_from_stdin_pass) || __print_lines noop_from_stdin_fail) || :
( (: </dev/stdout && __print_lines noop_from_stdout_pass) || __print_lines noop_from_stdout_fail) || :
( (: </dev/stderr && __print_lines noop_from_stderr_pass) || __print_lines noop_from_stderr_fail) || :
( (: </dev/tty && __print_lines noop_from_tty_pass) || __print_lines noop_from_tty_fail) || :

( (: >/dev/stdin && __print_lines noop_to_stdin_pass) || __print_lines noop_to_stdin_fail) || :
( (: >/dev/stdout && __print_lines noop_to_stdout_pass) || __print_lines noop_to_stdout_fail) || :
( (: >/dev/stderr && __print_lines noop_to_stderr_pass) || __print_lines noop_to_stderr_fail) || :
( (: >/dev/tty && __print_lines noop_to_tty_pass) || __print_lines noop_to_tty_fail) || :

( (: </dev/stdin >/dev/stdin && __print_lines noop_bidirectonal_stdin_pass) || __print_lines noop_bidirectonal_stdin_fail) || :
( (: </dev/stdout >/dev/stdout && __print_lines noop_bidirectonal_stdout_pass) || __print_lines noop_bidirectonal_stdout_fail) || :
( (: </dev/stderr >/dev/stderr && __print_lines noop_bidirectonal_stderr_pass) || __print_lines noop_bidirectonal_stderr_fail) || :
( (: </dev/tty >/dev/tty && __print_lines noop_bidirectonal_tty_pass) || __print_lines noop_bidirectonal_tty_fail) || :
}

local stdout stderr

__act

__print_lines '' '' '### testing pipe ###'
__print_lines 'testing pipe' | __act

__print_lines '' '' '### testing delayed pipe ###'
{
sleep 3
__print_line
} | __act || : # this is necessary, as otherwise the pipe fails with 141

__print_lines '' '' '### testing <<< ###'
__act <<<'testing <<<'

__print_lines '' '' '### testing < <(...) ###'
__act < <(__print_lines 'testing <<<')

__print_lines '' '' '### testing background ###'
__act &
wait $!

__print_lines '' '' '### --stdoutvar ###'
stdout=''
stderr=''
eval_capture --stdoutvar=stdout -- __act
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"

__print_lines '' '' '### --stderrvar ###'
stdout=''
stderr=''
eval_capture --stderrvar=stderr -- __act
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"

__print_lines '' '' '### --stdoutvar --stderrvar ###'
stdout=''
stderr=''
eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"

__print_lines '' '' '### pipe to --stdoutvar --stderrvar ###'
stdout=''
stderr=''
__print_lines 'testing pipe' | eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"

__print_lines '' '' '### delayed pipe to --stdoutvar --stderrvar ###'
stdout=''
stderr=''
{
sleep 3
__print_line
} | eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act || :
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"

__print_lines '' '' '### <<< to --stdoutvar --stderrvar ###'
stdout=''
stderr=''
eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act <<<'testing <<<'
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"

__print_lines '' '' '### < <(...) to --stdoutvar --stderrvar ###'
stdout=''
stderr=''
eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act < <(__print_lines 'testing <<<')
__print_lines 'stdout ='
echo-lines --indent=' ' --stdin <<<"$stdout"
__print_lines 'stderr ='
echo-lines --indent=' ' --stdin <<<"$stderr"
)

# fire if invoked standalone
if test "$0" = "${BASH_SOURCE[0]}"; then
debug_terminal_tty "$@"
fi
9 changes: 8 additions & 1 deletion commands/dorothy
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,13 @@ function dorothy_() (
echo-style --h1='Dorothy Tests'
source "$DOROTHY/sources/ripgrep.bash"

# run relevant debugs
__print_lines '' 'debug-terminal-stdin:'
debug-terminal-stdin || :
__print_lines '' 'debug-terminal-tty:'
debug-terminal-tty || :
__print_lines ''

# able to test on bash v3?
local bash has_macos_bash_v3='no'
bash="$(type -P bash)"
Expand All @@ -1916,7 +1923,7 @@ function dorothy_() (
local commands filepath filename failures=() scan_paths=(
"$DOROTHY/commands/"
"$DOROTHY/commands.beta/"
"$DOROTHY/commands.deprecated/"
# "$DOROTHY/commands.deprecated/" <-- don't run deprecated tests, as that will cause deprecated warnings, which cases dorothy-warnings test to fail
)
if test -d "$DOROTHY/user"; then
if test -d "$DOROTHY/user/commands"; then
Expand Down
7 changes: 2 additions & 5 deletions commands/echo-file
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function echo_file() (
)
fi
if test -z "${BAT_THEME-}"; then
terminal_theme="$(get-terminal-theme || :)"
terminal_theme="$(get-terminal-theme --ignore-cache || :)"
if test "$terminal_theme" = 'light'; then
bat_cmd+=(
--theme=ansi
Expand All @@ -121,10 +121,7 @@ function echo_file() (
bat_cmd+=(
--theme=1337
)
else
bat_cmd=()
# bat is installed, but without knowing the terminal theme, we cannot be sure that the bat theme is readable
fi
fi # else bat is installed, but without knowing the terminal theme, we cannot be sure that the bat theme is readable
fi

function echo_file_bat {
Expand Down
2 changes: 1 addition & 1 deletion commands/echo-revolving-door
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function echo_revolving_door() (
else
local input negative_columns
negative_columns="$((option_columns * -1))"
while IFS='' read -r input || test -n "$input"; do
while IFS= read -r input || test -n "$input"; do
if test -z "$input"; then
continue
fi
Expand Down
8 changes: 6 additions & 2 deletions commands/get-terminal-alternative-support
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,15 @@ function get_terminal_alternative_support() (
# =====================================
# Action

function __check {
is-ci
}

if test "$option_quiet" = 'yes'; then
if is-ci; then
if __check; then
return 1
fi
elif is-ci; then
elif __check; then
__print_lines 'no'
else
__print_lines 'yes'
Expand Down
Loading

0 comments on commit 613cec8

Please sign in to comment.