1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
|
#!/usr/bin/env bash
_modules=('system' 'bat' 'bat_config' 'bat_wrapper' 'bat_wrapper_function' 'tool')
_modules_consented=()
set -o pipefail
export LC_ALL=C
export LANG=C
BAT="bat"
if ! command -v bat &>/dev/null; then
if command -v batcat &> /dev/null; then
BAT="batcat"
else
tput setaf 1
printf "%s\n%s\n" \
"Unable to find a bat executable on your PATH." \
"Please ensure that 'bat' exists and is not named something else."
tput sgr0
exit 1
fi
fi
# -----------------------------------------------------------------------------
# Modules:
# -----------------------------------------------------------------------------
_bat_:description() {
_collects "Version information for 'bat'."
_collects "Custom syntaxes and themes for 'bat'."
}
_bat_config_:description() {
_collects "The environment variables used by 'bat'."
_collects "The 'bat' configuration file."
}
_bat_wrapper_:description() {
_collects "Any wrapper script used by 'bat'."
}
_bat_wrapper_function_:description() {
_collects "The wrapper function surrounding 'bat' (if applicable)."
}
_system_:description() {
_collects "Operating system name."
_collects "Operating system version."
}
_tool_:description() {
_collects "Version information for 'less'."
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_bat_:run() {
_out "$BAT" --version
_out env | grep '^BAT_\|^PAGER='
local cache_dir
cache_dir="$($BAT --cache-dir)"
if [[ -f "${cache_dir}/syntaxes.bin" ]]; then
_print_command "$BAT" "--list-languages"
echo "Found custom syntax set."
fi
if [[ -f "${cache_dir}/themes.bin" ]]; then
_print_command "$BAT" "--list-themes"
echo "Found custom theme set."
fi
}
_bat_config_:run() {
if [[ -f "$("$BAT" --config-file)" ]]; then
_out_fence cat "$("$BAT" --config-file)"
fi
}
_bat_wrapper_:run() {
_bat_wrapper_:detect_wrapper() {
local bat="$1"
if file "$(command -v "${bat}")" | grep "text executable" &> /dev/null; then
_out_fence cat "$(command -v "${bat}")"
return
fi
printf "\nNo wrapper script for '%s'.\n" "${bat}"
}
_bat_wrapper_:detect_wrapper bat
if [[ "$BAT" != "bat" ]]; then
_bat_wrapper_:detect_wrapper "$BAT"
fi
}
_bat_wrapper_function_:run() {
_bat_wrapper_function_:detect_wrapper() {
local command="$1"
case "$("$SHELL" --version | head -n 1)" in
*fish*)
if "$SHELL" --login -i -c "type ${command}" 2>&1 | grep 'function' &> /dev/null; then
_out_fence "$SHELL" --login -i -c "functions ${command}"
return
fi ;;
*bash* | *zsh*)
local type
type="$("$SHELL" --login -i -c "type ${command}" 2>&1)"
if grep 'function' <<< "$type" &> /dev/null; then
_out_fence "$SHELL" --login -i -c "declare -f ${command}"
return
elif grep 'alias' <<< "$type" &> /dev/null; then
_out_fence "$SHELL" --login -i -c "type ${command}"
return
fi ;;
*)
echo "Unable to determine if a wrapper function for '${command}' is set."
return ;;
esac
printf "\nNo wrapper function for '%s'.\n" "${command}"
}
_bat_wrapper_function_:detect_wrapper bat
_bat_wrapper_function_:detect_wrapper cat
if [[ "$BAT" != "bat" ]]; then
_bat_wrapper_function_:detect_wrapper "$BAT"
fi
}
_system_:run() {
_out uname -srm
if command -v "sw_vers" &> /dev/null; then _out sw_vers; fi
if command -v "lsb_release" &> /dev/null; then _out lsb_release -a; fi
}
_tool_:run() {
_out less --version | head -n1
}
# -----------------------------------------------------------------------------
# Functions:
# -----------------------------------------------------------------------------
_print_command() {
printf '\n**$' 1>&2
printf ' %s' "$@" 1>&2
printf '**\n' 1>&2
}
_out() {
_print_command "$@"
"$@" 2>&1 | sed 's/$/ /'
}
_out_fence() {
_print_command "$@"
printf '```\n' 1>&2
"$@" 2>&1
printf '```\n' 1>&2
}
_tput() {
tput "$@" 1>&2 2> /dev/null
}
_collects() {
printf " - %s\n" "$1" 1>&2
}
_ask_module() {
_tput clear
_tput cup 0 0
cat 1>&2 << EOF
--------------------------------------------------------------------------------
This script runs some harmless commands to collect information about your
system and bat configuration. It will give you a small preview of the commands
that will be run, and ask consent before running them. Once completed, it will
output a small report that you can review and copy into the issue description.
--------------------------------------------------------------------------------
EOF
# Print description.
_tput setaf 3
printf "The following data will be collected:\n" 1>&2
_tput sgr0
"_$1_:description"
_tput sgr0
# Print preview.
_tput setaf 3
printf "\nThe following commands will be run:\n" 1>&2
_tput sgr0
declare -f "_$1_:run" \
| sed 's/^ *//; s/;$//' \
| grep '^_out[^ ]* ' \
| sed 's/^_out[^ ]* //' \
| sed "s/\"\$BAT\"/$BAT/" 1>&2
# Prompt
printf "\n" 1>&2
local response
while true; do
_tput cup "$(($( tput lines || echo 22) - 2))"
_tput el
read -er -p "Collect $(sed 's/_/ /' <<< "$1") data? [Y/n] " response
case "$response" in
Y | y | yes | '') return 0 ;;
N | n | no) return 1 ;;
*) continue ;;
esac
done
}
_run_module() {
local module="$1"
printf "%s\n%s\n" "$module" "$(printf "%${#module}s" | tr ' ' '-')"
"_$1_:run"
}
# -----------------------------------------------------------------------------
# Functions:
# -----------------------------------------------------------------------------
# Tell the user if their executable isn't named "bat".
if [[ "$BAT" != "bat" ]] && [[ "$1" != '-y' ]]; then
trap '_tput rmcup; exit 1' INT
_tput smcup
_tput clear
_tput cup 0 0
_tput setaf 1
printf "The %s executable on your system is named '%s'.\n%s\n" "bat" "$BAT" \
"If your issue is related to installation, please check that this isn't the issue."
_tput sgr0
printf "Press any key to continue...\n"
read -rsn1
_tput rmcup
fi
# Ask for consent.
if [[ "$1" == '-y' ]]; then
_modules_consented=("${_modules[@]}")
else
trap '_tput rmcup; exit 1' INT
_tput smcup
for _module in "${_modules[@]}"; do
if _ask_module "$_module"; then
_modules_consented+=("$_module")
fi
done
_tput rmcup
fi
# Collect information.
for _module in "${_modules_consented[@]}"; do
_run_module "$_module" 2>&1
printf "\n"
done
|