FINALLY fix the weird cases for zsh/read builtin (particularly around reading one character from tty/pipe/file); also gave a --force-user-input flag in case you want to require user input on a yn prompt
This commit is contained in:
		| @@ -33,7 +33,7 @@ WARNING() {  # warning-level messages; not errors | ||||
| } | ||||
| 
 | ||||
| DEBUG() {  # helpful during development or (sparingly) to help others' development | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -gt 4 ]] \ | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 4 ]] \ | ||||
| 		&& PREFIX="DEBUG    ℹ" COLOR=$__WHITE          PRINT "$@" | ||||
| } | ||||
| 
 | ||||
| @@ -82,23 +82,10 @@ source "${0:a:h}/io.usage.zsh" | ||||
| ### facilitate user prompt and input ################################ | ||||
| ##################################################################### | ||||
| 
 | ||||
| Yn() {  # ask a yes-or-no question (default yes) | ||||
| 	PROMPT "$@ [Yn]" | ||||
| 	[ $CI ] && { echo y >&2; return 0; } | ||||
| 	[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; } | ||||
| 
 | ||||
| 	local Yn; READ -k Yn; echo >&2 | ||||
| 	[[ $Yn =~ [nN] ]] && return 1 || return 0 | ||||
| } | ||||
| 
 | ||||
| yN() {  # ask a yes-or-no question (default no) | ||||
| 	PROMPT "$@ [yN]" | ||||
| 	[ $CI ] && { echo y >&2; return 0; } | ||||
| 	[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; } | ||||
| 
 | ||||
| 	local yN; READ -k yN; echo >&2 | ||||
| 	[[ $yN =~ [yY] ]] && return 0 || return 1 | ||||
| } | ||||
| # yes/no prompts   && = yes (exit code 0) | ||||
| #                  || = no  (exit code 1) | ||||
| Yn() { [[ ! $(READ_YN $@ '[Yn]') =~ [nN] ]]; }  # default 'yes' | ||||
| yN() { [[   $(READ_YN $@ '[yN]') =~ [yY] ]]; }  # default 'no' | ||||
| 
 | ||||
| INPUT() {  # read a single line of user input | ||||
| 	PROMPT "${@:2}" | ||||
| @@ -159,12 +146,85 @@ GETSUDO() { | ||||
| 		|| { ERROR 'failed :c'; return 1; } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| READ()  { | ||||
| 	[ $CI ] && { | ||||
| 		WARNING 'currently in CI, skipping READ' | ||||
| 		return 0 | ||||
| 	} | ||||
| 	read $@ </dev/tty | ||||
| 	[ $CI ] && [ -t 0 ] \ | ||||
| 		&& FAIL 42 'currently in CI, but attempting interactive read; aborting' | ||||
| 
 | ||||
| 	local FORCE_USER_INPUT=false | ||||
| 	local ARGS=() | ||||
| 
 | ||||
| 	while [[ $# -gt 0 ]] | ||||
| 	do | ||||
| 		case $1 in | ||||
| 			--force-user-input ) FORCE_USER_INPUT=true ;; | ||||
| 			-k ) | ||||
| 				ARGS+=($1) | ||||
| 				;; | ||||
| 			* ) ARGS+=($1) ;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 	done | ||||
| 
 | ||||
| 	while read -k -t 0; do :; done;  # flush user stdin | ||||
| 
 | ||||
| 	case $FORCE_USER_INPUT in | ||||
| 		true  ) | ||||
| 			read ${PREARGS[@]} ${ARGS[@]} $@ </dev/tty | ||||
| 			;; | ||||
| 		false ) | ||||
| 			[ -t 0 ] || ARGS=(-u 0 ${ARGS[@]}) | ||||
| 			read ${ARGS[@]} $@ | ||||
| 			;; | ||||
| 	esac | ||||
| } | ||||
| 
 | ||||
| READ_YN() {  # yes/no read is suprisingly tricky | ||||
| 	local FORCE_USER_INPUT=false | ||||
| 	local USERPROMPT=() | ||||
| 	local READ_ARGS=() | ||||
| 
 | ||||
| 	while [[ $# -gt 0 ]] | ||||
| 	do | ||||
| 		case $1 in | ||||
| 			--force-user-input ) | ||||
| 				# overrides 'scwrypts -y' and stdin pipe but not CI | ||||
| 				FORCE_USER_INPUT=true | ||||
| 				READ_ARGS+=($1) | ||||
| 				;; | ||||
| 			* ) USERPROMPT+=($1) ;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 	done | ||||
| 
 | ||||
| 	########################################## | ||||
| 
 | ||||
| 	local SKIP_USER_INPUT=false | ||||
| 
 | ||||
| 	[ $CI ] \ | ||||
| 		&& SKIP_USER_INPUT=true | ||||
| 
 | ||||
| 	[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && [[ $FORCE_USER_INPUT =~ false ]] \ | ||||
| 		&& SKIP_USER_INPUT=true | ||||
| 
 | ||||
| 	########################################## | ||||
| 
 | ||||
| 	local yn | ||||
| 	PROMPT "${USERPROMPT[@]}" | ||||
| 
 | ||||
| 	case $SKIP_USER_INPUT in | ||||
| 		true ) yn=y ;; | ||||
| 		false ) | ||||
| 			[[ $FORCE_USER_INPUT =~ true ]] && [[ $SCWRYPTS_LOG_LEVEL -lt 1 ]] \ | ||||
| 				&& echo -n "${USERPROMPT[@]} : " >&2 | ||||
| 
 | ||||
| 			READ ${READ_ARGS[@]} -s -k yn | ||||
| 
 | ||||
| 			[[ $FORCE_USER_INPUT =~ true ]] && [[ $SCWRYPTS_LOG_LEVEL -lt 1 ]] \ | ||||
| 				&& echo $yn >&2 | ||||
| 			;; | ||||
| 	esac | ||||
| 
 | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $yn >&2 | ||||
| 
 | ||||
| 	echo $yn | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user