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
 | 
					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 "$@"
 | 
							&& PREFIX="DEBUG    ℹ" COLOR=$__WHITE          PRINT "$@"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,23 +82,10 @@ source "${0:a:h}/io.usage.zsh"
 | 
				
			|||||||
### facilitate user prompt and input ################################
 | 
					### facilitate user prompt and input ################################
 | 
				
			||||||
#####################################################################
 | 
					#####################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Yn() {  # ask a yes-or-no question (default yes)
 | 
					# yes/no prompts   && = yes (exit code 0)
 | 
				
			||||||
	PROMPT "$@ [Yn]"
 | 
					#                  || = no  (exit code 1)
 | 
				
			||||||
	[ $CI ] && { echo y >&2; return 0; }
 | 
					Yn() { [[ ! $(READ_YN $@ '[Yn]') =~ [nN] ]]; }  # default 'yes'
 | 
				
			||||||
	[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; }
 | 
					yN() { [[   $(READ_YN $@ '[yN]') =~ [yY] ]]; }  # default 'no'
 | 
				
			||||||
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
INPUT() {  # read a single line of user input
 | 
					INPUT() {  # read a single line of user input
 | 
				
			||||||
	PROMPT "${@:2}"
 | 
						PROMPT "${@:2}"
 | 
				
			||||||
@@ -159,12 +146,85 @@ GETSUDO() {
 | 
				
			|||||||
		|| { ERROR 'failed :c'; return 1; }
 | 
							|| { ERROR 'failed :c'; return 1; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
READ()  {
 | 
					READ()  {
 | 
				
			||||||
	[ $CI ] && {
 | 
						[ $CI ] && [ -t 0 ] \
 | 
				
			||||||
		WARNING 'currently in CI, skipping READ'
 | 
							&& FAIL 42 'currently in CI, but attempting interactive read; aborting'
 | 
				
			||||||
		return 0
 | 
					
 | 
				
			||||||
	}
 | 
						local FORCE_USER_INPUT=false
 | 
				
			||||||
	read $@ </dev/tty
 | 
						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