From ef3a3a97cb4e856d0a282b9cd53d741dfef49b1e Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Sat, 6 Mar 2021 16:24:03 +0000 Subject: [PATCH 01/61] Initial Install/Manage Script Test --- scripts/inquirer.sh | 667 ++++++++++++++++++++++++++++++++++++++++++++ scripts/manage.sh | 88 ++++++ 2 files changed, 755 insertions(+) create mode 100644 scripts/inquirer.sh create mode 100644 scripts/manage.sh diff --git a/scripts/inquirer.sh b/scripts/inquirer.sh new file mode 100644 index 00000000..02872f0f --- /dev/null +++ b/scripts/inquirer.sh @@ -0,0 +1,667 @@ +#!/usr/bin/env bash + +################## INQUIRER.SH ################## +# https://github.com/kahkhang/Inquirer.sh + +# The MIT License (MIT) + +# Copyright (c) 2017 + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# store the current set options +OLD_SET=$- +set -e + +arrow="$(echo -e '\xe2\x9d\xaf')" +checked="$(echo -e '\xe2\x97\x89')" +unchecked="$(echo -e '\xe2\x97\xaf')" + +black="$(tput setaf 0)" +red="$(tput setaf 1)" +green="$(tput setaf 2)" +yellow="$(tput setaf 3)" +blue="$(tput setaf 4)" +magenta="$(tput setaf 5)" +cyan="$(tput setaf 6)" +white="$(tput setaf 7)" +bold="$(tput bold)" +normal="$(tput sgr0)" +dim=$'\e[2m' + +print() { + echo "$1" + tput el +} + +join() { + local IFS=$'\n' + local _join_list + eval _join_list=( '"${'${1}'[@]}"' ) + local first=true + for item in ${_join_list[@]}; do + if [ "$first" = true ]; then + printf "%s" "$item" + first=false + else + printf "${2-, }%s" "$item" + fi + done +} + +function gen_env_from_options() { + local IFS=$'\n' + local _indices + local _env_names + local _checkbox_selected + eval _indices=( '"${'${1}'[@]}"' ) + eval _env_names=( '"${'${2}'[@]}"' ) + + for i in $(gen_index ${#_env_names[@]}); do + _checkbox_selected[$i]=false + done + + for i in ${_indices[@]}; do + _checkbox_selected[$i]=true + done + + for i in $(gen_index ${#_env_names[@]}); do + printf "%s=%s\n" "${_env_names[$i]}" "${_checkbox_selected[$i]}" + done +} + +on_default() { + true; +} + +on_keypress() { + local OLD_IFS + local IFS + local key + OLD_IFS=$IFS + local on_up=${1:-on_default} + local on_down=${2:-on_default} + local on_space=${3:-on_default} + local on_enter=${4:-on_default} + local on_left=${5:-on_default} + local on_right=${6:-on_default} + local on_ascii=${7:-on_default} + local on_backspace=${8:-on_default} + _break_keypress=false + while IFS="" read -rsn1 key; do + case "$key" in + $'\x1b') + read -rsn1 key + if [[ "$key" == "[" ]]; then + read -rsn1 key + case "$key" in + 'A') eval $on_up;; + 'B') eval $on_down;; + 'D') eval $on_left;; + 'C') eval $on_right;; + esac + fi + ;; + ' ') eval $on_space ' ';; + [a-z0-9A-Z\!\#\$\&\+\,\-\.\/\;\=\?\@\[\]\^\_\{\}\~]) eval $on_ascii $key;; + $'\x7f') eval $on_backspace $key;; + '') eval $on_enter $key;; + esac + if [ $_break_keypress = true ]; then + break + fi + done + IFS=$OLD_IFS +} + +gen_index() { + local k=$1 + local l=0 + if [ $k -gt 0 ]; then + for l in $(seq $k) + do + echo "$l-1" | bc + done + fi +} + +cleanup() { + # Reset character attributes, make cursor visible, and restore + # previous screen contents (if possible). + tput sgr0 + tput cnorm + stty echo + + # Restore `set e` option to its orignal value + if [[ $OLD_SET =~ e ]] + then set -e + else set +e + fi +} + +control_c() { + cleanup + exit $? +} + +select_indices() { + local _select_list + local _select_indices + local _select_selected=() + eval _select_list=( '"${'${1}'[@]}"' ) + eval _select_indices=( '"${'${2}'[@]}"' ) + local _select_var_name=$3 + eval $_select_var_name\=\(\) + for i in $(gen_index ${#_select_indices[@]}); do + eval $_select_var_name\+\=\(\""${_select_list[${_select_indices[$i]}]}"\"\) + done +} + + + + +on_checkbox_input_up() { + remove_checkbox_instructions + tput cub "$(tput cols)" + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf " ${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf " ${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi + tput el + + if [ $_current_index = 0 ]; then + _current_index=$((${#_checkbox_list[@]}-1)) + tput cud $((${#_checkbox_list[@]}-1)) + tput cub "$(tput cols)" + else + _current_index=$((_current_index-1)) + + tput cuu1 + tput cub "$(tput cols)" + tput el + fi + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi +} + +on_checkbox_input_down() { + remove_checkbox_instructions + tput cub "$(tput cols)" + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf " ${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf " ${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi + + tput el + + if [ $_current_index = $((${#_checkbox_list[@]}-1)) ]; then + _current_index=0 + tput cuu $((${#_checkbox_list[@]}-1)) + tput cub "$(tput cols)" + else + _current_index=$((_current_index+1)) + tput cud1 + tput cub "$(tput cols)" + tput el + fi + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi +} + +on_checkbox_input_enter() { + local OLD_IFS + OLD_IFS=$IFS + _checkbox_selected_indices=() + _checkbox_selected_options=() + IFS=$'\n' + + for i in $(gen_index ${#_checkbox_list[@]}); do + if [ "${_checkbox_selected[$i]}" = true ]; then + _checkbox_selected_indices+=($i) + _checkbox_selected_options+=("${_checkbox_list[$i]}") + fi + done + + tput cud $((${#_checkbox_list[@]}-${_current_index})) + tput cub "$(tput cols)" + + for i in $(seq $((${#_checkbox_list[@]}+1))); do + tput el1 + tput el + tput cuu1 + done + tput cub "$(tput cols)" + + tput cuf $((${#prompt}+3)) + printf "${cyan}$(join _checkbox_selected_options)${normal}" + tput el + + tput cud1 + tput cub "$(tput cols)" + tput el + + _break_keypress=true + IFS=$OLD_IFS +} + +on_checkbox_input_space() { + remove_checkbox_instructions + tput cub "$(tput cols)" + tput el + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + _checkbox_selected[$_current_index]=false + else + _checkbox_selected[$_current_index]=true + fi + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi +} + +remove_checkbox_instructions() { + if [ $_first_keystroke = true ]; then + tput cuu $((${_current_index}+1)) + tput cub "$(tput cols)" + tput cuf $((${#prompt}+3)) + tput el + tput cud $((${_current_index}+1)) + _first_keystroke=false + fi +} + +# for vim movements +on_checkbox_input_ascii() { + local key=$1 + case $key in + "j" ) on_checkbox_input_down;; + "k" ) on_checkbox_input_up;; + esac +} + +_checkbox_input() { + local i + local j + prompt=$1 + eval _checkbox_list=( '"${'${2}'[@]}"' ) + _current_index=0 + _first_keystroke=true + + trap control_c SIGINT EXIT + + stty -echo + tput civis + + print "${normal}${green}?${normal} ${bold}${prompt}${normal} ${dim}(Press to select, to finalize)${normal}" + + for i in $(gen_index ${#_checkbox_list[@]}); do + _checkbox_selected[$i]=false + done + + if [ -n "$3" ]; then + eval _selected_indices=( '"${'${3}'[@]}"' ) + for i in ${_selected_indices[@]}; do + _checkbox_selected[$i]=true + done + fi + + for i in $(gen_index ${#_checkbox_list[@]}); do + tput cub "$(tput cols)" + if [ $i = 0 ]; then + if [ "${_checkbox_selected[$i]}" = true ]; then + print "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$i]} ${normal}" + else + print "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$i]} ${normal}" + fi + else + if [ "${_checkbox_selected[$i]}" = true ]; then + print " ${green}${checked}${normal} ${_checkbox_list[$i]} ${normal}" + else + print " ${unchecked} ${_checkbox_list[$i]} ${normal}" + fi + fi + tput el + done + + for j in $(gen_index ${#_checkbox_list[@]}); do + tput cuu1 + done + + on_keypress on_checkbox_input_up on_checkbox_input_down on_checkbox_input_space on_checkbox_input_enter on_default on_default on_checkbox_input_ascii +} + +checkbox_input() { + _checkbox_input "$1" "$2" + _checkbox_input_output_var_name=$3 + select_indices _checkbox_list _checkbox_selected_indices $_checkbox_input_output_var_name + + unset _checkbox_list + unset _break_keypress + unset _first_keystroke + unset _current_index + unset _checkbox_input_output_var_name + unset _checkbox_selected_indices + unset _checkbox_selected_options + + cleanup +} + +checkbox_input_indices() { + _checkbox_input "$1" "$2" "$3" + _checkbox_input_output_var_name=$3 + + eval $_checkbox_input_output_var_name\=\(\) + for i in $(gen_index ${#_checkbox_selected_indices[@]}); do + eval $_checkbox_input_output_var_name\+\=\(${_checkbox_selected_indices[$i]}\) + done + + unset _checkbox_list + unset _break_keypress + unset _first_keystroke + unset _current_index + unset _checkbox_input_output_var_name + unset _checkbox_selected_indices + unset _checkbox_selected_options + + cleanup +} + + + + +on_list_input_up() { + remove_list_instructions + tput cub "$(tput cols)" + + printf " ${_list_options[$_list_selected_index]}" + tput el + + if [ $_list_selected_index = 0 ]; then + _list_selected_index=$((${#_list_options[@]}-1)) + tput cud $((${#_list_options[@]}-1)) + tput cub "$(tput cols)" + else + _list_selected_index=$((_list_selected_index-1)) + + tput cuu1 + tput cub "$(tput cols)" + tput el + fi + + printf "${cyan}${arrow} %s ${normal}" "${_list_options[$_list_selected_index]}" +} + +on_list_input_down() { + remove_list_instructions + tput cub "$(tput cols)" + + printf " ${_list_options[$_list_selected_index]}" + tput el + + if [ $_list_selected_index = $((${#_list_options[@]}-1)) ]; then + _list_selected_index=0 + tput cuu $((${#_list_options[@]}-1)) + tput cub "$(tput cols)" + else + _list_selected_index=$((_list_selected_index+1)) + tput cud1 + tput cub "$(tput cols)" + tput el + fi + printf "${cyan}${arrow} %s ${normal}" "${_list_options[$_list_selected_index]}" +} + +on_list_input_enter_space() { + local OLD_IFS + OLD_IFS=$IFS + IFS=$'\n' + + tput cud $((${#_list_options[@]}-${_list_selected_index})) + tput cub "$(tput cols)" + + for i in $(seq $((${#_list_options[@]}+1))); do + tput el1 + tput el + tput cuu1 + done + tput cub "$(tput cols)" + + tput cuf $((${#prompt}+3)) + printf "${cyan}${_list_options[$_list_selected_index]}${normal}" + tput el + + tput cud1 + tput cub "$(tput cols)" + tput el + + _break_keypress=true + IFS=$OLD_IFS +} + +remove_list_instructions() { + if [ $_first_keystroke = true ]; then + tput cuu $((${_list_selected_index}+1)) + tput cub "$(tput cols)" + tput cuf $((${#prompt}+3)) + tput el + tput cud $((${_list_selected_index}+1)) + _first_keystroke=false + fi +} + +_list_input() { + local i + local j + prompt=$1 + eval _list_options=( '"${'${2}'[@]}"' ) + + _list_selected_index=0 + _first_keystroke=true + + trap control_c SIGINT EXIT + + stty -echo + tput civis + + print "${normal}${green}?${normal} ${bold}${prompt}${normal} ${dim}(Use arrow keys)${normal}" + + for i in $(gen_index ${#_list_options[@]}); do + tput cub "$(tput cols)" + if [ $i = 0 ]; then + print "${cyan}${arrow} ${_list_options[$i]} ${normal}" + else + print " ${_list_options[$i]}" + fi + tput el + done + + for j in $(gen_index ${#_list_options[@]}); do + tput cuu1 + done + + on_keypress on_list_input_up on_list_input_down on_list_input_enter_space on_list_input_enter_space + +} + + +list_input() { + _list_input "$1" "$2" + local var_name=$3 + eval $var_name=\'"${_list_options[$_list_selected_index]}"\' + unset _list_selected_index + unset _list_options + unset _break_keypress + unset _first_keystroke + + cleanup +} + +list_input_index() { + _list_input "$1" "$2" + local var_name=$3 + eval $var_name=\'"$_list_selected_index"\' + unset _list_selected_index + unset _list_options + unset _break_keypress + unset _first_keystroke + + cleanup +} + + + + +on_text_input_left() { + remove_regex_failed + if [ $_current_pos -gt 0 ]; then + tput cub1 + _current_pos=$(($_current_pos-1)) + fi +} + +on_text_input_right() { + remove_regex_failed + if [ $_current_pos -lt ${#_text_input} ]; then + tput cuf1 + _current_pos=$(($_current_pos+1)) + fi +} + +on_text_input_enter() { + remove_regex_failed + + if [[ "$_text_input" =~ $_text_input_regex && "$(eval $_text_input_validator "$_text_input")" = true ]]; then + tput cub "$(tput cols)" + tput cuf $((${#_read_prompt}-19)) + printf "${cyan}${_text_input}${normal}" + tput el + tput cud1 + tput cub "$(tput cols)" + tput el + eval $var_name=\'"${_text_input}"\' + _break_keypress=true + else + _text_input_regex_failed=true + tput civis + tput cud1 + tput cub "$(tput cols)" + tput el + printf "${red}>>${normal} $_text_input_regex_failed_msg" + tput cuu1 + tput cub "$(tput cols)" + tput cuf $((${#_read_prompt}-19)) + tput el + _text_input="" + _current_pos=0 + tput cnorm + fi +} + +on_text_input_ascii() { + remove_regex_failed + local c=$1 + + if [ "$c" = '' ]; then + c=' ' + fi + + local rest="${_text_input:$_current_pos}" + _text_input="${_text_input:0:$_current_pos}$c$rest" + _current_pos=$(($_current_pos+1)) + + tput civis + printf "$c$rest" + tput el + if [ ${#rest} -gt 0 ]; then + tput cub ${#rest} + fi + tput cnorm +} + +on_text_input_backspace() { + remove_regex_failed + if [ $_current_pos -gt 0 ]; then + local start="${_text_input:0:$(($_current_pos-1))}" + local rest="${_text_input:$_current_pos}" + _current_pos=$(($_current_pos-1)) + tput cub 1 + tput el + tput sc + printf "$rest" + tput rc + _text_input="$start$rest" + fi +} + +remove_regex_failed() { + if [ $_text_input_regex_failed = true ]; then + _text_input_regex_failed=false + tput sc + tput cud1 + tput el1 + tput el + tput rc + fi +} + +text_input_default_validator() { + echo true; +} + +text_input() { + local prompt=$1 + local var_name=$2 + local _text_input_regex="${3:-"\.+"}" + local _text_input_regex_failed_msg=${4:-"Input validation failed"} + local _text_input_validator=${5:-text_input_default_validator} + local _read_prompt_start=$'\e[32m?\e[39m\e[1m' + local _read_prompt_end=$'\e[22m' + local _read_prompt="$( echo "$_read_prompt_start ${prompt} $_read_prompt_end")" + local _current_pos=0 + local _text_input_regex_failed=false + local _text_input="" + printf "$_read_prompt" + + + trap control_c SIGINT EXIT + + stty -echo + tput cnorm + + on_keypress on_default on_default on_text_input_ascii on_text_input_enter on_text_input_left on_text_input_right on_text_input_ascii on_text_input_backspace + eval $var_name=\'"${_text_input}"\' + + cleanup +} + +################## INQUIRER.SH ################## \ No newline at end of file diff --git a/scripts/manage.sh b/scripts/manage.sh new file mode 100644 index 00000000..84ef00a3 --- /dev/null +++ b/scripts/manage.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +REPO="Z-Bolt/OctoScreen" +MAIN="master" +RELEASES="https://api.github.com/repos/$REPO/releases/latest" +WGET_RAW="https://github.com/$REPO/raw/$MAIN" + +source <(wget -qO- "$WGET_RAW/scripts/inquirer.sh") + +exit + +arch=$(uname -m) +#if [[ $arch == x86_64 ]]; then +# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*amd64.deb" | cut -d '"' -f 4) +#elif [[ $arch == aarch64 ]]; then +# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*arm64.deb" | cut -d '"' -f 4) +if [[ $arch == arm* ]]; then + releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) +fi +dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" +IFS='/' read -ra version <<< "$releaseURL" + +echo "Installing OctoScreen "${version[7]}, $arch"" + +echo "Installing Dependencies ..." +sudo apt -qq update +sudo apt -qq install $dependencies -y + +if [ -d "/home/pi/OctoPrint/venv" ]; then + DIRECTORY="/home/pi/OctoPrint/venv" +elif [ -d "/home/pi/oprint" ]; then + DIRECTORY="/home/pi/oprint" +else + echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." + echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." + text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY +fi; + +if [ $DIRECTORY == "-" ]; then + echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." +elif [ ! -d $DIRECTORY ]; then + echo "Can't find OctoPrint Installation, please run the script again!" + exit 1 +fi; + +#if [ $DIRECTORY != "-" ]; then +# plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) +# checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins +# echo "Installing Plugins..." +# +# if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" +# fi; +#fi; + +echo "Installing OctoScreen "${version[7]}, $arch" ..." +cd ~ +wget -O octoscreen.deb $releaseURL -q --show-progress + +sudo dpkg -i octodash.deb + +rm octodash.deb + +yes_no=( 'yes' 'no' ) + +list_input "Shall I reboot your Pi now?" yes_no reboot +echo "OctoScreen has been successfully installed! :)" +if [ $reboot == 'yes' ]; then + sudo reboot +fi \ No newline at end of file From 2f94c4f4b447f1a9bb6fafd7d1ffee5cc2c138d0 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Sat, 6 Mar 2021 16:28:12 +0000 Subject: [PATCH 02/61] Fix Line Endings Well I'll need to adjust that in my IDE... --- scripts/inquirer.sh | 1332 +++++++++++++++++++++---------------------- scripts/manage.sh | 174 +++--- 2 files changed, 753 insertions(+), 753 deletions(-) mode change 100644 => 100755 scripts/manage.sh diff --git a/scripts/inquirer.sh b/scripts/inquirer.sh index 02872f0f..48dde94d 100644 --- a/scripts/inquirer.sh +++ b/scripts/inquirer.sh @@ -1,667 +1,667 @@ -#!/usr/bin/env bash - -################## INQUIRER.SH ################## -# https://github.com/kahkhang/Inquirer.sh - -# The MIT License (MIT) - -# Copyright (c) 2017 - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# store the current set options -OLD_SET=$- -set -e - -arrow="$(echo -e '\xe2\x9d\xaf')" -checked="$(echo -e '\xe2\x97\x89')" -unchecked="$(echo -e '\xe2\x97\xaf')" - -black="$(tput setaf 0)" -red="$(tput setaf 1)" -green="$(tput setaf 2)" -yellow="$(tput setaf 3)" -blue="$(tput setaf 4)" -magenta="$(tput setaf 5)" -cyan="$(tput setaf 6)" -white="$(tput setaf 7)" -bold="$(tput bold)" -normal="$(tput sgr0)" -dim=$'\e[2m' - -print() { - echo "$1" - tput el -} - -join() { - local IFS=$'\n' - local _join_list - eval _join_list=( '"${'${1}'[@]}"' ) - local first=true - for item in ${_join_list[@]}; do - if [ "$first" = true ]; then - printf "%s" "$item" - first=false - else - printf "${2-, }%s" "$item" - fi - done -} - -function gen_env_from_options() { - local IFS=$'\n' - local _indices - local _env_names - local _checkbox_selected - eval _indices=( '"${'${1}'[@]}"' ) - eval _env_names=( '"${'${2}'[@]}"' ) - - for i in $(gen_index ${#_env_names[@]}); do - _checkbox_selected[$i]=false - done - - for i in ${_indices[@]}; do - _checkbox_selected[$i]=true - done - - for i in $(gen_index ${#_env_names[@]}); do - printf "%s=%s\n" "${_env_names[$i]}" "${_checkbox_selected[$i]}" - done -} - -on_default() { - true; -} - -on_keypress() { - local OLD_IFS - local IFS - local key - OLD_IFS=$IFS - local on_up=${1:-on_default} - local on_down=${2:-on_default} - local on_space=${3:-on_default} - local on_enter=${4:-on_default} - local on_left=${5:-on_default} - local on_right=${6:-on_default} - local on_ascii=${7:-on_default} - local on_backspace=${8:-on_default} - _break_keypress=false - while IFS="" read -rsn1 key; do - case "$key" in - $'\x1b') - read -rsn1 key - if [[ "$key" == "[" ]]; then - read -rsn1 key - case "$key" in - 'A') eval $on_up;; - 'B') eval $on_down;; - 'D') eval $on_left;; - 'C') eval $on_right;; - esac - fi - ;; - ' ') eval $on_space ' ';; - [a-z0-9A-Z\!\#\$\&\+\,\-\.\/\;\=\?\@\[\]\^\_\{\}\~]) eval $on_ascii $key;; - $'\x7f') eval $on_backspace $key;; - '') eval $on_enter $key;; - esac - if [ $_break_keypress = true ]; then - break - fi - done - IFS=$OLD_IFS -} - -gen_index() { - local k=$1 - local l=0 - if [ $k -gt 0 ]; then - for l in $(seq $k) - do - echo "$l-1" | bc - done - fi -} - -cleanup() { - # Reset character attributes, make cursor visible, and restore - # previous screen contents (if possible). - tput sgr0 - tput cnorm - stty echo - - # Restore `set e` option to its orignal value - if [[ $OLD_SET =~ e ]] - then set -e - else set +e - fi -} - -control_c() { - cleanup - exit $? -} - -select_indices() { - local _select_list - local _select_indices - local _select_selected=() - eval _select_list=( '"${'${1}'[@]}"' ) - eval _select_indices=( '"${'${2}'[@]}"' ) - local _select_var_name=$3 - eval $_select_var_name\=\(\) - for i in $(gen_index ${#_select_indices[@]}); do - eval $_select_var_name\+\=\(\""${_select_list[${_select_indices[$i]}]}"\"\) - done -} - - - - -on_checkbox_input_up() { - remove_checkbox_instructions - tput cub "$(tput cols)" - - if [ "${_checkbox_selected[$_current_index]}" = true ]; then - printf " ${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" - else - printf " ${unchecked} ${_checkbox_list[$_current_index]} ${normal}" - fi - tput el - - if [ $_current_index = 0 ]; then - _current_index=$((${#_checkbox_list[@]}-1)) - tput cud $((${#_checkbox_list[@]}-1)) - tput cub "$(tput cols)" - else - _current_index=$((_current_index-1)) - - tput cuu1 - tput cub "$(tput cols)" - tput el - fi - - if [ "${_checkbox_selected[$_current_index]}" = true ]; then - printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" - else - printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" - fi -} - -on_checkbox_input_down() { - remove_checkbox_instructions - tput cub "$(tput cols)" - - if [ "${_checkbox_selected[$_current_index]}" = true ]; then - printf " ${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" - else - printf " ${unchecked} ${_checkbox_list[$_current_index]} ${normal}" - fi - - tput el - - if [ $_current_index = $((${#_checkbox_list[@]}-1)) ]; then - _current_index=0 - tput cuu $((${#_checkbox_list[@]}-1)) - tput cub "$(tput cols)" - else - _current_index=$((_current_index+1)) - tput cud1 - tput cub "$(tput cols)" - tput el - fi - - if [ "${_checkbox_selected[$_current_index]}" = true ]; then - printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" - else - printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" - fi -} - -on_checkbox_input_enter() { - local OLD_IFS - OLD_IFS=$IFS - _checkbox_selected_indices=() - _checkbox_selected_options=() - IFS=$'\n' - - for i in $(gen_index ${#_checkbox_list[@]}); do - if [ "${_checkbox_selected[$i]}" = true ]; then - _checkbox_selected_indices+=($i) - _checkbox_selected_options+=("${_checkbox_list[$i]}") - fi - done - - tput cud $((${#_checkbox_list[@]}-${_current_index})) - tput cub "$(tput cols)" - - for i in $(seq $((${#_checkbox_list[@]}+1))); do - tput el1 - tput el - tput cuu1 - done - tput cub "$(tput cols)" - - tput cuf $((${#prompt}+3)) - printf "${cyan}$(join _checkbox_selected_options)${normal}" - tput el - - tput cud1 - tput cub "$(tput cols)" - tput el - - _break_keypress=true - IFS=$OLD_IFS -} - -on_checkbox_input_space() { - remove_checkbox_instructions - tput cub "$(tput cols)" - tput el - if [ "${_checkbox_selected[$_current_index]}" = true ]; then - _checkbox_selected[$_current_index]=false - else - _checkbox_selected[$_current_index]=true - fi - - if [ "${_checkbox_selected[$_current_index]}" = true ]; then - printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" - else - printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" - fi -} - -remove_checkbox_instructions() { - if [ $_first_keystroke = true ]; then - tput cuu $((${_current_index}+1)) - tput cub "$(tput cols)" - tput cuf $((${#prompt}+3)) - tput el - tput cud $((${_current_index}+1)) - _first_keystroke=false - fi -} - -# for vim movements -on_checkbox_input_ascii() { - local key=$1 - case $key in - "j" ) on_checkbox_input_down;; - "k" ) on_checkbox_input_up;; - esac -} - -_checkbox_input() { - local i - local j - prompt=$1 - eval _checkbox_list=( '"${'${2}'[@]}"' ) - _current_index=0 - _first_keystroke=true - - trap control_c SIGINT EXIT - - stty -echo - tput civis - - print "${normal}${green}?${normal} ${bold}${prompt}${normal} ${dim}(Press to select, to finalize)${normal}" - - for i in $(gen_index ${#_checkbox_list[@]}); do - _checkbox_selected[$i]=false - done - - if [ -n "$3" ]; then - eval _selected_indices=( '"${'${3}'[@]}"' ) - for i in ${_selected_indices[@]}; do - _checkbox_selected[$i]=true - done - fi - - for i in $(gen_index ${#_checkbox_list[@]}); do - tput cub "$(tput cols)" - if [ $i = 0 ]; then - if [ "${_checkbox_selected[$i]}" = true ]; then - print "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$i]} ${normal}" - else - print "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$i]} ${normal}" - fi - else - if [ "${_checkbox_selected[$i]}" = true ]; then - print " ${green}${checked}${normal} ${_checkbox_list[$i]} ${normal}" - else - print " ${unchecked} ${_checkbox_list[$i]} ${normal}" - fi - fi - tput el - done - - for j in $(gen_index ${#_checkbox_list[@]}); do - tput cuu1 - done - - on_keypress on_checkbox_input_up on_checkbox_input_down on_checkbox_input_space on_checkbox_input_enter on_default on_default on_checkbox_input_ascii -} - -checkbox_input() { - _checkbox_input "$1" "$2" - _checkbox_input_output_var_name=$3 - select_indices _checkbox_list _checkbox_selected_indices $_checkbox_input_output_var_name - - unset _checkbox_list - unset _break_keypress - unset _first_keystroke - unset _current_index - unset _checkbox_input_output_var_name - unset _checkbox_selected_indices - unset _checkbox_selected_options - - cleanup -} - -checkbox_input_indices() { - _checkbox_input "$1" "$2" "$3" - _checkbox_input_output_var_name=$3 - - eval $_checkbox_input_output_var_name\=\(\) - for i in $(gen_index ${#_checkbox_selected_indices[@]}); do - eval $_checkbox_input_output_var_name\+\=\(${_checkbox_selected_indices[$i]}\) - done - - unset _checkbox_list - unset _break_keypress - unset _first_keystroke - unset _current_index - unset _checkbox_input_output_var_name - unset _checkbox_selected_indices - unset _checkbox_selected_options - - cleanup -} - - - - -on_list_input_up() { - remove_list_instructions - tput cub "$(tput cols)" - - printf " ${_list_options[$_list_selected_index]}" - tput el - - if [ $_list_selected_index = 0 ]; then - _list_selected_index=$((${#_list_options[@]}-1)) - tput cud $((${#_list_options[@]}-1)) - tput cub "$(tput cols)" - else - _list_selected_index=$((_list_selected_index-1)) - - tput cuu1 - tput cub "$(tput cols)" - tput el - fi - - printf "${cyan}${arrow} %s ${normal}" "${_list_options[$_list_selected_index]}" -} - -on_list_input_down() { - remove_list_instructions - tput cub "$(tput cols)" - - printf " ${_list_options[$_list_selected_index]}" - tput el - - if [ $_list_selected_index = $((${#_list_options[@]}-1)) ]; then - _list_selected_index=0 - tput cuu $((${#_list_options[@]}-1)) - tput cub "$(tput cols)" - else - _list_selected_index=$((_list_selected_index+1)) - tput cud1 - tput cub "$(tput cols)" - tput el - fi - printf "${cyan}${arrow} %s ${normal}" "${_list_options[$_list_selected_index]}" -} - -on_list_input_enter_space() { - local OLD_IFS - OLD_IFS=$IFS - IFS=$'\n' - - tput cud $((${#_list_options[@]}-${_list_selected_index})) - tput cub "$(tput cols)" - - for i in $(seq $((${#_list_options[@]}+1))); do - tput el1 - tput el - tput cuu1 - done - tput cub "$(tput cols)" - - tput cuf $((${#prompt}+3)) - printf "${cyan}${_list_options[$_list_selected_index]}${normal}" - tput el - - tput cud1 - tput cub "$(tput cols)" - tput el - - _break_keypress=true - IFS=$OLD_IFS -} - -remove_list_instructions() { - if [ $_first_keystroke = true ]; then - tput cuu $((${_list_selected_index}+1)) - tput cub "$(tput cols)" - tput cuf $((${#prompt}+3)) - tput el - tput cud $((${_list_selected_index}+1)) - _first_keystroke=false - fi -} - -_list_input() { - local i - local j - prompt=$1 - eval _list_options=( '"${'${2}'[@]}"' ) - - _list_selected_index=0 - _first_keystroke=true - - trap control_c SIGINT EXIT - - stty -echo - tput civis - - print "${normal}${green}?${normal} ${bold}${prompt}${normal} ${dim}(Use arrow keys)${normal}" - - for i in $(gen_index ${#_list_options[@]}); do - tput cub "$(tput cols)" - if [ $i = 0 ]; then - print "${cyan}${arrow} ${_list_options[$i]} ${normal}" - else - print " ${_list_options[$i]}" - fi - tput el - done - - for j in $(gen_index ${#_list_options[@]}); do - tput cuu1 - done - - on_keypress on_list_input_up on_list_input_down on_list_input_enter_space on_list_input_enter_space - -} - - -list_input() { - _list_input "$1" "$2" - local var_name=$3 - eval $var_name=\'"${_list_options[$_list_selected_index]}"\' - unset _list_selected_index - unset _list_options - unset _break_keypress - unset _first_keystroke - - cleanup -} - -list_input_index() { - _list_input "$1" "$2" - local var_name=$3 - eval $var_name=\'"$_list_selected_index"\' - unset _list_selected_index - unset _list_options - unset _break_keypress - unset _first_keystroke - - cleanup -} - - - - -on_text_input_left() { - remove_regex_failed - if [ $_current_pos -gt 0 ]; then - tput cub1 - _current_pos=$(($_current_pos-1)) - fi -} - -on_text_input_right() { - remove_regex_failed - if [ $_current_pos -lt ${#_text_input} ]; then - tput cuf1 - _current_pos=$(($_current_pos+1)) - fi -} - -on_text_input_enter() { - remove_regex_failed - - if [[ "$_text_input" =~ $_text_input_regex && "$(eval $_text_input_validator "$_text_input")" = true ]]; then - tput cub "$(tput cols)" - tput cuf $((${#_read_prompt}-19)) - printf "${cyan}${_text_input}${normal}" - tput el - tput cud1 - tput cub "$(tput cols)" - tput el - eval $var_name=\'"${_text_input}"\' - _break_keypress=true - else - _text_input_regex_failed=true - tput civis - tput cud1 - tput cub "$(tput cols)" - tput el - printf "${red}>>${normal} $_text_input_regex_failed_msg" - tput cuu1 - tput cub "$(tput cols)" - tput cuf $((${#_read_prompt}-19)) - tput el - _text_input="" - _current_pos=0 - tput cnorm - fi -} - -on_text_input_ascii() { - remove_regex_failed - local c=$1 - - if [ "$c" = '' ]; then - c=' ' - fi - - local rest="${_text_input:$_current_pos}" - _text_input="${_text_input:0:$_current_pos}$c$rest" - _current_pos=$(($_current_pos+1)) - - tput civis - printf "$c$rest" - tput el - if [ ${#rest} -gt 0 ]; then - tput cub ${#rest} - fi - tput cnorm -} - -on_text_input_backspace() { - remove_regex_failed - if [ $_current_pos -gt 0 ]; then - local start="${_text_input:0:$(($_current_pos-1))}" - local rest="${_text_input:$_current_pos}" - _current_pos=$(($_current_pos-1)) - tput cub 1 - tput el - tput sc - printf "$rest" - tput rc - _text_input="$start$rest" - fi -} - -remove_regex_failed() { - if [ $_text_input_regex_failed = true ]; then - _text_input_regex_failed=false - tput sc - tput cud1 - tput el1 - tput el - tput rc - fi -} - -text_input_default_validator() { - echo true; -} - -text_input() { - local prompt=$1 - local var_name=$2 - local _text_input_regex="${3:-"\.+"}" - local _text_input_regex_failed_msg=${4:-"Input validation failed"} - local _text_input_validator=${5:-text_input_default_validator} - local _read_prompt_start=$'\e[32m?\e[39m\e[1m' - local _read_prompt_end=$'\e[22m' - local _read_prompt="$( echo "$_read_prompt_start ${prompt} $_read_prompt_end")" - local _current_pos=0 - local _text_input_regex_failed=false - local _text_input="" - printf "$_read_prompt" - - - trap control_c SIGINT EXIT - - stty -echo - tput cnorm - - on_keypress on_default on_default on_text_input_ascii on_text_input_enter on_text_input_left on_text_input_right on_text_input_ascii on_text_input_backspace - eval $var_name=\'"${_text_input}"\' - - cleanup -} - +#!/usr/bin/env bash + +################## INQUIRER.SH ################## +# https://github.com/kahkhang/Inquirer.sh + +# The MIT License (MIT) + +# Copyright (c) 2017 + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# store the current set options +OLD_SET=$- +set -e + +arrow="$(echo -e '\xe2\x9d\xaf')" +checked="$(echo -e '\xe2\x97\x89')" +unchecked="$(echo -e '\xe2\x97\xaf')" + +black="$(tput setaf 0)" +red="$(tput setaf 1)" +green="$(tput setaf 2)" +yellow="$(tput setaf 3)" +blue="$(tput setaf 4)" +magenta="$(tput setaf 5)" +cyan="$(tput setaf 6)" +white="$(tput setaf 7)" +bold="$(tput bold)" +normal="$(tput sgr0)" +dim=$'\e[2m' + +print() { + echo "$1" + tput el +} + +join() { + local IFS=$'\n' + local _join_list + eval _join_list=( '"${'${1}'[@]}"' ) + local first=true + for item in ${_join_list[@]}; do + if [ "$first" = true ]; then + printf "%s" "$item" + first=false + else + printf "${2-, }%s" "$item" + fi + done +} + +function gen_env_from_options() { + local IFS=$'\n' + local _indices + local _env_names + local _checkbox_selected + eval _indices=( '"${'${1}'[@]}"' ) + eval _env_names=( '"${'${2}'[@]}"' ) + + for i in $(gen_index ${#_env_names[@]}); do + _checkbox_selected[$i]=false + done + + for i in ${_indices[@]}; do + _checkbox_selected[$i]=true + done + + for i in $(gen_index ${#_env_names[@]}); do + printf "%s=%s\n" "${_env_names[$i]}" "${_checkbox_selected[$i]}" + done +} + +on_default() { + true; +} + +on_keypress() { + local OLD_IFS + local IFS + local key + OLD_IFS=$IFS + local on_up=${1:-on_default} + local on_down=${2:-on_default} + local on_space=${3:-on_default} + local on_enter=${4:-on_default} + local on_left=${5:-on_default} + local on_right=${6:-on_default} + local on_ascii=${7:-on_default} + local on_backspace=${8:-on_default} + _break_keypress=false + while IFS="" read -rsn1 key; do + case "$key" in + $'\x1b') + read -rsn1 key + if [[ "$key" == "[" ]]; then + read -rsn1 key + case "$key" in + 'A') eval $on_up;; + 'B') eval $on_down;; + 'D') eval $on_left;; + 'C') eval $on_right;; + esac + fi + ;; + ' ') eval $on_space ' ';; + [a-z0-9A-Z\!\#\$\&\+\,\-\.\/\;\=\?\@\[\]\^\_\{\}\~]) eval $on_ascii $key;; + $'\x7f') eval $on_backspace $key;; + '') eval $on_enter $key;; + esac + if [ $_break_keypress = true ]; then + break + fi + done + IFS=$OLD_IFS +} + +gen_index() { + local k=$1 + local l=0 + if [ $k -gt 0 ]; then + for l in $(seq $k) + do + echo "$l-1" | bc + done + fi +} + +cleanup() { + # Reset character attributes, make cursor visible, and restore + # previous screen contents (if possible). + tput sgr0 + tput cnorm + stty echo + + # Restore `set e` option to its orignal value + if [[ $OLD_SET =~ e ]] + then set -e + else set +e + fi +} + +control_c() { + cleanup + exit $? +} + +select_indices() { + local _select_list + local _select_indices + local _select_selected=() + eval _select_list=( '"${'${1}'[@]}"' ) + eval _select_indices=( '"${'${2}'[@]}"' ) + local _select_var_name=$3 + eval $_select_var_name\=\(\) + for i in $(gen_index ${#_select_indices[@]}); do + eval $_select_var_name\+\=\(\""${_select_list[${_select_indices[$i]}]}"\"\) + done +} + + + + +on_checkbox_input_up() { + remove_checkbox_instructions + tput cub "$(tput cols)" + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf " ${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf " ${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi + tput el + + if [ $_current_index = 0 ]; then + _current_index=$((${#_checkbox_list[@]}-1)) + tput cud $((${#_checkbox_list[@]}-1)) + tput cub "$(tput cols)" + else + _current_index=$((_current_index-1)) + + tput cuu1 + tput cub "$(tput cols)" + tput el + fi + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi +} + +on_checkbox_input_down() { + remove_checkbox_instructions + tput cub "$(tput cols)" + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf " ${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf " ${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi + + tput el + + if [ $_current_index = $((${#_checkbox_list[@]}-1)) ]; then + _current_index=0 + tput cuu $((${#_checkbox_list[@]}-1)) + tput cub "$(tput cols)" + else + _current_index=$((_current_index+1)) + tput cud1 + tput cub "$(tput cols)" + tput el + fi + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi +} + +on_checkbox_input_enter() { + local OLD_IFS + OLD_IFS=$IFS + _checkbox_selected_indices=() + _checkbox_selected_options=() + IFS=$'\n' + + for i in $(gen_index ${#_checkbox_list[@]}); do + if [ "${_checkbox_selected[$i]}" = true ]; then + _checkbox_selected_indices+=($i) + _checkbox_selected_options+=("${_checkbox_list[$i]}") + fi + done + + tput cud $((${#_checkbox_list[@]}-${_current_index})) + tput cub "$(tput cols)" + + for i in $(seq $((${#_checkbox_list[@]}+1))); do + tput el1 + tput el + tput cuu1 + done + tput cub "$(tput cols)" + + tput cuf $((${#prompt}+3)) + printf "${cyan}$(join _checkbox_selected_options)${normal}" + tput el + + tput cud1 + tput cub "$(tput cols)" + tput el + + _break_keypress=true + IFS=$OLD_IFS +} + +on_checkbox_input_space() { + remove_checkbox_instructions + tput cub "$(tput cols)" + tput el + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + _checkbox_selected[$_current_index]=false + else + _checkbox_selected[$_current_index]=true + fi + + if [ "${_checkbox_selected[$_current_index]}" = true ]; then + printf "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$_current_index]} ${normal}" + else + printf "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$_current_index]} ${normal}" + fi +} + +remove_checkbox_instructions() { + if [ $_first_keystroke = true ]; then + tput cuu $((${_current_index}+1)) + tput cub "$(tput cols)" + tput cuf $((${#prompt}+3)) + tput el + tput cud $((${_current_index}+1)) + _first_keystroke=false + fi +} + +# for vim movements +on_checkbox_input_ascii() { + local key=$1 + case $key in + "j" ) on_checkbox_input_down;; + "k" ) on_checkbox_input_up;; + esac +} + +_checkbox_input() { + local i + local j + prompt=$1 + eval _checkbox_list=( '"${'${2}'[@]}"' ) + _current_index=0 + _first_keystroke=true + + trap control_c SIGINT EXIT + + stty -echo + tput civis + + print "${normal}${green}?${normal} ${bold}${prompt}${normal} ${dim}(Press to select, to finalize)${normal}" + + for i in $(gen_index ${#_checkbox_list[@]}); do + _checkbox_selected[$i]=false + done + + if [ -n "$3" ]; then + eval _selected_indices=( '"${'${3}'[@]}"' ) + for i in ${_selected_indices[@]}; do + _checkbox_selected[$i]=true + done + fi + + for i in $(gen_index ${#_checkbox_list[@]}); do + tput cub "$(tput cols)" + if [ $i = 0 ]; then + if [ "${_checkbox_selected[$i]}" = true ]; then + print "${cyan}${arrow}${green}${checked}${normal} ${_checkbox_list[$i]} ${normal}" + else + print "${cyan}${arrow}${normal}${unchecked} ${_checkbox_list[$i]} ${normal}" + fi + else + if [ "${_checkbox_selected[$i]}" = true ]; then + print " ${green}${checked}${normal} ${_checkbox_list[$i]} ${normal}" + else + print " ${unchecked} ${_checkbox_list[$i]} ${normal}" + fi + fi + tput el + done + + for j in $(gen_index ${#_checkbox_list[@]}); do + tput cuu1 + done + + on_keypress on_checkbox_input_up on_checkbox_input_down on_checkbox_input_space on_checkbox_input_enter on_default on_default on_checkbox_input_ascii +} + +checkbox_input() { + _checkbox_input "$1" "$2" + _checkbox_input_output_var_name=$3 + select_indices _checkbox_list _checkbox_selected_indices $_checkbox_input_output_var_name + + unset _checkbox_list + unset _break_keypress + unset _first_keystroke + unset _current_index + unset _checkbox_input_output_var_name + unset _checkbox_selected_indices + unset _checkbox_selected_options + + cleanup +} + +checkbox_input_indices() { + _checkbox_input "$1" "$2" "$3" + _checkbox_input_output_var_name=$3 + + eval $_checkbox_input_output_var_name\=\(\) + for i in $(gen_index ${#_checkbox_selected_indices[@]}); do + eval $_checkbox_input_output_var_name\+\=\(${_checkbox_selected_indices[$i]}\) + done + + unset _checkbox_list + unset _break_keypress + unset _first_keystroke + unset _current_index + unset _checkbox_input_output_var_name + unset _checkbox_selected_indices + unset _checkbox_selected_options + + cleanup +} + + + + +on_list_input_up() { + remove_list_instructions + tput cub "$(tput cols)" + + printf " ${_list_options[$_list_selected_index]}" + tput el + + if [ $_list_selected_index = 0 ]; then + _list_selected_index=$((${#_list_options[@]}-1)) + tput cud $((${#_list_options[@]}-1)) + tput cub "$(tput cols)" + else + _list_selected_index=$((_list_selected_index-1)) + + tput cuu1 + tput cub "$(tput cols)" + tput el + fi + + printf "${cyan}${arrow} %s ${normal}" "${_list_options[$_list_selected_index]}" +} + +on_list_input_down() { + remove_list_instructions + tput cub "$(tput cols)" + + printf " ${_list_options[$_list_selected_index]}" + tput el + + if [ $_list_selected_index = $((${#_list_options[@]}-1)) ]; then + _list_selected_index=0 + tput cuu $((${#_list_options[@]}-1)) + tput cub "$(tput cols)" + else + _list_selected_index=$((_list_selected_index+1)) + tput cud1 + tput cub "$(tput cols)" + tput el + fi + printf "${cyan}${arrow} %s ${normal}" "${_list_options[$_list_selected_index]}" +} + +on_list_input_enter_space() { + local OLD_IFS + OLD_IFS=$IFS + IFS=$'\n' + + tput cud $((${#_list_options[@]}-${_list_selected_index})) + tput cub "$(tput cols)" + + for i in $(seq $((${#_list_options[@]}+1))); do + tput el1 + tput el + tput cuu1 + done + tput cub "$(tput cols)" + + tput cuf $((${#prompt}+3)) + printf "${cyan}${_list_options[$_list_selected_index]}${normal}" + tput el + + tput cud1 + tput cub "$(tput cols)" + tput el + + _break_keypress=true + IFS=$OLD_IFS +} + +remove_list_instructions() { + if [ $_first_keystroke = true ]; then + tput cuu $((${_list_selected_index}+1)) + tput cub "$(tput cols)" + tput cuf $((${#prompt}+3)) + tput el + tput cud $((${_list_selected_index}+1)) + _first_keystroke=false + fi +} + +_list_input() { + local i + local j + prompt=$1 + eval _list_options=( '"${'${2}'[@]}"' ) + + _list_selected_index=0 + _first_keystroke=true + + trap control_c SIGINT EXIT + + stty -echo + tput civis + + print "${normal}${green}?${normal} ${bold}${prompt}${normal} ${dim}(Use arrow keys)${normal}" + + for i in $(gen_index ${#_list_options[@]}); do + tput cub "$(tput cols)" + if [ $i = 0 ]; then + print "${cyan}${arrow} ${_list_options[$i]} ${normal}" + else + print " ${_list_options[$i]}" + fi + tput el + done + + for j in $(gen_index ${#_list_options[@]}); do + tput cuu1 + done + + on_keypress on_list_input_up on_list_input_down on_list_input_enter_space on_list_input_enter_space + +} + + +list_input() { + _list_input "$1" "$2" + local var_name=$3 + eval $var_name=\'"${_list_options[$_list_selected_index]}"\' + unset _list_selected_index + unset _list_options + unset _break_keypress + unset _first_keystroke + + cleanup +} + +list_input_index() { + _list_input "$1" "$2" + local var_name=$3 + eval $var_name=\'"$_list_selected_index"\' + unset _list_selected_index + unset _list_options + unset _break_keypress + unset _first_keystroke + + cleanup +} + + + + +on_text_input_left() { + remove_regex_failed + if [ $_current_pos -gt 0 ]; then + tput cub1 + _current_pos=$(($_current_pos-1)) + fi +} + +on_text_input_right() { + remove_regex_failed + if [ $_current_pos -lt ${#_text_input} ]; then + tput cuf1 + _current_pos=$(($_current_pos+1)) + fi +} + +on_text_input_enter() { + remove_regex_failed + + if [[ "$_text_input" =~ $_text_input_regex && "$(eval $_text_input_validator "$_text_input")" = true ]]; then + tput cub "$(tput cols)" + tput cuf $((${#_read_prompt}-19)) + printf "${cyan}${_text_input}${normal}" + tput el + tput cud1 + tput cub "$(tput cols)" + tput el + eval $var_name=\'"${_text_input}"\' + _break_keypress=true + else + _text_input_regex_failed=true + tput civis + tput cud1 + tput cub "$(tput cols)" + tput el + printf "${red}>>${normal} $_text_input_regex_failed_msg" + tput cuu1 + tput cub "$(tput cols)" + tput cuf $((${#_read_prompt}-19)) + tput el + _text_input="" + _current_pos=0 + tput cnorm + fi +} + +on_text_input_ascii() { + remove_regex_failed + local c=$1 + + if [ "$c" = '' ]; then + c=' ' + fi + + local rest="${_text_input:$_current_pos}" + _text_input="${_text_input:0:$_current_pos}$c$rest" + _current_pos=$(($_current_pos+1)) + + tput civis + printf "$c$rest" + tput el + if [ ${#rest} -gt 0 ]; then + tput cub ${#rest} + fi + tput cnorm +} + +on_text_input_backspace() { + remove_regex_failed + if [ $_current_pos -gt 0 ]; then + local start="${_text_input:0:$(($_current_pos-1))}" + local rest="${_text_input:$_current_pos}" + _current_pos=$(($_current_pos-1)) + tput cub 1 + tput el + tput sc + printf "$rest" + tput rc + _text_input="$start$rest" + fi +} + +remove_regex_failed() { + if [ $_text_input_regex_failed = true ]; then + _text_input_regex_failed=false + tput sc + tput cud1 + tput el1 + tput el + tput rc + fi +} + +text_input_default_validator() { + echo true; +} + +text_input() { + local prompt=$1 + local var_name=$2 + local _text_input_regex="${3:-"\.+"}" + local _text_input_regex_failed_msg=${4:-"Input validation failed"} + local _text_input_validator=${5:-text_input_default_validator} + local _read_prompt_start=$'\e[32m?\e[39m\e[1m' + local _read_prompt_end=$'\e[22m' + local _read_prompt="$( echo "$_read_prompt_start ${prompt} $_read_prompt_end")" + local _current_pos=0 + local _text_input_regex_failed=false + local _text_input="" + printf "$_read_prompt" + + + trap control_c SIGINT EXIT + + stty -echo + tput cnorm + + on_keypress on_default on_default on_text_input_ascii on_text_input_enter on_text_input_left on_text_input_right on_text_input_ascii on_text_input_backspace + eval $var_name=\'"${_text_input}"\' + + cleanup +} + ################## INQUIRER.SH ################## \ No newline at end of file diff --git a/scripts/manage.sh b/scripts/manage.sh old mode 100644 new mode 100755 index 84ef00a3..9e2cebda --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -1,88 +1,88 @@ -#!/usr/bin/env bash - -REPO="Z-Bolt/OctoScreen" -MAIN="master" -RELEASES="https://api.github.com/repos/$REPO/releases/latest" -WGET_RAW="https://github.com/$REPO/raw/$MAIN" - -source <(wget -qO- "$WGET_RAW/scripts/inquirer.sh") - -exit - -arch=$(uname -m) -#if [[ $arch == x86_64 ]]; then -# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*amd64.deb" | cut -d '"' -f 4) -#elif [[ $arch == aarch64 ]]; then -# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*arm64.deb" | cut -d '"' -f 4) -if [[ $arch == arm* ]]; then - releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) -fi -dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" -IFS='/' read -ra version <<< "$releaseURL" - -echo "Installing OctoScreen "${version[7]}, $arch"" - -echo "Installing Dependencies ..." -sudo apt -qq update -sudo apt -qq install $dependencies -y - -if [ -d "/home/pi/OctoPrint/venv" ]; then - DIRECTORY="/home/pi/OctoPrint/venv" -elif [ -d "/home/pi/oprint" ]; then - DIRECTORY="/home/pi/oprint" -else - echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." - echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." - text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY -fi; - -if [ $DIRECTORY == "-" ]; then - echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." -elif [ ! -d $DIRECTORY ]; then - echo "Can't find OctoPrint Installation, please run the script again!" - exit 1 -fi; - -#if [ $DIRECTORY != "-" ]; then -# plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) -# checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins -# echo "Installing Plugins..." -# -# if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" -# fi; -#fi; - -echo "Installing OctoScreen "${version[7]}, $arch" ..." -cd ~ -wget -O octoscreen.deb $releaseURL -q --show-progress - -sudo dpkg -i octodash.deb - -rm octodash.deb - -yes_no=( 'yes' 'no' ) - -list_input "Shall I reboot your Pi now?" yes_no reboot -echo "OctoScreen has been successfully installed! :)" -if [ $reboot == 'yes' ]; then - sudo reboot +#!/usr/bin/env bash + +REPO="Z-Bolt/OctoScreen" +MAIN="master" +RELEASES="https://api.github.com/repos/$REPO/releases/latest" +WGET_RAW="https://github.com/$REPO/raw/$MAIN" + +source <(wget -qO- "$WGET_RAW/scripts/inquirer.sh") + +exit + +arch=$(uname -m) +#if [[ $arch == x86_64 ]]; then +# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*amd64.deb" | cut -d '"' -f 4) +#elif [[ $arch == aarch64 ]]; then +# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*arm64.deb" | cut -d '"' -f 4) +if [[ $arch == arm* ]]; then + releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) +fi +dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" +IFS='/' read -ra version <<< "$releaseURL" + +echo "Installing OctoScreen "${version[7]}, $arch"" + +echo "Installing Dependencies ..." +sudo apt -qq update +sudo apt -qq install $dependencies -y + +if [ -d "/home/pi/OctoPrint/venv" ]; then + DIRECTORY="/home/pi/OctoPrint/venv" +elif [ -d "/home/pi/oprint" ]; then + DIRECTORY="/home/pi/oprint" +else + echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." + echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." + text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY +fi; + +if [ $DIRECTORY == "-" ]; then + echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." +elif [ ! -d $DIRECTORY ]; then + echo "Can't find OctoPrint Installation, please run the script again!" + exit 1 +fi; + +#if [ $DIRECTORY != "-" ]; then +# plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) +# checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins +# echo "Installing Plugins..." +# +# if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" +# fi; +# if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then +# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" +# fi; +#fi; + +echo "Installing OctoScreen "${version[7]}, $arch" ..." +cd ~ +wget -O octoscreen.deb $releaseURL -q --show-progress + +sudo dpkg -i octodash.deb + +rm octodash.deb + +yes_no=( 'yes' 'no' ) + +list_input "Shall I reboot your Pi now?" yes_no reboot +echo "OctoScreen has been successfully installed! :)" +if [ $reboot == 'yes' ]; then + sudo reboot fi \ No newline at end of file From dbbf13a1c61c64c1e6e3f2577bdb7bae9de0495e Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Sat, 6 Mar 2021 16:59:18 +0000 Subject: [PATCH 03/61] Use expr instead of bc. `bc` is not always available, and we won't be using any of the special functions, so use standard `expr` instead. --- scripts/inquirer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/inquirer.sh b/scripts/inquirer.sh index 48dde94d..32f7d2ab 100644 --- a/scripts/inquirer.sh +++ b/scripts/inquirer.sh @@ -136,7 +136,7 @@ gen_index() { if [ $k -gt 0 ]; then for l in $(seq $k) do - echo "$l-1" | bc + expr $l - 1 done fi } From 529e99deb5604c5e8b97dd6a6fb30f9dea49e267 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 12:19:42 +0000 Subject: [PATCH 04/61] Add Optparse Library from thebeline/optparse --- scripts/optparse.sh | 562 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 562 insertions(+) create mode 100644 scripts/optparse.sh diff --git a/scripts/optparse.sh b/scripts/optparse.sh new file mode 100644 index 00000000..c40924f3 --- /dev/null +++ b/scripts/optparse.sh @@ -0,0 +1,562 @@ +#!/usr/bin/env bash +declare -g optparse_license="$(cat < +# +# Contributors: +# Alessio Biancone +# Mike Mulligan +EOL +)" + +function optparse.init(){ + + unset optparse_version + unset optparse_usage + unset optparse_process + unset optparse_defaults + unset optparse_name + unset optparse_usage_header + unset optparse_variables_validate + unset optparse_default_group + + declare -g optparse_version="0.0.2" + + declare -g optparse_defaults="" + declare -g optparse_process="" + declare -g optparse_variables_validate="" + declare -g optparse_shortnames=() + declare -g optparse_longnames=() + declare -g optparse_variables=() + + for option in "$@"; do + local key="${option%%=*}"; + local value="${option#*=}"; + + case "$key" in + "default_group"|"name"|"usage_header"|"description") + declare -g optparse_$key="$value" + ;; + "help_full_width") + if ! [[ "$value" =~ ^[0-9]+$ ]]; then + optparse.throw_error "optparse.init '$key' must be of type INTIGER" + fi + declare -g optparse_$key="$value" + ;; + esac + done + + [ -z "$optparse_help_full_width" ] && declare -g optparse_help_full_width=80 + [ -z "$optparse_default_group" ] && declare -g optparse_default_group="OPTIONS" + [ -z "$optparse_name" ] && declare -g optparse_name="$(basename $0)" + [ -z "$optparse_usage_header" ] && declare -g optparse_usage_header="[OPTIONS]" + [ -z "$optparse_description" ] && declare -g optparse_description="${optparse_name} Help" + + optparse.define long=help desc="This Help Screen" dispatch="optparse.usage" behaviour=flag help=explicit + optparse.define long=optparse_license desc="The OptParse Library License" dispatch="optparse.license" help=hide + +} + +# ----------------------------------------------------------------------------------------------------------------------------- +function optparse.throw_error(){ + local message="$1" + [ ! -z $2 ] && message+=" for option: ($2)" + optparse._log "ERROR" "$message" + exit 1 +} + +function optparse._log(){ + local type="$1" + local message="$2" + echo "OPTPARSE $type: $message" +} + +function optparse.warn(){ + local message="$1" + [ ! -z $2 ] && message+=" for option: ($2)" + optparse._log "WARN" "$message" +} + +function optparse.group(){ + local group="$1" + [ ! -z "$group" ] && [ ! -z "$optparse_usage" ] && group="#NL$group" + optparse_usage+="echo \"$group\";#NL" +} + +# ----------------------------------------------------------------------------------------------------------------------------- +function optparse.define(){ + local errorname="" + local short="" + local shortname="" + local long="" + local longname="" + local desc="" + local default="" + local behaviour="default" + local list=false + local variable="" + local dispatch="" + local val="" + local has_val="false" + local has_default="false" + local behaviour_help="default" + local behaviour_extra="" + local optparse_help_indent=15 + local debug="false" + + for option in "$@"; do + local key="${option%%=*}"; + local value="${option#*=}"; + + case "$key" in + "short") + [ -z errorname ] && + errorname="$value" + [ ${#value} -ne 1 ] && + optparse.throw_error "short name expected to be one character long" "$errorname" + for i in "${optparse_shortnames[@]}"; do + if [ "$i" == "$value" ] ; then + optparse.warn "shortname [-$value] already handled" "$errorname" + fi + done + optparse_shortnames+=("$value") + shortname="$value" + short="-$value" + ;; + "long") + [ -z ${value} ] && + optparse.throw_error "long name expected to be atleast one character long" "$error_name" + for i in "${optparse_longnames[@]}"; do + if [ "$i" == "$value" ] ; then + optparse.warn "longname [--$value] already handled" "$errorname" + fi + done + optparse_longnames+=("$value") + longname="$value" + errorname="$value" + long="--$value" + ;; + "desc") + desc="$value" + ;; + "default") + default="$value" + has_default="true" + ;; + "behaviour") + case $value in + default|list|flag) + behaviour="$value" + ;; + *) + optparse.throw_error "behaviour [$value] not supported" "$errorname" + ;; + esac + ;; + "list") + list="$value" + ;; + "variable") + variable="$value" + for i in "${optparse_variables[@]}"; do + if [ "$i" == "$value" ] ; then + optparse.warn "value assignment [\$$value] already handled" "$errorname" + fi + done + optparse_variables+=("$value") + ;; + "value") + val="$value" + ;; + "dispatch") + dispatch="$value" + ;; + "explicit_help") + always_help=false + ;; + "debug") + debug=true + ;; + "extra"|"help") + case $value in + default|explicit|hide) + declare behaviour_$key="$value" + ;; + *) + optparse.throw_error "$key [$value] not supported" "$errorname" + ;; + esac + ;; + esac + done + + [ -z $behaviour_extra ] && { + [ "$behaviour" == "flag" ] && behaviour_extra="hide" || behaviour_extra="explicit" + } + + [ -z "$errorname" ] && optparse.throw_error "argument must have a long or short name" + + flag=$([[ $behaviour == "flag" ]] && echo "true" || echo "false") + is_list=$([[ $behaviour == "list" ]] && echo "true" || echo "false") + + [ $behaviour == "flag" ] && { + [ -z $default ] && default=false + has_default=true + [ $default = "true" ] && val="false" + [ $default = "false" ] && val="true" + } + + has_val=$([[ -z "$val" ]] && echo "false" || echo "true") + has_variable=$([[ -z "$variable" ]] && echo "false" || echo "true") + + # check list behaviour + [ $behaviour == "list" ] && { + [[ -z ${list:-} ]] && + optparse.throw_error "list is mandatory when using list behaviour" "$errorname" + + $has_default && { + valid=false + for i in $list; do + [[ $default == $i ]] && valid=true && break + done + + $valid || optparse.throw_error "default should be in list" "$errorname" + } + } + + if [ -z "$desc" ]; then + if [ -z "$dispatch" ]; then + optparse.throw_error "description is mandatory" "$errorname" + else + [ "$behaviour_help" == "default" ] && help_behaviour="explicit" + [ "$behaviour_help" != "hide" ] && desc="Executes $dispatch" + fi + fi + + [ -z "$variable" ] && [ -z "$dispatch" ] && optparse.throw_error "you must give a target variable" "$errorname" + + + [ -z "$optparse_usage" ] && optparse.group "$optparse_default_group" + + + [ "$behaviour_help" != "hide" ] && { + + local _optparse_usage="" + + # build OPTIONS and help + + local description=() + local description_index=0 + local description_word="" + local description_sep="" + local description_char_index=0 + + # Break to lines + + #for (( description_char_index=0; description_char_index<${#desc}; description_char_index++ )); do + # #echo "${foo:$i:1}" + # : + #done + + #_optparse_usage+="cat >&2 << EOU" + _optparse_usage+="#TB$(printf "%-${optparse_help_indent}s %s" "${short:= }$([ ! -z $short ] && [ ! -z $long ] && echo "," || echo " ") ${long}" "${desc}")" + # -h, --help T + + _optparse_usage="cat >&2 << EOU#NL$_optparse_usage#NLEOU#NL" + + [ "$behaviour_extra" != "hide" ] && { + + local _optparse_extra="" + + $is_list && _optparse_extra+="#TB#TB#TBOne of: '$list'#NL" + + $flag && { + _optparse_extra+="#TB#TB#TBTreated as a Flag#NL" + } || { + ${has_default} && + _optparse_extra+="#TB#TB#TBDefault: '$default'#NL" + } + + [ ! -z "$_optparse_extra" ] && { + + _optparse_extra="cat >&2 << EOE#NL${_optparse_extra}EOE#NL" + + [ "$behaviour_extra" == "explicit" ] && + _optparse_extra="if [[ \$1 == "true" ]]; then#NL$_optparse_extra#NLfi#NL" + + _optparse_usage+="$_optparse_extra" + } + } + + [ "$behaviour_help" == "explicit" ] && + _optparse_usage="if [[ \$1 == "true" ]]; then#NL$_optparse_usage#NLfi#NL" + + optparse_usage+="$_optparse_usage" + + #echo "$_optparse_usage" + } + + $has_default && [ ! -z "$variable" ] && + optparse_defaults+="#NL${variable}='${default}'" + + local validate_variable="$is_list && { + valid=false + for i in $list; do + [[ \$optparse_processing_arg_value == \$i ]] && valid=true && break + done + \$valid || optparse.usage false \"ERROR: invalid value for argument \\\"\$_optparse_arg_errorname\\\"\" 1 + } + $has_variable && [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage false \"ERROR: (\$_optparse_arg_errorname) requires input value\" 1" + + local dispatch_caller="# No Dispatcher" + + [ ! -z "$dispatch" ] && { + [ -z "$dispatch_var" ] && { + $has_variable && dispatch_var="\"\$${variable}\"" || dispatch_var="\"\$optparse_processing_arg_value\"" + } + dispatch_caller="${dispatch} ${dispatch_var}" + } + + [ ! -z "$shortname" ] && { + optparse_process_short+=" + ${shortname}) + _optparse_arg_errorname=\"$short\" + optparse_processing_arg_value=\"\" + ( $flag || $has_val ) && optparse_processing_arg_value=\"$val\" || { + $has_variable && { + optparse_processing_arg_value=\"\$optparse_processing_arg\"; + if [ -z \"\$optparse_processing_arg_value\" ]; then + optparse_processing_arg_value=\"\$1\" && shift + else + optparse_processing_arg='' + fi + } + } + $has_variable && ${variable}=\"\$optparse_processing_arg_value\" + $validate_variable + $dispatch_caller + continue + ;;" + } + + [ ! -z "$longname" ] && { + optparse_process_long+=" + ${longname}) + _optparse_arg_errorname=\"$long\" + $has_val && { + [ ! -z \"\$optparse_processing_arg_value\" ] && optparse.usage true 'ERROR: (${errorname}) does not accept user input' 1 + optparse_processing_arg_value=\"$val\" + } + $has_variable && ${variable}=\"\$optparse_processing_arg_value\" + $validate_variable + $dispatch_caller + continue + ;;" + } + + $has_variable && optparse_variables_validate+=" + [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true" +} + +# ----------------------------------------------------------------------------------------------------------------------------- +function optparse.build(){ + + local preserve_positional=false + local allow_unrecognized=false + local optparse_debug=false + local unknown_long_handler='' + local unknown_short_handler='' + local non_empty_shorts='' + + local _optparse_process=$optparse_process + local _optparse_variables_validate=$optparse_variables_validate + + for option in "$@"; do + local key="${option%%=*}"; + local value="${option#*=}"; + + case "$key" in + "version") + optparse_version="$value" + ;; + "allow") + value=( $value ) + for allowed in "${value[@]}"; do + case "$allowed" in + "positional") + preserve_positional=true + ;; + "unrecognized") + allow_unrecognized=true + ;; + *) + optparse.throw_error "Unhandled Allowance '$allow'" + ;; + esac + done + ;; + "debug") + optparse_debug=true + ;; + esac + done + + $preserve_positional && { + preserve_positional=" + [ ! -z \"\$optparse_processing_arg\" ] && { + $optparse_debug && echo \"Passing positional arg to args \\\"\$optparse_processing_arg\\\"\" + optparse_processing_args+=( \"\$optparse_processing_arg\" ) + }" + } || { + preserve_positional="optparse.usage true \"ERROR: Unconfigured Arguments are not accepted.\" 1" + } + + $allow_unrecognized && { + unknown_long_handler=" + $optparse_debug && echo \"Passing unknown long to args \$optparse_processing_arg\" + optparse_processing_args+=( \"\$optparse_processing_arg\" ) + continue" + unknown_short_handler=" + $optparse_debug && echo \"Passing unknown short '\$optparse_processing_arg_key' to args \$optparse_processing_arg\" + optparse_processing_arg+=\"\$optparse_processing_arg_key\" + continue" + non_empty_shorts=" + [ ! -z \"\$optparse_processing_arg\" ] && { + $optparse_debug && echo \"Passing non-empty shorts '-\$optparse_processing_arg' to args \$optparse_processing_arg\" + optparse_processing_args+=(\"-\$optparse_processing_arg\") + continue + }" + } || { + unknown_long_handler="optparse.usage true \"Unrecognized option: \$optparse_processing_arg_key\" 1" + unknown_short_handler="$unknown_long_handler" + } + + # Function usage + cat <&2 << EOH +${optparse_description} +Usage: $optparse_name $optparse_usage_header + +EOH +$optparse_usage +cat >&2 << EOH + +\$(printf "%${optparse_help_full_width}s %s" "Powered by optparse $optparse_version") +\$(printf "%${optparse_help_full_width}s %s" "@see --optparse_license") +EOH +if [ "\$1" == "true" ] && [ ! -z "\$3" ]; then + exit "\$3" +else + exit 3 +fi +} + +# Set default variable values +$optparse_defaults + +optparse_processing_args=() + +# Begin Parseing +while [ \$# -ne 0 ]; do + optparse_processing_arg="\$1" + shift + + case "\$optparse_processing_arg" in + --) + optparse_processing_args+=("--") && break + ;; + + --*) + + optparse_processing_arg_key="\${optparse_processing_arg%%=*}"; + optparse_processing_arg_value="\${optparse_processing_arg#*=}"; + + [ "\$optparse_processing_arg_value" == "\$optparse_processing_arg_key" ] && optparse_processing_arg_value='' + + case "\${optparse_processing_arg_key:2}" in + $optparse_process_long + esac + + $unknown_long_handler + + ;; + + -*) + + optparse_processing_arg_short="\${optparse_processing_arg:1}" + optparse_processing_arg='' + + while [ \${#optparse_processing_arg_short} -ne 0 ]; do + + optparse_processing_arg_key="\${optparse_processing_arg_short:0:1}"; + optparse_processing_arg_short="\${optparse_processing_arg_short:1}" + optparse_processing_arg_value=''; + + case "\$optparse_processing_arg_key" in + $optparse_process_short + esac + + $unknown_short_handler + + done + + $non_empty_shorts + + ;; + + $default_handler + + esac + + $preserve_positional + +done + +# GODLY arg quote with printf, WHERE HAVE YOU BEEN?? +eval set -- "\$([ ! -z "$optparse_processing_args" ] && printf ' %q' "\${optparse_processing_args[@]}") \$(printf ' %q' "\${@}")" + +$optparse_variables_validate + +unset _optparse_params +unset _optparse_param + +EOF + + if [ -z "$optparse_preserve" ] ; then + # Unset global variables + optparse.init + fi +} +optparse.init \ No newline at end of file From fb9f919e8a4f99d697b5c55a6716b5dfc837fc99 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 13:42:04 +0000 Subject: [PATCH 05/61] Fine-tuning the Bash Manager dependency loader. Note: This has debug code in it to test remote sourcing. Please Hold. --- scripts/{inquirer.sh => inquirer.bash} | 0 scripts/manage.sh | 16 ++++++--- scripts/{optparse.sh => optparse.bash} | 50 +++++++++++++++++--------- 3 files changed, 45 insertions(+), 21 deletions(-) rename scripts/{inquirer.sh => inquirer.bash} (100%) rename scripts/{optparse.sh => optparse.bash} (95%) diff --git a/scripts/inquirer.sh b/scripts/inquirer.bash similarity index 100% rename from scripts/inquirer.sh rename to scripts/inquirer.bash diff --git a/scripts/manage.sh b/scripts/manage.sh index 9e2cebda..32aa0a4c 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -4,10 +4,17 @@ REPO="Z-Bolt/OctoScreen" MAIN="master" RELEASES="https://api.github.com/repos/$REPO/releases/latest" WGET_RAW="https://github.com/$REPO/raw/$MAIN" +LIBRARIES=("inquirer.bash" "optparse.bash") -source <(wget -qO- "$WGET_RAW/scripts/inquirer.sh") +SOURCE="${BASH_SOURCE[0]}"; while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done +DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" -exit +echo "$DIR" +return + +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE="scripts/$LIBRARY"; if [[ ! -f "$SOURCE_FILE" ]]; then echo -e "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}'..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; unset SOURCE_FILE; done; echo -en "${CL}${CL}"; + +yes_no=( 'yes' 'no' ) arch=$(uname -m) #if [[ $arch == x86_64 ]]; then @@ -75,11 +82,10 @@ echo "Installing OctoScreen "${version[7]}, $arch" ..." cd ~ wget -O octoscreen.deb $releaseURL -q --show-progress -sudo dpkg -i octodash.deb +sudo dpkg -i octoscreen.deb -rm octodash.deb +rm octoscreen.deb -yes_no=( 'yes' 'no' ) list_input "Shall I reboot your Pi now?" yes_no reboot echo "OctoScreen has been successfully installed! :)" diff --git a/scripts/optparse.sh b/scripts/optparse.bash similarity index 95% rename from scripts/optparse.sh rename to scripts/optparse.bash index c40924f3..ea45daee 100644 --- a/scripts/optparse.sh +++ b/scripts/optparse.bash @@ -35,15 +35,6 @@ EOL function optparse.init(){ - unset optparse_version - unset optparse_usage - unset optparse_process - unset optparse_defaults - unset optparse_name - unset optparse_usage_header - unset optparse_variables_validate - unset optparse_default_group - declare -g optparse_version="0.0.2" declare -g optparse_defaults="" @@ -58,9 +49,14 @@ function optparse.init(){ local value="${option#*=}"; case "$key" in - "default_group"|"name"|"usage_header"|"description") + "default_group"|"usage_header"|"description") declare -g optparse_$key="$value" ;; + "name") + [[ "${value::1}" == "-" ]] && + declare -g optparse_name="" || + declare -g optparse_name="$(basename $value)" + ;; "help_full_width") if ! [[ "$value" =~ ^[0-9]+$ ]]; then optparse.throw_error "optparse.init '$key' must be of type INTIGER" @@ -70,17 +66,37 @@ function optparse.init(){ esac done - [ -z "$optparse_help_full_width" ] && declare -g optparse_help_full_width=80 - [ -z "$optparse_default_group" ] && declare -g optparse_default_group="OPTIONS" - [ -z "$optparse_name" ] && declare -g optparse_name="$(basename $0)" - [ -z "$optparse_usage_header" ] && declare -g optparse_usage_header="[OPTIONS]" - [ -z "$optparse_description" ] && declare -g optparse_description="${optparse_name} Help" + [[ -z "$optparse_name" ]] && { + [[ "${0::1}" == "-" ]] && + declare -g optparse_name="" || + declare -g optparse_name="$(basename $0)" + } + [[ -z "$optparse_help_full_width" ]] && declare -g optparse_help_full_width=80 + [[ -z "$optparse_default_group" ]] && declare -g optparse_default_group="OPTIONS" + [[ -z "$optparse_usage_header" ]] && declare -g optparse_usage_header="[OPTIONS]" + [[ -z "$optparse_description" ]] && declare -g optparse_description="${optparse_name} Help" optparse.define long=help desc="This Help Screen" dispatch="optparse.usage" behaviour=flag help=explicit optparse.define long=optparse_license desc="The OptParse Library License" dispatch="optparse.license" help=hide } +function optparse.reset(){ + optparse.unset + optparse.init $(printf ' %q' "${@}") +} + +function optparse.unset(){ + unset optparse_version + unset optparse_usage + unset optparse_process + unset optparse_defaults + unset optparse_name + unset optparse_usage_header + unset optparse_variables_validate + unset optparse_default_group +} + # ----------------------------------------------------------------------------------------------------------------------------- function optparse.throw_error(){ local message="$1" @@ -380,6 +396,8 @@ function optparse.define(){ $has_variable && optparse_variables_validate+=" [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true" + + true } # ----------------------------------------------------------------------------------------------------------------------------- @@ -556,7 +574,7 @@ EOF if [ -z "$optparse_preserve" ] ; then # Unset global variables - optparse.init + optparse.unset fi } optparse.init \ No newline at end of file From 84cfe54496c5a6b52885b580d01272ef59c1d837 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 14:03:32 +0000 Subject: [PATCH 06/61] More debugging stuffs Just testing out the capabilities and limitations of pulling from remote. --- scripts/manage.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index 32aa0a4c..5f558dd5 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -10,9 +10,25 @@ SOURCE="${BASH_SOURCE[0]}"; while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" echo "$DIR" -return - -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE="scripts/$LIBRARY"; if [[ ! -f "$SOURCE_FILE" ]]; then echo -e "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}'..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; unset SOURCE_FILE; done; echo -en "${CL}${CL}"; +echo "$(pwd)" +echo "$(printf " '%q'" "${@}")" +eval set -- "$(printf " %q" "${@}")" +echo "$(printf " '%q'" "${@}")" +echo "${@}" +[ -v PS1 ] && return || exit + +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; +for LIBRARY in ${LIBRARIES[*]}; do + SOURCE_FILE="scripts/$LIBRARY"; + if [[ ! -f "$SOURCE_FILE" ]]; then + echo -e "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); + if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi + SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; + fi + echo -en "${CL}Loading '{$LIBRARY}'..."; source "$SOURCE_FILE"; + if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi + unset SOURCE_FILE +done; echo -en "${CL}${CL}"; yes_no=( 'yes' 'no' ) From 38b7b5c7f76d972dee2208bcc808a53bbd540be7 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 14:04:18 +0000 Subject: [PATCH 07/61] I should probably set MY repo for testing... --- scripts/manage.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index 5f558dd5..f83bb8e2 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -REPO="Z-Bolt/OctoScreen" -MAIN="master" +REPO="thebeline/OctoScreen" +MAIN="IMP/Installer" RELEASES="https://api.github.com/repos/$REPO/releases/latest" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("inquirer.bash" "optparse.bash") From 8661fb8606e89d0f147cf10f139630fc53339aeb Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 14:27:56 +0000 Subject: [PATCH 08/61] Remote or Local resolution of Bash dependencies. Allows the user to use locally stored versions of the dependent files, in the event that they are executing the manager locally (from within the Git/Source directory). This will be useful in the future if this script is expanded in any ways where it may be installed locally in /usr/bin for managing the current installation. That said, in that case, we may have to split manager and installer, but, whateves. The research and groundwork is there anyway. --- scripts/manage.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index f83bb8e2..466126f1 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -8,6 +8,7 @@ LIBRARIES=("inquirer.bash" "optparse.bash") SOURCE="${BASH_SOURCE[0]}"; while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" +PWD="$(pwd)" echo "$DIR" echo "$(pwd)" @@ -15,21 +16,24 @@ echo "$(printf " '%q'" "${@}")" eval set -- "$(printf " %q" "${@}")" echo "$(printf " '%q'" "${@}")" echo "${@}" -[ -v PS1 ] && return || exit echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do - SOURCE_FILE="scripts/$LIBRARY"; - if [[ ! -f "$SOURCE_FILE" ]]; then + [[ -f "$DIR/$LIBRARY" ]] && SOURCE_FILE="$DIR/$LIBRARY" || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; } + if [[ -z "$SOURCE_FILE" ]]; then echo -e "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi - echo -en "${CL}Loading '{$LIBRARY}'..."; source "$SOURCE_FILE"; + echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi unset SOURCE_FILE + sleep 1 done; echo -en "${CL}${CL}"; +echo "DONE" +[ -v PS1 ] && return || exit 1 + yes_no=( 'yes' 'no' ) arch=$(uname -m) From 0f293c71e8e38e5646249c688d63e449db25778e Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 16:59:31 +0000 Subject: [PATCH 09/61] Batteling an odd shell behaviour... This is a bit weird, but when sourching inside a source... SHELLOPTS[errexit] gets set while processing the nested source, and never get's unset... Which... I THINK... Is causing me a bit of an issue... The issue: A bit of an edge case, but, if you SOURCE the manager, close it, and then CALL the manager (./scripts/manager.sh) and close that, it straight up kills your terminal. As an added bonus: If you don't kill the CALL, and it exits on it's own, and go to use tab completion... POOF, THAT kills your teminal... Odd indeed... --- scripts/inquirer.bash | 2 +- scripts/manage.sh | 83 +++++++++++++++++++++++++++++-------------- scripts/optparse.bash | 2 +- 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/scripts/inquirer.bash b/scripts/inquirer.bash index 32f7d2ab..ca9380f9 100644 --- a/scripts/inquirer.bash +++ b/scripts/inquirer.bash @@ -664,4 +664,4 @@ text_input() { cleanup } -################## INQUIRER.SH ################## \ No newline at end of file +################## INQUIRER.SH ################## diff --git a/scripts/manage.sh b/scripts/manage.sh index 466126f1..1bd09183 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -6,33 +6,61 @@ RELEASES="https://api.github.com/repos/$REPO/releases/latest" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("inquirer.bash" "optparse.bash") -SOURCE="${BASH_SOURCE[0]}"; while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done -DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" PWD="$(pwd)" +SOURCE="${BASH_SOURCE[0]:-$0}"; + +while [[ -L "$SOURCE" && "$SOURCE" != /dev/fd/* ]]; do + echo "T1 '$SOURCE'" + DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; + echo "T2 '$DIR'" + SOURCE="$(readlink "$SOURCE")"; + echo "T3 '$SOURCE'" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; + echo "T4 '$SOURCE'" +done +echo "OUT '$SOURCE'" +[[ "$SOURCE" != /dev/fd/* ]] && DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" || DIR='' +echo "DONE '$DIR'" echo "$DIR" echo "$(pwd)" -echo "$(printf " '%q'" "${@}")" -eval set -- "$(printf " %q" "${@}")" -echo "$(printf " '%q'" "${@}")" -echo "${@}" +#echo "$(printf " '%q'" "${@}")" +#eval set -- "$(printf " %q" "${@}")" +#echo "$(printf " '%q'" "${@}")" +#echo "${@}" -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL=''; #'\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do - [[ -f "$DIR/$LIBRARY" ]] && SOURCE_FILE="$DIR/$LIBRARY" || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; } + echo "STARTING $LIBRARY: $SHELLOPTS" + SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" && SOURCE_FILE="$DIR/$LIBRARY" ]] || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; } if [[ -z "$SOURCE_FILE" ]]; then echo -e "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); - if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi - SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; + echo "STARTING FETCH: $SHELLOPTS" + if [[ "$?" != "0" ]]; then + echo " ERROR Fetching dependency '$LIBRARY'!"; + #[ -v PS1 ] && return || exit 1; + else echo ' SUCCESS'; fi + echo "MAKING SOURCE: $SHELLOPTS" + SOURCE_FILE=<(echo "$SOURCE"); + echo "MADE SOURCE: $SHELLOPTS" + unset SOURCE; fi - echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; - if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi - unset SOURCE_FILE - sleep 1 + echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; + echo "PRE SOURCE: $SHELLOPTS" + source "$SOURCE_FILE"; + echo "POST SOURCE: $SHELLOPTS" + if [[ "$?" != "0" ]]; then + echo " ERROR Loading dependency '$LIBRARY'!"; + #[ -v PS1 ] && return || exit 1; + else echo ' SUCCESS'; fi + echo "ENDING $LIBRARY: $SHELLOPTS" + set +o errexit done; echo -en "${CL}${CL}"; -echo "DONE" -[ -v PS1 ] && return || exit 1 +echo "DONE: $SHELLOPTS" +#[ -v PS1 ] && return || exit 1 + + yes_no=( 'yes' 'no' ) @@ -50,8 +78,8 @@ IFS='/' read -ra version <<< "$releaseURL" echo "Installing OctoScreen "${version[7]}, $arch"" echo "Installing Dependencies ..." -sudo apt -qq update -sudo apt -qq install $dependencies -y +#sudo apt -qq update +#sudo apt -qq install $dependencies -y if [ -d "/home/pi/OctoPrint/venv" ]; then DIRECTORY="/home/pi/OctoPrint/venv" @@ -100,15 +128,18 @@ fi; echo "Installing OctoScreen "${version[7]}, $arch" ..." cd ~ -wget -O octoscreen.deb $releaseURL -q --show-progress +#wget -O octoscreen.deb $releaseURL -q --show-progress + +#sudo dpkg -i octoscreen.deb + +#rm octoscreen.deb -sudo dpkg -i octoscreen.deb -rm octoscreen.deb +#list_input "Shall I reboot your Pi now?" yes_no reboot +#echo "OctoScreen has been successfully installed! :)" +#if [ $reboot == 'yes' ]; then +# sudo reboot +#fi -list_input "Shall I reboot your Pi now?" yes_no reboot -echo "OctoScreen has been successfully installed! :)" -if [ $reboot == 'yes' ]; then - sudo reboot -fi \ No newline at end of file +echo "FINAL: $SHELLOPTS" diff --git a/scripts/optparse.bash b/scripts/optparse.bash index ea45daee..24c03c7a 100644 --- a/scripts/optparse.bash +++ b/scripts/optparse.bash @@ -577,4 +577,4 @@ EOF optparse.unset fi } -optparse.init \ No newline at end of file +optparse.init From d026d719b67e4359fec4724266110cb05ab25bf2 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 18:48:18 +0000 Subject: [PATCH 10/61] **WELL THAT WAS NEAT** Turns out the issue was two-fold: - Mind your line-endings, kids\! - Nested source calls don't reset the environment correctly when inturupted. This coupled with the fact that traps modify the return state, and unless VERY precisely timed, the source call may or may not ALSO modify the return state (with regards to checking success), AND you can't EXIT a command-line sourced script... Made for some fun times. Sorted. Moving on. --- scripts/manage.sh | 57 ++++------------------------------------------- 1 file changed, 4 insertions(+), 53 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index 1bd09183..ce2fe411 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -5,60 +5,11 @@ MAIN="IMP/Installer" RELEASES="https://api.github.com/repos/$REPO/releases/latest" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("inquirer.bash" "optparse.bash") +PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; -PWD="$(pwd)" -SOURCE="${BASH_SOURCE[0]:-$0}"; - -while [[ -L "$SOURCE" && "$SOURCE" != /dev/fd/* ]]; do - echo "T1 '$SOURCE'" - DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; - echo "T2 '$DIR'" - SOURCE="$(readlink "$SOURCE")"; - echo "T3 '$SOURCE'" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; - echo "T4 '$SOURCE'" -done -echo "OUT '$SOURCE'" -[[ "$SOURCE" != /dev/fd/* ]] && DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" || DIR='' -echo "DONE '$DIR'" - -echo "$DIR" -echo "$(pwd)" -#echo "$(printf " '%q'" "${@}")" -#eval set -- "$(printf " %q" "${@}")" -#echo "$(printf " '%q'" "${@}")" -#echo "${@}" - -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL=''; #'\e[1A\e[K'; -for LIBRARY in ${LIBRARIES[*]}; do - echo "STARTING $LIBRARY: $SHELLOPTS" - SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" && SOURCE_FILE="$DIR/$LIBRARY" ]] || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; } - if [[ -z "$SOURCE_FILE" ]]; then - echo -e "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); - echo "STARTING FETCH: $SHELLOPTS" - if [[ "$?" != "0" ]]; then - echo " ERROR Fetching dependency '$LIBRARY'!"; - #[ -v PS1 ] && return || exit 1; - else echo ' SUCCESS'; fi - echo "MAKING SOURCE: $SHELLOPTS" - SOURCE_FILE=<(echo "$SOURCE"); - echo "MADE SOURCE: $SHELLOPTS" - unset SOURCE; - fi - echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; - echo "PRE SOURCE: $SHELLOPTS" - source "$SOURCE_FILE"; - echo "POST SOURCE: $SHELLOPTS" - if [[ "$?" != "0" ]]; then - echo " ERROR Loading dependency '$LIBRARY'!"; - #[ -v PS1 ] && return || exit 1; - else echo ' SUCCESS'; fi - echo "ENDING $LIBRARY: $SHELLOPTS" - set +o errexit -done; echo -en "${CL}${CL}"; - -echo "DONE: $SHELLOPTS" -#[ -v PS1 ] && return || exit 1 +while [[ -L "$SOURCE" && "$SOURCE" != /dev/fd/* ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; [[ "$SOURCE" != /dev/fd/* ]] && DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" || DIR=''; function __clear_opts(){ set +o errexit; trap - $1; declare -g _ret="1"; }; function __trap_EXIT(){ __clear_opts EXIT; [ -v PS1 ] && return 1 || exit 1; }; function __trap_SIGINT(){ __clear_opts SIGINT; [ -v PS1 ] && return 1 || exit 1; }; + +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL=''; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; declare -g _ret="0"; trap __trap_SIGINT SIGINT; trap __trap_EXIT EXIT; source "$SOURCE_FILE"; [[ ! -z "$?" && -z "$_ret" ]] && _ret="1"; set +o errexit; trap - SIGINT; trap - EXIT; if [[ "$_ret" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; From e927362572fb0f27e587a8a6ffe6e53a288035c7 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 18:51:29 +0000 Subject: [PATCH 11/61] Forgot the ClearLine --- scripts/manage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index ce2fe411..9a9fe52d 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -9,7 +9,7 @@ PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; while [[ -L "$SOURCE" && "$SOURCE" != /dev/fd/* ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; [[ "$SOURCE" != /dev/fd/* ]] && DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" || DIR=''; function __clear_opts(){ set +o errexit; trap - $1; declare -g _ret="1"; }; function __trap_EXIT(){ __clear_opts EXIT; [ -v PS1 ] && return 1 || exit 1; }; function __trap_SIGINT(){ __clear_opts SIGINT; [ -v PS1 ] && return 1 || exit 1; }; -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL=''; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; declare -g _ret="0"; trap __trap_SIGINT SIGINT; trap __trap_EXIT EXIT; source "$SOURCE_FILE"; [[ ! -z "$?" && -z "$_ret" ]] && _ret="1"; set +o errexit; trap - SIGINT; trap - EXIT; if [[ "$_ret" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; declare -g _ret="0"; trap __trap_SIGINT SIGINT; trap __trap_EXIT EXIT; source "$SOURCE_FILE"; [[ ! -z "$?" && -z "$_ret" ]] && _ret="1"; set +o errexit; trap - SIGINT; trap - EXIT; if [[ "$_ret" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; From 87964ed35020e678ecc789e72cbef24585b23d56 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 18:52:06 +0000 Subject: [PATCH 12/61] Getting back to where I was going... --- scripts/manage.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index 9a9fe52d..f12eeed7 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -23,14 +23,17 @@ arch=$(uname -m) if [[ $arch == arm* ]]; then releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) fi + +echo "Installing From: $releaseURL" + dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" IFS='/' read -ra version <<< "$releaseURL" echo "Installing OctoScreen "${version[7]}, $arch"" echo "Installing Dependencies ..." -#sudo apt -qq update -#sudo apt -qq install $dependencies -y +sudo apt -qq update +sudo apt -qq install $dependencies -y if [ -d "/home/pi/OctoPrint/venv" ]; then DIRECTORY="/home/pi/OctoPrint/venv" @@ -78,19 +81,16 @@ fi; #fi; echo "Installing OctoScreen "${version[7]}, $arch" ..." -cd ~ -#wget -O octoscreen.deb $releaseURL -q --show-progress -#sudo dpkg -i octoscreen.deb +wget -O ~/octoscreen.deb $releaseURL -q --show-progress -#rm octoscreen.deb +sudo dpkg -i ~/octoscreen.deb +rm ~/octoscreen.deb -#list_input "Shall I reboot your Pi now?" yes_no reboot -#echo "OctoScreen has been successfully installed! :)" -#if [ $reboot == 'yes' ]; then -# sudo reboot -#fi - -echo "FINAL: $SHELLOPTS" +list_input "Shall I reboot your Pi now?" yes_no reboot +echo "OctoScreen has been successfully installed! :)" +if [ $reboot == 'yes' ]; then + sudo reboot +fi From 1fb8eae519df4a680de0ee8c320b41d4e4cd0739 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 21:43:00 +0000 Subject: [PATCH 13/61] I was an IDIOT... Yeah, so, sourcing at the command line is STUPID... But I learned that you can use the bash command the same way. Nice and clean, AND accepts arguments (which piping doesn't, which is why I was shying away from that option). Well that was an experience... --- scripts/manage.sh | 6 +- scripts/optparse.bash | 151 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 137 insertions(+), 20 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index f12eeed7..5b22f531 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -7,10 +7,10 @@ WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("inquirer.bash" "optparse.bash") PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; -while [[ -L "$SOURCE" && "$SOURCE" != /dev/fd/* ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; [[ "$SOURCE" != /dev/fd/* ]] && DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" || DIR=''; function __clear_opts(){ set +o errexit; trap - $1; declare -g _ret="1"; }; function __trap_EXIT(){ __clear_opts EXIT; [ -v PS1 ] && return 1 || exit 1; }; function __trap_SIGINT(){ __clear_opts SIGINT; [ -v PS1 ] && return 1 || exit 1; }; - -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; declare -g _ret="0"; trap __trap_SIGINT SIGINT; trap __trap_EXIT EXIT; source "$SOURCE_FILE"; [[ ! -z "$?" && -z "$_ret" ]] && _ret="1"; set +o errexit; trap - SIGINT; trap - EXIT; if [[ "$_ret" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; +while [[ "$SOURCE" != /dev/fd/* ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; +DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; yes_no=( 'yes' 'no' ) diff --git a/scripts/optparse.bash b/scripts/optparse.bash index 24c03c7a..87bea0f8 100644 --- a/scripts/optparse.bash +++ b/scripts/optparse.bash @@ -43,6 +43,7 @@ function optparse.init(){ declare -g optparse_shortnames=() declare -g optparse_longnames=() declare -g optparse_variables=() + declare -g optparse_usage_commands="" for option in "$@"; do local key="${option%%=*}"; @@ -100,7 +101,7 @@ function optparse.unset(){ # ----------------------------------------------------------------------------------------------------------------------------- function optparse.throw_error(){ local message="$1" - [ ! -z $2 ] && message+=" for option: ($2)" + [ ! -z $2 ] && message+=": ($2)" optparse._log "ERROR" "$message" exit 1 } @@ -113,7 +114,7 @@ function optparse._log(){ function optparse.warn(){ local message="$1" - [ ! -z $2 ] && message+=" for option: ($2)" + [ ! -z $2 ] && message+=": ($2)" optparse._log "WARN" "$message" } @@ -124,6 +125,120 @@ function optparse.group(){ } # ----------------------------------------------------------------------------------------------------------------------------- +function optparse.command(){ + local name="" + local desc="" + local default="" + local behaviour="default" + local list=false + local variable="" + local dispatch="" + local val="" + local has_val="false" + local has_default="false" + local behaviour_help="default" + local behaviour_extra="" + local optparse_help_indent=15 + local debug="false" + + for option in "$@"; do + local key="${option%%=*}"; + local value="${option#*=}"; + + [[ "$value" == "$key" ]] && value='' + + case "$key" in + "desc"|"description") + desc="$value" + ;; + "name") + name="$value" + ;; + "value") + val="$value" + ;; + "dispatch") + dispatch="$value" + ;; + "help") + case $value in + default|explicit|hide) + declare behaviour_$key="$value" + ;; + *) + optparse.throw_error "$key [$value] not supported" "$name" + ;; + esac + ;; + esac + done + + has_val=$([[ -z "$val" ]] && echo "false" || echo "true") + + [ -z "$name" ] && optparse.throw_error "name is mandatory"; + [ -z "$desc" ] && optparse.throw_error "description is mandatory" "$name"; + [ -z "$dispatch" ] && optparse.throw_error "a dispatcher is mandatory for commands" "$name"; + + #[ -z "$optparse_usage" ] && optparse.group "$optparse_default_group" + + + [ "$behaviour_help" != "hide" ] && { + + [ -z "$optparse_usage_commands" ] && optparse_usage_commands="echo \"Commands\"#NL" + + local _optparse_usage="" + + # build OPTIONS and help + + local description=() + local description_index=0 + local description_word="" + local description_sep="" + local description_char_index=0 + + # Break to lines + + #for (( description_char_index=0; description_char_index<${#desc}; description_char_index++ )); do + # #echo "${foo:$i:1}" + # : + #done + + #_optparse_usage+="cat >&2 << EOU" + _optparse_usage+="#TB$(printf "%-${optparse_help_indent}s %s" " ${name}" "${desc}")" + # -h, --help T + + _optparse_usage="cat >&2 << EOU#NL$_optparse_usage#NLEOU#NL" + + [ "$behaviour_help" == "explicit" ] && + _optparse_usage="if [[ \$1 == "true" ]]; then#NL$_optparse_usage#NLfi#NL" + + optparse_usage_commands+="$_optparse_usage" + + #echo "$_optparse_usage" + } + + + + + + + [ ! -z "$dispatch" ] && { + [ -z "$dispatch_var" ] && { + $has_val && dispatch_var="\"${val}\"" || dispatch_var="\"\$@\"" + } + dispatch_caller="${dispatch} ${dispatch_var}" + } + + optparse_additional_handlers+=" + ${name}) + ${dispatch} ${dispatch_var} + optparse_command_hit=\"true\" + break + ;;" + + true +} + function optparse.define(){ local errorname="" local short="" @@ -142,7 +257,6 @@ function optparse.define(){ local behaviour_help="default" local behaviour_extra="" local optparse_help_indent=15 - local debug="false" for option in "$@"; do local key="${option%%=*}"; @@ -150,33 +264,33 @@ function optparse.define(){ case "$key" in "short") - [ -z errorname ] && - errorname="$value" [ ${#value} -ne 1 ] && - optparse.throw_error "short name expected to be one character long" "$errorname" + optparse.throw_error "short name expected to be one character long" "$value" for i in "${optparse_shortnames[@]}"; do if [ "$i" == "$value" ] ; then - optparse.warn "shortname [-$value] already handled" "$errorname" + optparse.warn "shortname [-$value] already handled" "-$value" fi done optparse_shortnames+=("$value") shortname="$value" short="-$value" + [ -z errorname ] && + errorname="-$short" ;; "long") [ -z ${value} ] && - optparse.throw_error "long name expected to be atleast one character long" "$error_name" + optparse.throw_error "long name expected to be atleast one character long" "--$value" for i in "${optparse_longnames[@]}"; do if [ "$i" == "$value" ] ; then - optparse.warn "longname [--$value] already handled" "$errorname" + optparse.warn "longname [--$value] already handled" "--$value" fi done optparse_longnames+=("$value") longname="$value" - errorname="$value" long="--$value" + errorname="$long" ;; - "desc") + "desc"|"description") desc="$value" ;; "default") @@ -416,10 +530,10 @@ function optparse.build(){ for option in "$@"; do local key="${option%%=*}"; local value="${option#*=}"; - + case "$key" in - "version") - optparse_version="$value" + "name"|"description"|"usage_header"|"usage") + declare -g optparse_$key="$value" ;; "allow") value=( $value ) @@ -437,8 +551,8 @@ function optparse.build(){ esac done ;; - "debug") - optparse_debug=true + "exec") + optparse_variables_validate+="#NL$value;" ;; esac done @@ -488,6 +602,7 @@ ${optparse_description} Usage: $optparse_name $optparse_usage_header EOH +$optparse_usage_commands $optparse_usage cat >&2 << EOH @@ -506,6 +621,8 @@ $optparse_defaults optparse_processing_args=() +optparse_command_hit="false" + # Begin Parseing while [ \$# -ne 0 ]; do optparse_processing_arg="\$1" @@ -554,7 +671,7 @@ while [ \$# -ne 0 ]; do ;; - $default_handler + $optparse_additional_handlers esac From 2cb159d06d7f45a4cc3b9e22071c7359c5477912 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Tue, 9 Mar 2021 21:44:08 +0000 Subject: [PATCH 14/61] Kay, getting read to actually work on the install script... --- scripts/manage.sh | 167 ++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 79 deletions(-) diff --git a/scripts/manage.sh b/scripts/manage.sh index 5b22f531..7275a0d0 100755 --- a/scripts/manage.sh +++ b/scripts/manage.sh @@ -12,85 +12,94 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; +optparse.command name="install" description="Install OctoScreen" dispatch="octoscreen.install" +optparse.command name="*" description="Unknown Command" dispatch="echo \"Unknown Command\"" help=hide yes_no=( 'yes' 'no' ) -arch=$(uname -m) -#if [[ $arch == x86_64 ]]; then -# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*amd64.deb" | cut -d '"' -f 4) -#elif [[ $arch == aarch64 ]]; then -# releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*arm64.deb" | cut -d '"' -f 4) -if [[ $arch == arm* ]]; then - releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) -fi - -echo "Installing From: $releaseURL" - -dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" -IFS='/' read -ra version <<< "$releaseURL" - -echo "Installing OctoScreen "${version[7]}, $arch"" - -echo "Installing Dependencies ..." -sudo apt -qq update -sudo apt -qq install $dependencies -y - -if [ -d "/home/pi/OctoPrint/venv" ]; then - DIRECTORY="/home/pi/OctoPrint/venv" -elif [ -d "/home/pi/oprint" ]; then - DIRECTORY="/home/pi/oprint" -else - echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." - echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." - text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY -fi; - -if [ $DIRECTORY == "-" ]; then - echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." -elif [ ! -d $DIRECTORY ]; then - echo "Can't find OctoPrint Installation, please run the script again!" - exit 1 -fi; - -#if [ $DIRECTORY != "-" ]; then -# plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) -# checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins -# echo "Installing Plugins..." -# -# if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" -# fi; -# if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then -# "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" -# fi; -#fi; - -echo "Installing OctoScreen "${version[7]}, $arch" ..." - -wget -O ~/octoscreen.deb $releaseURL -q --show-progress - -sudo dpkg -i ~/octoscreen.deb - -rm ~/octoscreen.deb - - -list_input "Shall I reboot your Pi now?" yes_no reboot -echo "OctoScreen has been successfully installed! :)" -if [ $reboot == 'yes' ]; then - sudo reboot -fi +function octoscreen.install() { + + arch=$(uname -m) + #if [[ $arch == x86_64 ]]; then + # releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*amd64.deb" | cut -d '"' -f 4) + #elif [[ $arch == aarch64 ]]; then + # releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*arm64.deb" | cut -d '"' -f 4) + if [[ $arch == arm* ]]; then + releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) + fi + + echo "Installing From: $releaseURL" + + dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" + IFS='/' read -ra version <<< "$releaseURL" + + echo "Installing OctoScreen "${version[7]}, $arch"" + + echo "Installing Dependencies ..." + sudo apt -qq update + sudo apt -qq install $dependencies -y + + if [ -d "/home/pi/OctoPrint/venv" ]; then + DIRECTORY="/home/pi/OctoPrint/venv" + elif [ -d "/home/pi/oprint" ]; then + DIRECTORY="/home/pi/oprint" + else + echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." + echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." + text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY + fi; + + if [ $DIRECTORY == "-" ]; then + echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." + elif [ ! -d $DIRECTORY ]; then + echo "Can't find OctoPrint Installation, please run the script again!" + exit 1 + fi; + + #if [ $DIRECTORY != "-" ]; then + # plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) + # checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins + # echo "Installing Plugins..." + # + # if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" + # fi; + #fi; + + echo "Installing OctoScreen "${version[7]}, $arch" ..." + + wget -O ~/octoscreen.deb $releaseURL -q --show-progress + + sudo dpkg -i ~/octoscreen.deb + + rm ~/octoscreen.deb + + list_input "Shall I reboot your Pi now?" yes_no reboot + echo "OctoScreen has been successfully installed! :)" + if [ $reboot == 'yes' ]; then + sudo reboot + fi + + echo "HAY LO" + +} + +. <( optparse.build name=octoscreen description="OctoScreen Manager" allow=positional exec=optparse.usage) From de68b94d5523cbbbd8c975eaeb274a65c5bba20c Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 15:30:10 +0000 Subject: [PATCH 15/61] OctoScreen Support Script You didn't ask for it, but you got it: - This is the groundwork for a pretty comprehensive commandline manager for OctoScreen. - Supports... Well... Anything, in a pretty robust manner. Right now it really only handles 'install', but I have some boilerplate in there to handle building, as well as LCD configuration. Adding Config File manipulation and other tasks would be fairly trivial too. Hmmmmm... *leans back* yup, cool... --- scripts/{ => lib}/inquirer.bash | 0 scripts/{ => lib}/optparse.bash | 278 ++++++++++---------- scripts/lib/verbosity.bash | 112 ++++++++ scripts/manage.sh | 105 -------- scripts/octoscreen | 451 ++++++++++++++++++++++++++++++++ 5 files changed, 695 insertions(+), 251 deletions(-) rename scripts/{ => lib}/inquirer.bash (100%) rename scripts/{ => lib}/optparse.bash (69%) create mode 100644 scripts/lib/verbosity.bash delete mode 100755 scripts/manage.sh create mode 100755 scripts/octoscreen diff --git a/scripts/inquirer.bash b/scripts/lib/inquirer.bash similarity index 100% rename from scripts/inquirer.bash rename to scripts/lib/inquirer.bash diff --git a/scripts/optparse.bash b/scripts/lib/optparse.bash similarity index 69% rename from scripts/optparse.bash rename to scripts/lib/optparse.bash index 87bea0f8..cdb5cac0 100644 --- a/scripts/optparse.bash +++ b/scripts/lib/optparse.bash @@ -101,7 +101,7 @@ function optparse.unset(){ # ----------------------------------------------------------------------------------------------------------------------------- function optparse.throw_error(){ local message="$1" - [ ! -z $2 ] && message+=": ($2)" + [[ ! -z $2 ]] && message+=": ($2)" optparse._log "ERROR" "$message" exit 1 } @@ -114,18 +114,18 @@ function optparse._log(){ function optparse.warn(){ local message="$1" - [ ! -z $2 ] && message+=": ($2)" + [[ ! -z "$2" ]] && message+=": ($2)" optparse._log "WARN" "$message" } function optparse.group(){ local group="$1" - [ ! -z "$group" ] && [ ! -z "$optparse_usage" ] && group="#NL$group" - optparse_usage+="echo \"$group\";#NL" + [[ ! -z "$group" && ! -z "$optparse_usage" ]] && group="#NL$group" + optparse_usage+="cat >&2 << EOU#NL$group#NLEOU#NL" } # ----------------------------------------------------------------------------------------------------------------------------- -function optparse.command(){ +function optparse.define.single(){ local name="" local desc="" local default="" @@ -175,16 +175,16 @@ function optparse.command(){ has_val=$([[ -z "$val" ]] && echo "false" || echo "true") - [ -z "$name" ] && optparse.throw_error "name is mandatory"; - [ -z "$desc" ] && optparse.throw_error "description is mandatory" "$name"; - [ -z "$dispatch" ] && optparse.throw_error "a dispatcher is mandatory for commands" "$name"; + [[ -z "$name" ]] && optparse.throw_error "name is mandatory"; + [[ -z "$desc" && "$behaviour_help" != "hide" ]] && optparse.throw_error "description is mandatory" "$name"; + [[ -z "$dispatch" ]] && optparse.throw_error "a dispatcher is mandatory for commands" "$name"; #[ -z "$optparse_usage" ] && optparse.group "$optparse_default_group" - [ "$behaviour_help" != "hide" ] && { + [[ "$behaviour_help" != "hide" ]] && { - [ -z "$optparse_usage_commands" ] && optparse_usage_commands="echo \"Commands\"#NL" + [[ -z "$optparse_usage_commands" ]] && optparse_usage_commands="cat >&2 << EOU#NLCommands#NLEOU#NL" local _optparse_usage="" @@ -217,23 +217,9 @@ function optparse.command(){ #echo "$_optparse_usage" } - - - - - - [ ! -z "$dispatch" ] && { - [ -z "$dispatch_var" ] && { - $has_val && dispatch_var="\"${val}\"" || dispatch_var="\"\$@\"" - } - dispatch_caller="${dispatch} ${dispatch_var}" - } - optparse_additional_handlers+=" ${name}) - ${dispatch} ${dispatch_var} - optparse_command_hit=\"true\" - break + ${dispatch} ; true; ;;" true @@ -257,6 +243,8 @@ function optparse.define(){ local behaviour_help="default" local behaviour_extra="" local optparse_help_indent=15 + local optional="false" + local has_variable="false" for option in "$@"; do local key="${option%%=*}"; @@ -264,26 +252,24 @@ function optparse.define(){ case "$key" in "short") - [ ${#value} -ne 1 ] && + [[ ${#value} -ne 1 ]] && optparse.throw_error "short name expected to be one character long" "$value" for i in "${optparse_shortnames[@]}"; do - if [ "$i" == "$value" ] ; then - optparse.warn "shortname [-$value] already handled" "-$value" - fi + [[ "$i" == "$value" ]] && + optparse.warn "shortname [-$value] already handled" "-$value" && break; done optparse_shortnames+=("$value") shortname="$value" short="-$value" - [ -z errorname ] && - errorname="-$short" + [[ -z "$errorname" ]] && + errorname="$short" ;; "long") - [ -z ${value} ] && + [[ -z ${value} ]] && optparse.throw_error "long name expected to be atleast one character long" "--$value" for i in "${optparse_longnames[@]}"; do - if [ "$i" == "$value" ] ; then - optparse.warn "longname [--$value] already handled" "--$value" - fi + [[ "$i" == "$value" ]] && + optparse.warn "longname [--$value] already handled" "--$value" && break; done optparse_longnames+=("$value") longname="$value" @@ -297,6 +283,12 @@ function optparse.define(){ default="$value" has_default="true" ;; + "optional") + optional="true" + ;; + flag|list) + behaviour="$key" + ;; "behaviour") case $value in default|list|flag) @@ -313,9 +305,8 @@ function optparse.define(){ "variable") variable="$value" for i in "${optparse_variables[@]}"; do - if [ "$i" == "$value" ] ; then - optparse.warn "value assignment [\$$value] already handled" "$errorname" - fi + [[ "$i" == "$value" ]] && + optparse.warn "value assignment [\$$value] already handled" "$errorname" && break; done optparse_variables+=("$value") ;; @@ -325,16 +316,13 @@ function optparse.define(){ "dispatch") dispatch="$value" ;; - "explicit_help") - always_help=false - ;; - "debug") - debug=true - ;; - "extra"|"help") + "extra"|"help"|"hide"|"explicit") case $value in default|explicit|hide) - declare behaviour_$key="$value" + [[ "$value" == "$key" ]] && { + declare behaviour_help="$value"; + declare behaviour_extra="$value"; + } || declare behaviour_$key="$value"; ;; *) optparse.throw_error "$key [$value] not supported" "$errorname" @@ -344,27 +332,27 @@ function optparse.define(){ esac done - [ -z $behaviour_extra ] && { - [ "$behaviour" == "flag" ] && behaviour_extra="hide" || behaviour_extra="explicit" + [[ -z $behaviour_extra ]] && { + [[ "$behaviour" == "flag" ]] && behaviour_extra="hide" || behaviour_extra="explicit" } - [ -z "$errorname" ] && optparse.throw_error "argument must have a long or short name" + [[ -z "$errorname" ]] && optparse.throw_error "argument must have a long or short name" flag=$([[ $behaviour == "flag" ]] && echo "true" || echo "false") is_list=$([[ $behaviour == "list" ]] && echo "true" || echo "false") - [ $behaviour == "flag" ] && { - [ -z $default ] && default=false + [[ $behaviour == "flag" ]] && { + [[ -z $default ]] && default=false has_default=true - [ $default = "true" ] && val="false" - [ $default = "false" ] && val="true" + [[ $default == "true" ]] && val="false" + [[ $default == "false" ]] && val="true" } has_val=$([[ -z "$val" ]] && echo "false" || echo "true") has_variable=$([[ -z "$variable" ]] && echo "false" || echo "true") # check list behaviour - [ $behaviour == "list" ] && { + [[ $behaviour == "list" ]] && { [[ -z ${list:-} ]] && optparse.throw_error "list is mandatory when using list behaviour" "$errorname" @@ -378,22 +366,21 @@ function optparse.define(){ } } - if [ -z "$desc" ]; then - if [ -z "$dispatch" ]; then + [[ -z "$desc" && "$behaviour_help" != "hide" ]] && { + [[ -z "$dispatch" ]] && { optparse.throw_error "description is mandatory" "$errorname" - else - [ "$behaviour_help" == "default" ] && help_behaviour="explicit" - [ "$behaviour_help" != "hide" ] && desc="Executes $dispatch" - fi - fi + } || { + [[ "$behaviour_help" == "default" ]] && help_behaviour="explicit" + [[ "$behaviour_help" != "hide" ]] && desc="Executes $dispatch" + } + } - [ -z "$variable" ] && [ -z "$dispatch" ] && optparse.throw_error "you must give a target variable" "$errorname" + [[ -z "$variable" && -z "$dispatch" ]] && optparse.throw_error "you must give a target variable" "$errorname"; - [ -z "$optparse_usage" ] && optparse.group "$optparse_default_group" - - - [ "$behaviour_help" != "hide" ] && { + [[ "$behaviour_help" != "hide" ]] && { + + [[ -z "$optparse_usage" ]] && optparse.group "$optparse_default_group"; local _optparse_usage="" @@ -418,7 +405,7 @@ function optparse.define(){ _optparse_usage="cat >&2 << EOU#NL$_optparse_usage#NLEOU#NL" - [ "$behaviour_extra" != "hide" ] && { + [[ "$behaviour_extra" != "hide" ]] && { local _optparse_extra="" @@ -427,22 +414,22 @@ function optparse.define(){ $flag && { _optparse_extra+="#TB#TB#TBTreated as a Flag#NL" } || { - ${has_default} && + $has_default && _optparse_extra+="#TB#TB#TBDefault: '$default'#NL" } - [ ! -z "$_optparse_extra" ] && { + [[ ! -z "$_optparse_extra" ]] && { _optparse_extra="cat >&2 << EOE#NL${_optparse_extra}EOE#NL" - [ "$behaviour_extra" == "explicit" ] && + [[ "$behaviour_extra" == "explicit" ]] && _optparse_extra="if [[ \$1 == "true" ]]; then#NL$_optparse_extra#NLfi#NL" _optparse_usage+="$_optparse_extra" } } - [ "$behaviour_help" == "explicit" ] && + [[ "$behaviour_help" == "explicit" ]] && _optparse_usage="if [[ \$1 == "true" ]]; then#NL$_optparse_usage#NLfi#NL" optparse_usage+="$_optparse_usage" @@ -450,58 +437,56 @@ function optparse.define(){ #echo "$_optparse_usage" } - $has_default && [ ! -z "$variable" ] && - optparse_defaults+="#NL${variable}='${default}'" + [[ $has_default && ! -z "$variable" ]] && + optparse_defaults+="#NL[[ -z ${variable} ]] && ${variable}='${default}'" local validate_variable="$is_list && { valid=false for i in $list; do - [[ \$optparse_processing_arg_value == \$i ]] && valid=true && break + [[ \$__arg_value == \$i ]] && valid=true && break done - \$valid || optparse.usage false \"ERROR: invalid value for argument \\\"\$_optparse_arg_errorname\\\"\" 1 + \$valid || optparse.usage false \"ERROR: invalid value for argument \\\"\$__arg_errorname\\\"\" 1 } - $has_variable && [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage false \"ERROR: (\$_optparse_arg_errorname) requires input value\" 1" + $has_variable && [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage false \"ERROR: (\$__arg_errorname) requires input value\" 1 || true" local dispatch_caller="# No Dispatcher" - [ ! -z "$dispatch" ] && { - [ -z "$dispatch_var" ] && { - $has_variable && dispatch_var="\"\$${variable}\"" || dispatch_var="\"\$optparse_processing_arg_value\"" + [[ ! -z "$dispatch" ]] && { + [[ -z "$dispatch_var" ]] && { + $has_variable && dispatch_var="\"\$${variable}\"" || dispatch_var="\"\$__arg_value\"" } - dispatch_caller="${dispatch} ${dispatch_var}" + dispatch_caller="${dispatch} ${dispatch_var}; true;" } - [ ! -z "$shortname" ] && { + [[ ! -z "$shortname" ]] && { optparse_process_short+=" ${shortname}) - _optparse_arg_errorname=\"$short\" - optparse_processing_arg_value=\"\" - ( $flag || $has_val ) && optparse_processing_arg_value=\"$val\" || { - $has_variable && { - optparse_processing_arg_value=\"\$optparse_processing_arg\"; - if [ -z \"\$optparse_processing_arg_value\" ]; then - optparse_processing_arg_value=\"\$1\" && shift - else - optparse_processing_arg='' - fi - } + __arg_errorname=\"$short\"; + __arg_value=''; + ( $flag || $has_val ) && { + __arg_value=\"$val\"; } - $has_variable && ${variable}=\"\$optparse_processing_arg_value\" + $has_variable && [[ -z \"\$__arg_value\" ]] && { + __arg_value=\"\$__arg_sremain\"; + __arg_sremain=''; + [[ -z \"\$__arg_value\" && ! -z \"\$1\" ]] && __arg_value=\"\$1\" && shift; + } + $has_variable && ${variable}=\"\$__arg_value\"; $validate_variable $dispatch_caller continue ;;" } - [ ! -z "$longname" ] && { + [[ ! -z "$longname" ]] && { optparse_process_long+=" ${longname}) - _optparse_arg_errorname=\"$long\" + __arg_errorname=\"$long\"; $has_val && { - [ ! -z \"\$optparse_processing_arg_value\" ] && optparse.usage true 'ERROR: (${errorname}) does not accept user input' 1 - optparse_processing_arg_value=\"$val\" + [[ ! -z \"\$__arg_value\" ]] && optparse.usage true 'ERROR: (${errorname}) does not accept user input' 1; + __arg_value=\"$val\"; } - $has_variable && ${variable}=\"\$optparse_processing_arg_value\" + $has_variable && ${variable}=\"\$__arg_value\"; $validate_variable $dispatch_caller continue @@ -509,7 +494,7 @@ function optparse.define(){ } $has_variable && optparse_variables_validate+=" - [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true" + $optional || { [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true; };" true } @@ -526,6 +511,8 @@ function optparse.build(){ local _optparse_process=$optparse_process local _optparse_variables_validate=$optparse_variables_validate + + local _exec='' for option in "$@"; do local key="${option%%=*}"; @@ -545,45 +532,40 @@ function optparse.build(){ "unrecognized") allow_unrecognized=true ;; - *) - optparse.throw_error "Unhandled Allowance '$allow'" - ;; esac done ;; - "exec") - optparse_variables_validate+="#NL$value;" + "finally") + _exec="#NL$value;" ;; esac done + local _has_additional=$([[ -z "$optparse_additional_handlers" ]] && echo "false" || echo "true") + + $_has_additional && preserve_positional=true + $preserve_positional && { preserve_positional=" - [ ! -z \"\$optparse_processing_arg\" ] && { - $optparse_debug && echo \"Passing positional arg to args \\\"\$optparse_processing_arg\\\"\" - optparse_processing_args+=( \"\$optparse_processing_arg\" ) - }" + [ ! -z \"\$__arg\" ] && __args_processed+=( \"\$__arg\" )" } || { preserve_positional="optparse.usage true \"ERROR: Unconfigured Arguments are not accepted.\" 1" } $allow_unrecognized && { unknown_long_handler=" - $optparse_debug && echo \"Passing unknown long to args \$optparse_processing_arg\" - optparse_processing_args+=( \"\$optparse_processing_arg\" ) + __args_processed+=( \"\$__arg\" ) continue" unknown_short_handler=" - $optparse_debug && echo \"Passing unknown short '\$optparse_processing_arg_key' to args \$optparse_processing_arg\" - optparse_processing_arg+=\"\$optparse_processing_arg_key\" + __arg_processed+=\"\$__arg_key\" continue" non_empty_shorts=" - [ ! -z \"\$optparse_processing_arg\" ] && { - $optparse_debug && echo \"Passing non-empty shorts '-\$optparse_processing_arg' to args \$optparse_processing_arg\" - optparse_processing_args+=(\"-\$optparse_processing_arg\") + [ ! -z \"\$__arg_short_processed\" ] && { + __args_processed+=(\"-\$__arg_processed\") continue }" } || { - unknown_long_handler="optparse.usage true \"Unrecognized option: \$optparse_processing_arg_key\" 1" + unknown_long_handler="optparse.usage true \"Unrecognized option: \$__arg_key\" 1" unknown_short_handler="$unknown_long_handler" } @@ -596,7 +578,7 @@ exit 0 } function optparse.usage(){ -( [ "\$1" == "true" ] && [ ! -z "\$2" ]) && echo -e "\$2" +[[ ! -z "\$2" ]] && echo -e "\$2" cat >&2 << EOH ${optparse_description} Usage: $optparse_name $optparse_usage_header @@ -609,38 +591,37 @@ cat >&2 << EOH \$(printf "%${optparse_help_full_width}s %s" "Powered by optparse $optparse_version") \$(printf "%${optparse_help_full_width}s %s" "@see --optparse_license") EOH -if [ "\$1" == "true" ] && [ ! -z "\$3" ]; then - exit "\$3" -else - exit 3 -fi +[[ "\$1" == "true" && ! -z "\$3" ]] && exit "\$3" || exit 3 } # Set default variable values $optparse_defaults -optparse_processing_args=() +__args_processed=() optparse_command_hit="false" # Begin Parseing -while [ \$# -ne 0 ]; do - optparse_processing_arg="\$1" +while [[ \$# -ne 0 ]]; do + __arg_key='' + __arg_value='' + __arg_short='' + __arg="\$1" shift - case "\$optparse_processing_arg" in + case "\$__arg" in --) - optparse_processing_args+=("--") && break + __args_processed+=("--") && break ;; --*) - optparse_processing_arg_key="\${optparse_processing_arg%%=*}"; - optparse_processing_arg_value="\${optparse_processing_arg#*=}"; + __arg_key="\${__arg%%=*}"; + __arg_value="\${__arg#*=}"; - [ "\$optparse_processing_arg_value" == "\$optparse_processing_arg_key" ] && optparse_processing_arg_value='' + [[ "\$__arg_value" == "\$__arg_key" ]] && __arg_value='' - case "\${optparse_processing_arg_key:2}" in + case "\${__arg_key:2}" in $optparse_process_long esac @@ -650,16 +631,16 @@ while [ \$# -ne 0 ]; do -*) - optparse_processing_arg_short="\${optparse_processing_arg:1}" - optparse_processing_arg='' + __arg_sremain="\${__arg:1}" + __arg_processed='' - while [ \${#optparse_processing_arg_short} -ne 0 ]; do + while [[ \${#__arg_sremain} -ne 0 ]]; do - optparse_processing_arg_key="\${optparse_processing_arg_short:0:1}"; - optparse_processing_arg_short="\${optparse_processing_arg_short:1}" - optparse_processing_arg_value=''; + __arg_key="\${__arg_sremain:0:1}"; + __arg_sremain="\${__arg_sremain:1}" + __arg_value=''; - case "\$optparse_processing_arg_key" in + case "\$__arg_key" in $optparse_process_short esac @@ -670,7 +651,7 @@ while [ \$# -ne 0 ]; do $non_empty_shorts ;; - + $optparse_additional_handlers esac @@ -679,19 +660,24 @@ while [ \$# -ne 0 ]; do done -# GODLY arg quote with printf, WHERE HAVE YOU BEEN?? -eval set -- "\$([ ! -z "$optparse_processing_args" ] && printf ' %q' "\${optparse_processing_args[@]}") \$(printf ' %q' "\${@}")" +# GODLY arg quote with printf, WHERE HAVE YOU BEEN MY WHOLE LIFE?? +[[ ! -z "\$__args_processed" ]] && { + __args_processed="\$(printf '%q ' "\${__args_processed[@]}")" + [[ ! -z "\$@" ]] && __args_processed+="\$(printf '%q ' "\${@}")" + eval set -- "\$__args_processed" +} $optparse_variables_validate unset _optparse_params unset _optparse_param +$_exec + EOF - if [ -z "$optparse_preserve" ] ; then - # Unset global variables - optparse.unset - fi + # Unset global variables + [[ -z "$optparse_preserve" ]] && optparse.unset } -optparse.init + +optparse.init && true diff --git a/scripts/lib/verbosity.bash b/scripts/lib/verbosity.bash new file mode 100644 index 00000000..adbddb12 --- /dev/null +++ b/scripts/lib/verbosity.bash @@ -0,0 +1,112 @@ +#!/user/bib/env bash + +VERBOSITY_CURRENT=0 +VERBOSITY_FATAL=-3 +VERBOSITY_ERROR=-2 +VERBOSITY_QUIET=-1 +VERBOSITY_ECHO=0 +VERBOSITY_WARN=0 +VERBOSITY_NOTICE=1 +VERBOSITY_INFO=2 +VERBOSITY_DEBUG=3 +VERBOSITY_HELL=6 + +VERBOSITY_ERROR_FORMAT='\e[100\e[91m%s%s\e[0m: %s' +VERBOSITY_FATAL_FORMAT='\e[41m%s%s\e[0m: %s' +VERBOSITY_QUIET_FORMAT='\e[94m%s%s\e[0m: %s' +VERBOSITY_WARN_FORMAT='\e[91m%s%s\e[0m: %s' +VERBOSITY_NOTICE_FORMAT='\e[93m%s%s\e[0m: %s' +VERBOSITY_INFO_FORMAT='\e[96m%s%s\e[0m: %s' +VERBOSITY_DEBUG_FORMAT='\e[94m%s%s\e[0m: %s' +VERBOSITY_HELL_FORMAT='\e[102m\e[95m\e[5m\e[30m\e[2m' + +function echo.verbosity.init_optparse() { + VERBOSITY_CURRENT=0 + + declare -F 'optparse.define' > /dev/null + + [[ $? -eq 0 ]] && { + optparse.define short=v description="Verbosity" dispatch="echo.verbosity.raise" + optparse.define short=q description="Quiet Mode" dispatch="echo.verbosity.quiet" + } || { + echo.warn "OptParse is not available, can not initialize verbosity handlers." + optparse.throw_error "um... but I am..." + } +} + +function echo.verbosity.raise(){ + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_HELL ]] && { echo.fatal "OK, THAT'S ENOUGH. I'M OUT"; } && return; + [[ $VERBOSITY_CURRENT -lt 0 ]] && VERBOSITY_CURRENT="0" + (( ++VERBOSITY_CURRENT )) + [[ $VERBOSITY_CURRENT -eq $VERBOSITY_HELL ]] && { + VERBOSITY_ERROR_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_ERROR_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_FATAL_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_FATAL_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_QUIET_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_QUIET_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_WARN_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_WARN_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_NOTICE_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_NOTICE_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_INFO_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_INFO_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_DEBUG_FORMAT="$VERBOSITY_HELL_FORMAT$( echo $VERBOSITY_DEBUG_FORMAT | sed -e 's/\\e\[0m//g' )" + VERBOSITY_PREFIX="HELL MODE $VERBOSITY_PREFIX"; + echo.warn "Oh, right, hell mode... SURPRISE...\n\tYou brought this on yourself...\n\tTHERE IS NO RETURN... THIS IS YOUR LIFE NOW..."; + } && return; + [[ $VERBOSITY_CURRENT -gt $VERBOSITY_DEBUG ]] && echo.notice "We can't really get more verbose than this, sorry..." && return; + [[ $VERBOSITY_CURRENT -eq $VERBOSITY_DEBUG ]] && echo.debug "You have entered DEBUG levels of verbosity... God Speed..." && return; + true +} + +function echo.verbosity.quiet(){ + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_HELL ]] && echo.warn "I WON'T QUIET DOWN." && return; + VERBOSITY_CURRENT=$VERBOSITY_QUIET + #echo.quiet "We don't really support QUIET mode, but we'll try, just for you." +} + +function echo(){ + local urgency=0 + [[ ! -z "$__VERBOSITY_URGENCY" ]] && urgency="$__VERBOSITY_URGENCY" + unset __VERBOSITY_URGENCY + [[ $VERBOSITY_CURRENT -lt $urgency ]] && return + builtin echo "$@" + [[ $urgency -le $VERBOSITY_FATAL ]] && { exit 1; } || true +} + +function echo.quiet(){ + __VERBOSITY_URGENCY=$VERBOSITY_QUIET + printf -v message "$VERBOSITY_QUIET_FORMAT\e[0m" "$VERBOSITY_PREFIX" "WHISPER" "$1" + echo -e "$message" +} + +function echo.error(){ + __VERBOSITY_URGENCY=$VERBOSITY_ERROR + printf -v message "$VERBOSITY_ERROR_FORMAT\e[0m" "$VERBOSITY_PREFIX" "ERROR" "$1" + >&2 echo -e "$message" +} + +function echo.fatal(){ + __VERBOSITY_URGENCY=$VERBOSITY_FATAL + printf -v message "$VERBOSITY_FATAL_FORMAT\e[0m" "$VERBOSITY_PREFIX" "FATAL" "$1" + >&2 echo -e "$message" +} + +function echo.warn(){ + __VERBOSITY_URGENCY=$VERBOSITY_WARN + printf -v message "$VERBOSITY_WARN_FORMAT\e[0m" "$VERBOSITY_PREFIX" "WARN" "$1" + echo -e "$message" +} + +function echo.notice(){ + __VERBOSITY_URGENCY=$VERBOSITY_NOTICE + printf -v message "$VERBOSITY_NOTICE_FORMAT\e[0m" "$VERBOSITY_PREFIX" "NOTICE" "$1" + echo -e "$message" +} + +function echo.info(){ + __VERBOSITY_URGENCY=$VERBOSITY_INFO + printf -v message "$VERBOSITY_INFO_FORMAT\e[0m" "$VERBOSITY_PREFIX" "INFO" "$1" + echo -e "$message" +} + +function echo.debug(){ + __VERBOSITY_URGENCY=$VERBOSITY_DEBUG + printf -v message "$VERBOSITY_DEBUG_FORMAT\e[0m" "$VERBOSITY_PREFIX" "DEBUG" "$1" + echo -e "$message" +} \ No newline at end of file diff --git a/scripts/manage.sh b/scripts/manage.sh deleted file mode 100755 index 7275a0d0..00000000 --- a/scripts/manage.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env bash - -REPO="thebeline/OctoScreen" -MAIN="IMP/Installer" -RELEASES="https://api.github.com/repos/$REPO/releases/latest" -WGET_RAW="https://github.com/$REPO/raw/$MAIN" -LIBRARIES=("inquirer.bash" "optparse.bash") -PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; - -while [[ "$SOURCE" != /dev/fd/* ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; -DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; - -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; - -optparse.command name="install" description="Install OctoScreen" dispatch="octoscreen.install" -optparse.command name="*" description="Unknown Command" dispatch="echo \"Unknown Command\"" help=hide - -yes_no=( 'yes' 'no' ) - -function octoscreen.install() { - - arch=$(uname -m) - #if [[ $arch == x86_64 ]]; then - # releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*amd64.deb" | cut -d '"' -f 4) - #elif [[ $arch == aarch64 ]]; then - # releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*arm64.deb" | cut -d '"' -f 4) - if [[ $arch == arm* ]]; then - releaseURL=$(curl -s "$RELEASES" | grep "browser_download_url.*armf.deb" | cut -d '"' -f 4) - fi - - echo "Installing From: $releaseURL" - - dependencies="libgtk-3-0 xserver-xorg xinit x11-xserver-utils" - IFS='/' read -ra version <<< "$releaseURL" - - echo "Installing OctoScreen "${version[7]}, $arch"" - - echo "Installing Dependencies ..." - sudo apt -qq update - sudo apt -qq install $dependencies -y - - if [ -d "/home/pi/OctoPrint/venv" ]; then - DIRECTORY="/home/pi/OctoPrint/venv" - elif [ -d "/home/pi/oprint" ]; then - DIRECTORY="/home/pi/oprint" - else - echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." - echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." - text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY - fi; - - if [ $DIRECTORY == "-" ]; then - echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." - elif [ ! -d $DIRECTORY ]; then - echo "Can't find OctoPrint Installation, please run the script again!" - exit 1 - fi; - - #if [ $DIRECTORY != "-" ]; then - # plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) - # checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins - # echo "Installing Plugins..." - # - # if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" - # fi; - # if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" - # fi; - # if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" - # fi; - # if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" - # fi; - # if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" - # fi; - # if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" - # fi; - # if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then - # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" - # fi; - #fi; - - echo "Installing OctoScreen "${version[7]}, $arch" ..." - - wget -O ~/octoscreen.deb $releaseURL -q --show-progress - - sudo dpkg -i ~/octoscreen.deb - - rm ~/octoscreen.deb - - list_input "Shall I reboot your Pi now?" yes_no reboot - echo "OctoScreen has been successfully installed! :)" - if [ $reboot == 'yes' ]; then - sudo reboot - fi - - echo "HAY LO" - -} - -. <( optparse.build name=octoscreen description="OctoScreen Manager" allow=positional exec=optparse.usage) diff --git a/scripts/octoscreen b/scripts/octoscreen new file mode 100755 index 00000000..891214de --- /dev/null +++ b/scripts/octoscreen @@ -0,0 +1,451 @@ +#!/usr/bin/bash +function octoscreen.license() { [[ $VERBOSITY_CURRENT -ge $VERBOSITY_ECHO ]] && { cat <. +EOL +} || echo.error "Can't display License when quiet..." +exit; +} + +REPO="Z-Bolt/OctoScreen" +MAIN="master" +WGET_RAW="https://github.com/$REPO/raw/$MAIN" +LIBRARIES=("lib/verbosity.bash" "lib/inquirer.bash" "lib/optparse.bash") +PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; +RELEASE_ARCH='' + +VERBOSITY_PREFIX='OCTOSCREEN ' +OCTOSCREEN_TASKS=() +OCTOSCREEN_DEPENDENCIES=() +OCTOSCREEN_DEB='' +yes_no=( 'yes' 'no' ) + +SYSTEM_ARCH=$(uname -m) +declare -A ARCHITECTURES=( [arm.*]=*armhf.deb ) + +# Prelim, just check if we support the current architecture... +for __ARCH in "${!ARCHITECTURES[@]}"; do [[ `expr "$SYSTEM_ARCH" : "^$__ARCH\$"` -gt 0 ]] && RELEASE_ARCH="${ARCHITECTURES[$__ARCH]}" && break; done; +[[ -z $RELEASE_ARCH ]] && { echo "We are sorry, but we do not support your system achitecture ($SYSTEM_ARCH). Exiting"; exit 1; } + +while [[ "$SOURCE" != /dev/fd/* && -L "$SOURCE" ]]; do echo "hit"; DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; +DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; + +### Setup + +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; + +optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" +optparse.define short=b long=build description="Build OctoScreen from source directory" variable=MAKE_DIR dispatch="octoscreen.tasks.add build #" default="$(pwd)" +optparse.define long='nodep' variable=SKIP_DEPENDENCIES hide flag + +optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" +#optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag + +optparse.define.single name="install" description="Install/Upgrade OctoScreen" dispatch="octoscreen.tasks.add install" +optparse.define.single name="*.deb" description="Target for Install/Upgrade and/or Build" dispatch="octoscreen.set.deb \"\$__arg\"" +optparse.define.single name="*" dispatch="octoscreen.handle.unknown \"\$__arg\"" help=hide + +echo.verbosity.init_optparse 0 + + +### Primary Functions: See bottom for other Utility Functions + +function octoscreen.main(){ #Called after all args are parsed + + local _task_order="build lcd install" + + [[ -z "${OCTOSCREEN_TASKS[@]}" ]] && echo.error "Nothing to do. Please give me a purpose in life... I BEG YOU" && octoscreen.maybe.usage; + + echo "Welcome to the OctoScreen Manager" + + echo.info "Beginning Task List" + + echo.debug "Tasks have to occur in an order, so we do them in order, no matter how they were passed." + echo.debug "We check them in the following order: $_task_order[@]" + echo.debug "First we execute and available \`prepare\` commands, then we install any registered dependencies, and then we execute the task it's self." + + octoscreen.tasks.do prepare $_task_order + + [[ $? -eq 0 ]] && octoscreen.dependencies.install + + # Tasks have to occur in an order, so we do them in order, no matter how they were passed. + [[ $? -eq 0 ]] && octoscreen.tasks.do task $_task_order + + [[ $? -eq 0 ]] || echo.fatal "Unknown error. ($?)" + +} + +function octoscreen.dependencies.install(){ + echo.debug "octoscreen.dependencies.install()" + + [[ -z "$OCTOSCREEN_DEPENDENCIES" ]] && echo.info "No dependencies to install, returning" && return 0 + + local dependency_count="${#OCTOSCREEN_DEPENDENCIES[@]}" + + echo.debug "${dependency_count} dependencies queued to install: ${OCTOSCREEN_DEPENDENCIES[*]}" + + [[ ! -z $SKIP_DEPENDENCIES ]] && echo.notice "Skipping dependencies per user request" && return 0 + + #local _apt_list_installed=() + # + #echo.debug "Looking for already installed libraries" + # + #readarray -t _apt_list_installed <<<"$(apt list ${OCTOSCREEN_DEPENDENCIES[*]} 2>/dev/null)" + # + #[[ "${#_apt_installed[@]}" -gt 1 ]] && { + # + # local _listing=false + # local _apt_installed=() + # + # + # + # echo.info "Parsing out already installed libraries" + # + # echo.debug "Of the queued dependencies, we found the following were already installed: ${_apt_installed[*]}" + # + #} + # + #[[ -z $AUTO_FORCE ]] && { + # + # + # + # #IFS=$'\n' read -rd '' -a __read <<<"$(apt list ${OCTOSCREEN_DEPENDENCIES[*]} 2>/dev/null)" + # + # for option in "${_apt_installed[@]}"; do + # echo "Package: $option" + # done + # + #} + + echo -e "Installing the queued dependencies:\n\t${OCTOSCREEN_DEPENDENCIES[*]}" + + local apt='apt' + + [[ $VERBOSITY_CURRENT -le $VERBOSITY_NOTICE ]] && { + echo.notice "Setting \`apt\` quiet." + apt+=' -q' + } + + echo.notice "Executing \`$apt update\`" + sudo $apt update + + [[ ! -z $AUTO_YES ]] && apt+=' -y' + + echo.notice "Executing \`$apt install ${OCTOSCREEN_DEPENDENCIES[*]}\`" + sudo $apt install ${OCTOSCREEN_DEPENDENCIES[*]} + + true +} + +function octoscreen.task.install() { + + local version_regex='' + local deb_name='' + + echo "HEY HEY! Welcome to OctoScreen. Let's get you set up and going..." + + local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_INFO ]] && silent+='>/dev/null 2>&1' + + echo.notice "Looking to see if OctoScreen is already installed... '$found'" + + [[ "${found::1}" = "i" ]] && { + + local question="OctoScreen is already installed. " + + [[ "${found:1:1}" != "i" ]] && + question+="But it is in a bad way... Would you like to reinstall it?" || + question+="Would you like to upgrade it?" + + list_input "$question" yes_no reinstall + if [ $reinstall == 'yes' ]; then + echo.notice "We will continue with removing and re-installing OctoScreen." + + echo.debug "Stopping the OctoScreen Service" + sudo service octoscreen stop >/dev/null 2>&1 + + echo.debug "Removing OctoScreen" + sudo dpkg -r octoscreen + + else + echo "OctoScreen is already installed, exiting." && exit + fi + } + + [[ -z $OCTOSCREEN_DEB ]] && { + + [[ -z "$RELEASE_ARCH" ]] && echo.fatal "It doesn't seem like we support your Architecture (${SYSTEM_ARCH})" + + local RELEASES="https://api.github.com/repos/$REPO/releases/latest" + + echo.info "Using Release Source URL: $RELEASES" + + local RELEASE_URL=$(curl -s "$RELEASES" | grep "browser_download_url.$RELEASE_ARCH" | cut -d '"' -f 4); + + [[ -z "$RELEASE_URL" ]] && echo.fatal "Unable to find correct package for your Architecture (${arch})" + + echo.info "Found matching Package URL: $RELEASE_URL" + + deb_name=$(basename $RELEASE_URL) + + echo.debug "Basename is \`basename $deb_name\`" + + OCTOSCREEN_DEB=$(mktemp) + + echo.debug "Created temporary target file $OCTOSCREEN_DEB" + + } || { + + echo.info "Using user-supplied DEB file $OCTOSCREEN_DEB" + + [[ ! -f $OCTOSCREEN_DEB ]] && echo.fatal "$OCTOSCREEN_DEB does not exist" + + deb_name=$(basename $OCTOSCREEN_DEB) + + echo.debug "Basename is \`$deb_name\`" + } + + echo.debug "Extracting the Version and Architecture from ($deb_name)" + + if [[ $deb_name =~ [^_/]+_(.+)_([^_]+)\.deb ]]; then + local DEB_ARCH="${BASH_REMATCH[2]}" + OCTOSCREEN_DEB_VERSION="${BASH_REMATCH[1]}" + + else + echo.warn "Unable to determine the OctoScreen Version and Architecture from file: $deb_name" + OCTOSCREEN_DEB_VERSION=unknown + list_input "The Package version and Release Architecture were unable to be determined, this may not end well. Would you like to continue?" yes_no force + if [ $force == 'yes' ]; then + echo.warn "We will continue with installation, god speed." + SYSTEM_ARCH=unknown + else + echo.fatal "Unable to determine the OctoScreen Version and Archetecture from Package: $deb_name" + fi + fi + + echo.debug "Parsed DEB Version: $OCTOSCREEN_DEB_VERSION" + + false && { + if [ -d "/home/pi/OctoPrint/venv" ]; then + DIRECTORY="/home/pi/OctoPrint/venv" + elif [ -d "/home/pi/oprint" ]; then + DIRECTORY="/home/pi/oprint" + else + echo "Neither /home/pi/OctoPrint/venv nor /home/pi/oprint can be found." + echo "If your OctoPrint instance is running on a different machine just type - in the following prompt." + text_input "Please specify OctoPrints full virtualenv path manually (no trailing slash)." DIRECTORY + fi; + + if [ $DIRECTORY == "-" ]; then + echo "Not installing any plugins for remote installation. Please make sure to have Display Layer Progress installed." + elif [ ! -d $DIRECTORY ]; then + echo "Can't find OctoPrint Installation, please run the script again!" + exit 1 + fi; + + + #if [ $DIRECTORY != "-" ]; then + # plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) + # checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins + # echo "Installing Plugins..." + # + # if [[ " ${selected_plugins[@]} " =~ "Display Layer Progress (mandatory)" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Filament Manager" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Preheat Button" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/marian42/octoprint-preheat/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Enclosure" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Print Time Genius" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "Ultimaker Format Package" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip" + # fi; + # if [[ " ${selected_plugins[@]} " =~ "PrusaSlicer Thumbnails" ]]; then + # "$DIRECTORY"/bin/pip install -q --disable-pip-version-check "https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip" + # fi; + #fi; + } + + echo "Installing OctoScreen "$OCTOSCREEN_DEB_VERSION, $DEB_ARCH"" + + + [[ ! -z $RELEASE_URL ]] && { + echo.notice "Downloading Remote Deb File From: $RELEASE_URL" + + local command="wget -O $OCTOSCREEN_DEB $RELEASE_URL" + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_INFO ]] && command+=' -q' + + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_ECHO ]] && command+=' --show-progress' + + echo.debug "Executing \`$command\`" + + trap "rm -f $OCTOSCREEN_DEB" EXIT + + # -q --show-progress + $command + + echo.info "Temporary Deb File: $OCTOSCREEN_DEB" + + } + + [[ ! -f $OCTOSCREEN_DEB ]] && echo.fatal "After all this work, it seems like the Package doesn't actually exist: $OCTOSCREEN_DEB" + + sudo dpkg -i $OCTOSCREEN_DEB + + [[ ! -z $RELEASE_URL ]] && { + rm -f $OCTOSCREEN_DEB + trap - EXIT + } + + #? Maybe other tasks? + list_input "Shall I reboot your Pi now?" yes_no reboot + if [ $reboot == 'yes' ]; then + echo "Your system will now reboot!" + sudo reboot + else + echo "Starting OctoScreen Service" + sudo service octoscreen start + echo "OctoScreen has been successfully installed! Have a great day!" + fi + + exit #? Maybe other tasks? +} + +function octoscreen.task.build(){ + echo "building" + : + true +} + +function octoscreen.task.lcd(){ + : +} + +### Task Preparation Functions + +function octoscreen.set.deb(){ + + # wondering if we should do any checks here... + # thinking they should be done in build/instal + + !( octoscreen.tasks.has build || octoscreen.tasks.has install ) && echo.warn "The target *.deb file SHOULD be specified after the target COMMAND (build|install)" + + OCTOSCREEN_DEB="$1"; +} + +function octoscreen.prepare.install(){ + echo.debug "octoscreen.prepare.install()" + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils +} + +function octoscreen.prepare.build(){ + echo.debug "octoscreen.prepare.build()" + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils + echo "build" +} + +function octoscreen.prepare.lcd(){ + echo.debug "octoscreen.prepare.lcd()" + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils +} + +function octoscreen.handle.unknown(){ + echo.error "Unknown Task '$1'" + octoscreen.maybe.usage +} + + +### Utility Functions + +function octoscreen.tasks.do(){ + echo.debug "octoscreen.tasks.do($*)" + + local did_a_thing=false + + [[ -z "$2" ]] && echo.fatal "Task execution requies at least an action AND a task to take it on" && return 1; + + local do="$1"; shift; + + for task in $@; do + octoscreen.tasks.has $task && { + task="octoscreen.$do.${task}" + + echo.debug "Fully qualified callback name: $task" + + echo.debug "Checking to see if there is a function with that name" + + ( declare -f "$task" >/dev/null 2>&1 ) && { + echo.debug "Function Exists: $task" + echo.info "Executing ${task}()" + $task + did_a_thing="$?" + } || { + echo.debug "Function does not exist, skipping: $task" + } + + } + done + + echo.debug "'did_a_thing' status: $did_a_thing" + return "$did_a_thing" +} + +function octoscreen.tasks.has(){ + echo.debug "octoscreen.tasks.has($1)" + [[ -z "$1" ]] && echo.error "You can't search for nothing, that's bad, m'kay?"; + echo.debug "Checking for OCTOSCREEN_TASK '$task' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'" + if ( dlm=$'\x1F' ; IFS="$dlm" ; [[ "$dlm${OCTOSCREEN_TASKS[*]}$dlm" == *"$dlm${1}$dlm"* ]] ) ; then + echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'" + return 0 + else + echo.debug "task not found" + fi + return 1 +} + + +function octoscreen.tasks.add(){ + echo.debug "octoscreen.tasks.add()" + [[ -z "$1" ]] && echo.error "Can't add... um... NO tasks... Bad dev..." && return 0; + OCTOSCREEN_TASKS+=( $1 ) + echo.debug "New Task List: ${OCTOSCREEN_TASKS[*]}" +} + + +function octoscreen.dependencies.add(){ + echo.debug "octoscreen.dependencies.add()"; + + [[ -z "$1" ]] && echo.error "Can't add... um... NO dependencies... Bad dev..." && return 0; + + OCTOSCREEN_DEPENDENCIES+=( $* ); + echo.debug "New Dependency List: ${OCTOSCREEN_DEPENDENCIES[*]}"; +} + +function octoscreen.maybe.usage() { + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_ECHO ]] && optparse.usage || echo.fatal "Your verbosity is hiding the default behaviour of the help menu, stupid face."; + exit +} + +. <( optparse.build name=$([[ "$DIR" =~ /proc/* ]] && echo '' || basename $0) description="OctoScreen Manager" allow=positional finally=octoscreen.main allow=unrecognized usage_header="${optparse_usage_header} command [command ...] [*.deb]") From c1693c2d31bfb678b6d1687b400d1a98126ff8f3 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 15:52:23 +0000 Subject: [PATCH 16/61] Added echo.chatty for conversational debug echos --- scripts/octoscreen | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 891214de..ac219ee4 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -73,9 +73,9 @@ function octoscreen.main(){ #Called after all args are parsed echo.info "Beginning Task List" - echo.debug "Tasks have to occur in an order, so we do them in order, no matter how they were passed." - echo.debug "We check them in the following order: $_task_order[@]" - echo.debug "First we execute and available \`prepare\` commands, then we install any registered dependencies, and then we execute the task it's self." + echo.chatty "Tasks have to occur in an order, so we do them in order, no matter how they were passed." + echo.chatty "We check them in the following order: $_task_order[@]" + echo.chatty "First we execute and available \`prepare\` commands, then we install any registered dependencies, and then we execute the task it's self." octoscreen.tasks.do prepare $_task_order @@ -408,7 +408,7 @@ function octoscreen.tasks.do(){ } done - echo.debug "'did_a_thing' status: $did_a_thing" + echo.chatty "'did_a_thing' status: $did_a_thing" return "$did_a_thing" } @@ -448,4 +448,10 @@ function octoscreen.maybe.usage() { exit } +function echo.chatty(){ + __VERBOSITY_URGENCY=$VERBOSITY_DEBUG+1 + printf -v message "$VERBOSITY_DEBUG_FORMAT\e[0m" "$VERBOSITY_PREFIX" "CHATTY" "$1" + echo -e "$message" +} + . <( optparse.build name=$([[ "$DIR" =~ /proc/* ]] && echo '' || basename $0) description="OctoScreen Manager" allow=positional finally=octoscreen.main allow=unrecognized usage_header="${optparse_usage_header} command [command ...] [*.deb]") From e06b610e1682f058a4b881ae44a91b7065676b38 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 15:56:40 +0000 Subject: [PATCH 17/61] Made sure to fatal out of build and LCD (not yet implemented) --- scripts/octoscreen | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index ac219ee4..052cebed 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -334,12 +334,13 @@ function octoscreen.task.install() { } function octoscreen.task.build(){ - echo "building" + echo.fatal "Building not implemented yet" : true } function octoscreen.task.lcd(){ + echo.fatal "Installing the LCD is not implemented yet" : } From 8c94b5667f3f8019cae8978dc71648ebe98d8eef Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 16:07:38 +0000 Subject: [PATCH 18/61] Yeah, moved the 'installed' check to `octoscreen.prepare.install`, mush betterer. --- scripts/octoscreen | 57 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 052cebed..3bd09dcb 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -157,35 +157,6 @@ function octoscreen.task.install() { echo "HEY HEY! Welcome to OctoScreen. Let's get you set up and going..." - local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` - - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_INFO ]] && silent+='>/dev/null 2>&1' - - echo.notice "Looking to see if OctoScreen is already installed... '$found'" - - [[ "${found::1}" = "i" ]] && { - - local question="OctoScreen is already installed. " - - [[ "${found:1:1}" != "i" ]] && - question+="But it is in a bad way... Would you like to reinstall it?" || - question+="Would you like to upgrade it?" - - list_input "$question" yes_no reinstall - if [ $reinstall == 'yes' ]; then - echo.notice "We will continue with removing and re-installing OctoScreen." - - echo.debug "Stopping the OctoScreen Service" - sudo service octoscreen stop >/dev/null 2>&1 - - echo.debug "Removing OctoScreen" - sudo dpkg -r octoscreen - - else - echo "OctoScreen is already installed, exiting." && exit - fi - } - [[ -z $OCTOSCREEN_DEB ]] && { [[ -z "$RELEASE_ARCH" ]] && echo.fatal "It doesn't seem like we support your Architecture (${SYSTEM_ARCH})" @@ -358,6 +329,34 @@ function octoscreen.set.deb(){ function octoscreen.prepare.install(){ echo.debug "octoscreen.prepare.install()" + + local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` + + echo.notice "Looking to see if OctoScreen is already installed... '$found'" + + [[ "${found::1}" = "i" ]] && { + + local question="OctoScreen is already installed. " + + [[ "${found:1:1}" != "i" ]] && + question+="But it is in a bad way... Would you like to reinstall it?" || + question+="Would you like to upgrade it?" + + list_input "$question" yes_no reinstall + if [ $reinstall == 'yes' ]; then + echo.notice "We will continue with removing and re-installing OctoScreen." + + echo.debug "Stopping the OctoScreen Service" + sudo service octoscreen stop >/dev/null 2>&1 + + echo.debug "Removing OctoScreen" + sudo dpkg -r octoscreen + + else + echo "OctoScreen is already installed, exiting." && exit + fi + } + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils } From 62aaf7ee2893e859223dd95d3e0e663b8e1c81dd Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 17:00:16 +0000 Subject: [PATCH 19/61] Removed a stray Echo and an unnessesary fd creation. --- scripts/octoscreen | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 3bd09dcb..2c8a95f6 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -23,7 +23,7 @@ exit; REPO="Z-Bolt/OctoScreen" MAIN="master" WGET_RAW="https://github.com/$REPO/raw/$MAIN" -LIBRARIES=("lib/verbosity.bash" "lib/inquirer.bash" "lib/optparse.bash") +LIBRARIES=("lib/optparse.bash" "lib/inquirer.bash" "lib/verbosity.bash") PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; RELEASE_ARCH='' @@ -40,12 +40,11 @@ declare -A ARCHITECTURES=( [arm.*]=*armhf.deb ) for __ARCH in "${!ARCHITECTURES[@]}"; do [[ `expr "$SYSTEM_ARCH" : "^$__ARCH\$"` -gt 0 ]] && RELEASE_ARCH="${ARCHITECTURES[$__ARCH]}" && break; done; [[ -z $RELEASE_ARCH ]] && { echo "We are sorry, but we do not support your system achitecture ($SYSTEM_ARCH). Exiting"; exit 1; } -while [[ "$SOURCE" != /dev/fd/* && -L "$SOURCE" ]]; do echo "hit"; DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; +while [[ "$SOURCE" != /dev/fd/* && -L "$SOURCE" ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; -### Setup - -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE=$(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; [ -v PS1 ] && return || exit 1; else echo ' SUCCESS'; fi; SOURCE_FILE=<(echo "$SOURCE"); unset SOURCE; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source "$SOURCE_FILE"; if [[ "$?" != "0" ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; +### Load Bash Dependencies +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE_FILE=<(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); if [[ $? -ne 0 ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" optparse.define short=b long=build description="Build OctoScreen from source directory" variable=MAKE_DIR dispatch="octoscreen.tasks.add build #" default="$(pwd)" From cdaa1498f798c836ea9f4d0529caee4b1063a0be Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 17:27:47 +0000 Subject: [PATCH 20/61] Too many un-needed fd's, fixed it. --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 2c8a95f6..f2bc1b11 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -44,7 +44,7 @@ while [[ "$SOURCE" != /dev/fd/* && -L "$SOURCE" ]]; do DIR="$( cd -P "$( dirname DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; ### Load Bash Dependencies -echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; if [[ -z "$SOURCE_FILE" ]]; then echo -en "${CL}Fetching '{$LIBRARY}'..."; SOURCE_FILE=<(wget -qO- "$WGET_RAW/scripts/$LIBRARY"); if [[ "$?" != "0" ]]; then echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; fi; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); if [[ $? -ne 0 ]]; then echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; else echo ' SUCCESS'; fi; done; echo -en "${CL}${CL}"; +echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; [[ -z "$SOURCE_FILE" ]] && { echo -en "${CL}Fetching '{$LIBRARY}'..."; source <(curl -s -L "$WGET_RAW/scripts/$LIBRARY"); [[ $? -ne 0 ]] && { echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; continue; }; }; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); [[ $? -ne 0 ]] && { echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; }; done; echo -en "${CL}${CL}"; optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" optparse.define short=b long=build description="Build OctoScreen from source directory" variable=MAKE_DIR dispatch="octoscreen.tasks.add build #" default="$(pwd)" From adc5501002ead6e05f99dc0e084a0e352759a840 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 19:39:59 +0000 Subject: [PATCH 21/61] Missing $ in defaults caused defaults not to be populated. --- scripts/lib/optparse.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/lib/optparse.bash b/scripts/lib/optparse.bash index cdb5cac0..5973a6fb 100644 --- a/scripts/lib/optparse.bash +++ b/scripts/lib/optparse.bash @@ -437,8 +437,8 @@ function optparse.define(){ #echo "$_optparse_usage" } - [[ $has_default && ! -z "$variable" ]] && - optparse_defaults+="#NL[[ -z ${variable} ]] && ${variable}='${default}'" + $has_default && [[ ! -z "$variable" ]] && + optparse_defaults+="#NL[[ -z \$${variable} ]] && ${variable}='${default}'" local validate_variable="$is_list && { valid=false From 5f0e71980bec66226ab1a263bec214b786a41045 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 20:25:24 +0000 Subject: [PATCH 22/61] Added the Build Process Also not sure if I mentioned that I added `remove`. Additionally, this moves the installed and healthy checks to `octoscreen.main`. Should about do it for building/installing/removing and such. --- scripts/octoscreen | 192 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 162 insertions(+), 30 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index f2bc1b11..37aa89d1 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -47,13 +47,15 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; [[ -z "$SOURCE_FILE" ]] && { echo -en "${CL}Fetching '{$LIBRARY}'..."; source <(curl -s -L "$WGET_RAW/scripts/$LIBRARY"); [[ $? -ne 0 ]] && { echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; continue; }; }; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); [[ $? -ne 0 ]] && { echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; }; done; echo -en "${CL}${CL}"; optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" -optparse.define short=b long=build description="Build OctoScreen from source directory" variable=MAKE_DIR dispatch="octoscreen.tasks.add build #" default="$(pwd)" +optparse.define short=m long=makedir description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has && echo.fatal 'Provide MakeDir AFTER \'build\' " default=$(pwd) optparse.define long='nodep' variable=SKIP_DEPENDENCIES hide flag optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" #optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag optparse.define.single name="install" description="Install/Upgrade OctoScreen" dispatch="octoscreen.tasks.add install" +optparse.define.single name="remove" description="Remove OctoScreen" dispatch="octoscreen.tasks.add remove" +optparse.define.single name=build description="Build OctoScreen" dispatch="octoscreen.tasks.add build" optparse.define.single name="*.deb" description="Target for Install/Upgrade and/or Build" dispatch="octoscreen.set.deb \"\$__arg\"" optparse.define.single name="*" dispatch="octoscreen.handle.unknown \"\$__arg\"" help=hide @@ -64,12 +66,22 @@ echo.verbosity.init_optparse 0 function octoscreen.main(){ #Called after all args are parsed - local _task_order="build lcd install" + local _task_order="docker build lcd remove install" [[ -z "${OCTOSCREEN_TASKS[@]}" ]] && echo.error "Nothing to do. Please give me a purpose in life... I BEG YOU" && octoscreen.maybe.usage; echo "Welcome to the OctoScreen Manager" + local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` + + echo.notice "Checking to see if OctoScreen is already installed..." + + declare -G OCTOSCREEN_INSTALLED=$([[ "${found::1}" = "i" ]] && echo "true" || echo "false") + + $OCTOSCREEN_INSTALLED && [[ "${found:1:1}" != "i" ]] && !octoscreen.tasks.has remove && + echo.warn "OctoScreen is KINDA installed, but it is in a bad way. We suggest re-installing." + + echo.info "Beginning Task List" echo.chatty "Tasks have to occur in an order, so we do them in order, no matter how they were passed." @@ -304,9 +316,58 @@ function octoscreen.task.install() { } function octoscreen.task.build(){ - echo.fatal "Building not implemented yet" - : - true + echo.debug "octoscreen.prepare.build()" + + [[ ! -z $OCTOSCREEN_DEB ]] && echo.error "Just so you know, we don't support outputting the build to a specific file, so, we won't be changing OCTOSCREEN_DEB ($OCTOSCREEN_DEB), this may mess with your install." + + ( grep 'PACKAGE_NAME = octoscreen' "$MAKE_DIR/Makefile" >/dev/null 2>&1 ) && + echo.debug "Buildign with Source Directory ($MAKE_DIR)" || + echo.fatal "Make File does not seem to be for OctoScreen"; + + [[ -d $MAKE_DIR/build ]] && { + echo.notice "Clearing the existing \`build\` directory ($MAKE_DIR/build)" + echo.info "Pausing for 5 seconds..." + sleep 5 + sudo rm -rf "$MAKE_DIR/build" + } + + local make_command="make -C $MAKE_DIR" + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && make_command+=' -s' + + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_INFO ]] && make_command+=' -d' + + make_command+=" build" + + echo.notice "Executing MAKE command: $make_command" + + echo "Building OctoScreen, this may take a bit." + + echo.notice "Sleeping for 5 seconds, incase you want to abort..." + + sleep 5 + + sudo $make_command + + [[ $? -ne 0 ]] && { + echo.fatal "Make exited unsuccessfully!"; + } + + echo.notice "Build Complete!" + + BUILT_DEB=$(find $MAKE_DIR/build/ -name "*.deb" -print0 | xargs -r -0 ls -1 -t | head -1) + + [[ -z $BUILT_DEB ]] && echo.fatal "Something happen, we can't find the compiled DEB..." + + [[ -z $OCTOSCREEN_DEB ]] && { + echo.info "Setting OCTOSCREEN_DEB to $BUILT_DEB" + OCTOSCREEN_DEB=$BUILT_DEB + } || { + echo.info "OCTOSCREEN_DEB is not empty, leaving it as it is." + } + + echo "Most recently compiled deb can be found at: $BUILT_DEB" + } function octoscreen.task.lcd(){ @@ -321,7 +382,7 @@ function octoscreen.set.deb(){ # wondering if we should do any checks here... # thinking they should be done in build/instal - !( octoscreen.tasks.has build || octoscreen.tasks.has install ) && echo.warn "The target *.deb file SHOULD be specified after the target COMMAND (build|install)" + !( octoscreen.tasks.has install ) && echo.warn "The target *.deb file SHOULD be specified after \`install\`" OCTOSCREEN_DEB="$1"; } @@ -331,26 +392,16 @@ function octoscreen.prepare.install(){ local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` - echo.notice "Looking to see if OctoScreen is already installed... '$found'" + echo.notice "Checking to see if OctoScreen is already installed..." - [[ "${found::1}" = "i" ]] && { - - local question="OctoScreen is already installed. " + ( $OCTOSCREEN_INSTALLED && ! octoscreen.tasks.has remove ) && { - [[ "${found:1:1}" != "i" ]] && - question+="But it is in a bad way... Would you like to reinstall it?" || - question+="Would you like to upgrade it?" + local question="OctoScreen is already installed. Would you like to re-install it?" list_input "$question" yes_no reinstall if [ $reinstall == 'yes' ]; then - echo.notice "We will continue with removing and re-installing OctoScreen." - - echo.debug "Stopping the OctoScreen Service" - sudo service octoscreen stop >/dev/null 2>&1 - - echo.debug "Removing OctoScreen" - sudo dpkg -r octoscreen - + echo.notice "Excelent! We will removie and re-install OctoScreen." + octoscreen.tasks.add remove else echo "OctoScreen is already installed, exiting." && exit fi @@ -359,10 +410,66 @@ function octoscreen.prepare.install(){ octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils } +function octoscreen.task.remove(){ + + echo.notice "Removing OctoScreen" + + echo.debug "Stopping the OctoScreen Service" + sudo service octoscreen stop >/dev/null 2>&1 + + echo.debug "Removing OctoScreen" + sudo dpkg -r octoscreen + +} + +function octoscreen.prepare.remove(){ + $OCTOSCREEN_INSTALLED || { + echo.error "OctoScreen is not installed, nothing to do" + octoscreen.tasks.remove remove + } +} + +function octoscreen.task.docker(){ + echo "Installing Docker... This may take a while..." + echo.warn "If this hangs on 'Scanning something something something...' just hit enter, should be good..." + + local _docker='~/get-docker.sh' + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _docker+=' >/dev/null 2>&1' + + declare -g CHANNEL='stable' + declare -g DOWNLOAD_URL='' + declare -g REPO_FILE='' + + curl -fsSL get.docker.com -o $_docker + sh $_docker +} + function octoscreen.prepare.build(){ + echo.debug "octoscreen.prepare.build()" - octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils - echo "build" + + [[ -z $MAKE_DIR ]] && echo.fatal "No Make Directory provided" + [[ -d $MAKE_DIR ]] || echo.fatal "Specified Make Directory is not a directory: $MAKE_DIR" + + while [[ -d $MAKE_DIR ]] && [[ ! -f $MAKE_DIR/Makefile ]]; do + echo.debug "$MAKE_DIR does not seem like a valid Make directory. Looking up." + local _make_dir=$( dirname $MAKE_DIR ) + [[ "$_make_dir" == "$MAKE_DIR" ]] && echo.debug "Looks like we are looping, breaking" && break; + MAKE_DIR=$_make_dir; + done + + [[ -f $MAKE_DIR/Makefile ]] && + echo.info "Found $MAKE_DIR/Makefile" || + echo.fatal "No Make File found in ($MAKE_DIR)"; + + command -v "docker" > /dev/null 2>&1 && + echo.debug "Docker IS installed." || + octoscreen.tasks.add docker; + + # need to recall what the dependencies are... + # octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils + } function octoscreen.prepare.lcd(){ @@ -384,11 +491,12 @@ function octoscreen.tasks.do(){ local did_a_thing=false [[ -z "$2" ]] && echo.fatal "Task execution requies at least an action AND a task to take it on" && return 1; + [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; local do="$1"; shift; for task in $@; do - octoscreen.tasks.has $task && { + ( octoscreen.tasks.has $task ) && { task="octoscreen.$do.${task}" echo.debug "Fully qualified callback name: $task" @@ -408,27 +516,51 @@ function octoscreen.tasks.do(){ done echo.chatty "'did_a_thing' status: $did_a_thing" + return "$did_a_thing" } function octoscreen.tasks.has(){ echo.debug "octoscreen.tasks.has($1)" - [[ -z "$1" ]] && echo.error "You can't search for nothing, that's bad, m'kay?"; + [[ -z "$1" ]] && echo.error "You can't search for nothing, that's bad, m'kay?" && return 1; + [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; echo.debug "Checking for OCTOSCREEN_TASK '$task' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'" if ( dlm=$'\x1F' ; IFS="$dlm" ; [[ "$dlm${OCTOSCREEN_TASKS[*]}$dlm" == *"$dlm${1}$dlm"* ]] ) ; then - echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'" - return 0 + echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'"; + return 0; else - echo.debug "task not found" + echo.debug "task not found"; fi return 1 } +function octoscreen.tasks.remove(){ + echo.debug "octoscreen.tasks.remove()" + [[ -z "$1" ]] && { echo.error "Can't remove... um... NO tasks... Bad dev..."; return 0; }; + octoscreen.tasks.has "$1" || { echo.debug "Task ($1) not set. Nothing to do."; return 0; }; + + for i in "${!OCTOSCREEN_TASKS[@]}"; do + if [[ ${OCTOSCREEN_TASKS[i]} = $1 ]]; then + unset 'OCTOSCREEN_TASKS[i]' + fi + done + + local _tasks=() + + for i in "${!OCTOSCREEN_TASKS[@]}"; do + _tasks+=( "${OCTOSCREEN_TASKS[i]}" ) + done + + OCTOSCREEN_TASKS=("${_tasks[@]}") + + echo.debug "New Task List: ${OCTOSCREEN_TASKS[*]}" +} function octoscreen.tasks.add(){ echo.debug "octoscreen.tasks.add()" - [[ -z "$1" ]] && echo.error "Can't add... um... NO tasks... Bad dev..." && return 0; - OCTOSCREEN_TASKS+=( $1 ) + [[ -z "$1" ]] && { echo.error "Can't add... um... NO tasks... Bad dev..."; return 0; }; + octoscreen.tasks.has "$1" && { echo.debug "Task ($1) already active. Nothing to do."; return 0; }; + OCTOSCREEN_TASKS+=( "$1" ) echo.debug "New Task List: ${OCTOSCREEN_TASKS[*]}" } From ec196ed3d28362109813be2de213ec9a774efeaf Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Thu, 11 Mar 2021 20:32:52 +0000 Subject: [PATCH 23/61] Added an ERROR if you want us to be quiet when making... --- scripts/octoscreen | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 37aa89d1..0f187aef 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -78,7 +78,7 @@ function octoscreen.main(){ #Called after all args are parsed declare -G OCTOSCREEN_INSTALLED=$([[ "${found::1}" = "i" ]] && echo "true" || echo "false") - $OCTOSCREEN_INSTALLED && [[ "${found:1:1}" != "i" ]] && !octoscreen.tasks.has remove && + $OCTOSCREEN_INSTALLED && [[ "${found:1:1}" != "i" ]] && ! octoscreen.tasks.has remove && echo.warn "OctoScreen is KINDA installed, but it is in a bad way. We suggest re-installing." @@ -339,6 +339,11 @@ function octoscreen.task.build(){ make_command+=" build" + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_ECHO ]] && { + echo.error "We couldn't help but notice you wanted us to be quiet... UNFORTUNATELY, we can't silence \`make\`, so... Get ready..." + # make_command+=' >/dev/null 2>&1' + } + echo.notice "Executing MAKE command: $make_command" echo "Building OctoScreen, this may take a bit." From 26d20df3d9b7fa15760c1cb4c9ce18fb50ca24d1 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 00:07:15 +0000 Subject: [PATCH 24/61] Build Additions - Added consumption of local /etc/os-release (made it mandatory, but if this seems incorrect, sure) - Added ability to specify Release Target - Spelling Correction - Made '--nodep' visible --- scripts/octoscreen | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 0f187aef..70af1330 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -20,6 +20,10 @@ EOL exit; } +[[ ! -f /etc/os-release ]] && echo "ERROR: We kinda need \`/etc/os-release\`, but I couldn't find it. Proooobably means we don't support your system. If you believe this is in error, please file a bug report." && exit 1; +source /etc/os-release +[[ $ID_LIKE != debian ]] && echo "ERROR: Yeah, no." && exit 1; + REPO="Z-Bolt/OctoScreen" MAIN="master" WGET_RAW="https://github.com/$REPO/raw/$MAIN" @@ -48,7 +52,8 @@ echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" optparse.define short=m long=makedir description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has && echo.fatal 'Provide MakeDir AFTER \'build\' " default=$(pwd) -optparse.define long='nodep' variable=SKIP_DEPENDENCIES hide flag +optparse.define short=b long=build description="Build for a specific Release Target [STRETCH|BUSTER|JESSIE]" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit +optparse.define long='nodep' description="Skip installing Apt Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" #optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag @@ -337,7 +342,7 @@ function octoscreen.task.build(){ [[ $VERBOSITY_CURRENT -ge $VERBOSITY_INFO ]] && make_command+=' -d' - make_command+=" build" + make_command+=" build DEBIAN_PACKAGES=$VERSION_CODENAME" [[ $VERBOSITY_CURRENT -lt $VERBOSITY_ECHO ]] && { echo.error "We couldn't help but notice you wanted us to be quiet... UNFORTUNATELY, we can't silence \`make\`, so... Get ready..." @@ -405,7 +410,7 @@ function octoscreen.prepare.install(){ list_input "$question" yes_no reinstall if [ $reinstall == 'yes' ]; then - echo.notice "Excelent! We will removie and re-install OctoScreen." + echo.notice "Excelent! We will remove and re-install OctoScreen." octoscreen.tasks.add remove else echo "OctoScreen is already installed, exiting." && exit @@ -454,6 +459,9 @@ function octoscreen.prepare.build(){ echo.debug "octoscreen.prepare.build()" + [[ -z $VERSION_CODENAME ]] && echo.fatal "Unable to determine a Release Target (see --help)" + VERSION_CODENAME=${VERSION_CODENAME^^} + [[ -z $MAKE_DIR ]] && echo.fatal "No Make Directory provided" [[ -d $MAKE_DIR ]] || echo.fatal "Specified Make Directory is not a directory: $MAKE_DIR" From 769f1490452ed0d4557fd3ab771361a911e131ac Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 19:58:21 +0000 Subject: [PATCH 25/61] Renamed flags and added use of -y and --force Also includes a new timer, and the last refactor of optparse.bash for now... --- scripts/lib/optparse.bash | 222 +++++++++++++++++++++++--------------- scripts/octoscreen | 77 ++++++++----- 2 files changed, 184 insertions(+), 115 deletions(-) diff --git a/scripts/lib/optparse.bash b/scripts/lib/optparse.bash index 5973a6fb..94f5a47e 100644 --- a/scripts/lib/optparse.bash +++ b/scripts/lib/optparse.bash @@ -145,46 +145,54 @@ function optparse.define.single(){ local key="${option%%=*}"; local value="${option#*=}"; - [[ "$value" == "$key" ]] && value='' + [[ $value == $key ]] && value='' case "$key" in - "desc"|"description") + desc|description) desc="$value" ;; - "name") + name) name="$value" ;; - "value") + value) val="$value" ;; - "dispatch") + dispatch) dispatch="$value" ;; - "help") + help) case $value in default|explicit|hide) declare behaviour_$key="$value" ;; *) - optparse.throw_error "$key [$value] not supported" "$name" + optparse.throw_error "$key [$value] not supported" $name ;; esac ;; esac done - has_val=$([[ -z "$val" ]] && echo "false" || echo "true") + [[ -z "$val" ]] && + local has_val=false || + local has_val=true; - [[ -z "$name" ]] && optparse.throw_error "name is mandatory"; - [[ -z "$desc" && "$behaviour_help" != "hide" ]] && optparse.throw_error "description is mandatory" "$name"; - [[ -z "$dispatch" ]] && optparse.throw_error "a dispatcher is mandatory for commands" "$name"; + [[ -z "$name" ]] && + optparse.throw_error "name is mandatory"; + + [[ -z "$desc" && "$behaviour_help" != "hide" ]] && + optparse.throw_error "description is mandatory" "$name"; + + [[ -z "$dispatch" ]] && + optparse.throw_error "a dispatcher is mandatory for commands" "$name"; #[ -z "$optparse_usage" ] && optparse.group "$optparse_default_group" - [[ "$behaviour_help" != "hide" ]] && { + [[ $behaviour_help != hide ]] && { - [[ -z "$optparse_usage_commands" ]] && optparse_usage_commands="cat >&2 << EOU#NLCommands#NLEOU#NL" + [[ -z "$optparse_usage_commands" ]] && + optparse_usage_commands="cat >&2 << EOU#NLCommands#NLEOU#NL" local _optparse_usage="" @@ -251,78 +259,86 @@ function optparse.define(){ local value="${option#*=}"; case "$key" in - "short") + short) [[ ${#value} -ne 1 ]] && - optparse.throw_error "short name expected to be one character long" "$value" + optparse.throw_error "short name expected to be one character long" $value; + for i in "${optparse_shortnames[@]}"; do - [[ "$i" == "$value" ]] && + [[ $i == $value ]] && optparse.warn "shortname [-$value] already handled" "-$value" && break; - done - optparse_shortnames+=("$value") - shortname="$value" - short="-$value" + done; + + local optparse_shortnames+=("$value") + local shortname="$value" + local short="-$value" [[ -z "$errorname" ]] && - errorname="$short" + local errorname="$short"; ;; - "long") + long) [[ -z ${value} ]] && - optparse.throw_error "long name expected to be atleast one character long" "--$value" + optparse.throw_error "long name expected to be atleast one character long" "--$value"; + for i in "${optparse_longnames[@]}"; do - [[ "$i" == "$value" ]] && + [[ $i == $value ]] && optparse.warn "longname [--$value] already handled" "--$value" && break; - done + done; + optparse_longnames+=("$value") longname="$value" long="--$value" errorname="$long" ;; - "desc"|"description") + desc|description) desc="$value" ;; - "default") + default) default="$value" - has_default="true" + has_default=true ;; - "optional") - optional="true" + optional) + optional=true ;; flag|list) - behaviour="$key" + behaviour=$key ;; - "behaviour") + behaviour) case $value in default|list|flag) - behaviour="$value" + behaviour=$value ;; *) - optparse.throw_error "behaviour [$value] not supported" "$errorname" + optparse.throw_error "behaviour [$value] not supported" $errorname ;; - esac + esac; + ;; - "list") + list) list="$value" ;; - "variable") - variable="$value" + variable) + local variable=$value + for i in "${optparse_variables[@]}"; do - [[ "$i" == "$value" ]] && - optparse.warn "value assignment [\$$value] already handled" "$errorname" && break; - done + [[ $i == $value ]] && + optparse.warn "value assignment [\$$value] already handled" $errorname && break; + done; + optparse_variables+=("$value") ;; - "value") - val="$value" + value) + val=$value ;; - "dispatch") - dispatch="$value" + dispatch) + dispatch=$value ;; - "extra"|"help"|"hide"|"explicit") + extra|help|hide|explicit) case $value in default|explicit|hide) - [[ "$value" == "$key" ]] && { - declare behaviour_help="$value"; - declare behaviour_extra="$value"; - } || declare behaviour_$key="$value"; + [[ $value == $key ]] && { + local behaviour_help=$value; + local behaviour_extra=$value; + } || + local behaviour_$key=$value; ;; *) optparse.throw_error "$key [$value] not supported" "$errorname" @@ -333,52 +349,67 @@ function optparse.define(){ done [[ -z $behaviour_extra ]] && { - [[ "$behaviour" == "flag" ]] && behaviour_extra="hide" || behaviour_extra="explicit" + [[ $behaviour == flag ]] && + local behaviour_extra=hide || + local behaviour_extra=explicit; } [[ -z "$errorname" ]] && optparse.throw_error "argument must have a long or short name" - flag=$([[ $behaviour == "flag" ]] && echo "true" || echo "false") - is_list=$([[ $behaviour == "list" ]] && echo "true" || echo "false") + [[ $behaviour == flag ]] && + local flag=true || + local flag=false; + + [[ $behaviour == list ]] && + local is_list=true || + local is_list=false; - [[ $behaviour == "flag" ]] && { + [[ $behaviour == flag ]] && { [[ -z $default ]] && default=false has_default=true - [[ $default == "true" ]] && val="false" - [[ $default == "false" ]] && val="true" + [[ $default == true ]] && val=false + [[ $default == false ]] && val=true } - has_val=$([[ -z "$val" ]] && echo "false" || echo "true") - has_variable=$([[ -z "$variable" ]] && echo "false" || echo "true") + [[ -z "$val" ]] && + local has_val="false" || + local has_val="true"; + + + [[ -z "$variable" ]] && + local has_variable=false || + local has_variable=true; # check list behaviour - [[ $behaviour == "list" ]] && { + [[ $behaviour == list ]] && { [[ -z ${list:-} ]] && - optparse.throw_error "list is mandatory when using list behaviour" "$errorname" + optparse.throw_error "list is mandatory when using list behaviour" $errorname $has_default && { - valid=false + local valid=false; for i in $list; do - [[ $default == $i ]] && valid=true && break - done + [[ $default == $i ]] && + local valid=true && + break; + done; - $valid || optparse.throw_error "default should be in list" "$errorname" + $valid || optparse.throw_error "default should be in list" $errorname } } - [[ -z "$desc" && "$behaviour_help" != "hide" ]] && { + [[ -z "$desc" && $behaviour_help != hide ]] && { [[ -z "$dispatch" ]] && { - optparse.throw_error "description is mandatory" "$errorname" + optparse.throw_error "description is mandatory" $errorname } || { - [[ "$behaviour_help" == "default" ]] && help_behaviour="explicit" - [[ "$behaviour_help" != "hide" ]] && desc="Executes $dispatch" + [[ $behaviour_help == default ]] && help_behaviour=explicit + [[ $behaviour_help != hide ]] && desc="Executes $dispatch" } } [[ -z "$variable" && -z "$dispatch" ]] && optparse.throw_error "you must give a target variable" "$errorname"; - [[ "$behaviour_help" != "hide" ]] && { + [[ $behaviour_help != hide ]] && { [[ -z "$optparse_usage" ]] && optparse.group "$optparse_default_group"; @@ -405,7 +436,7 @@ function optparse.define(){ _optparse_usage="cat >&2 << EOU#NL$_optparse_usage#NLEOU#NL" - [[ "$behaviour_extra" != "hide" ]] && { + [[ $behaviour_extra != hide ]] && { local _optparse_extra="" @@ -422,17 +453,17 @@ function optparse.define(){ _optparse_extra="cat >&2 << EOE#NL${_optparse_extra}EOE#NL" - [[ "$behaviour_extra" == "explicit" ]] && + [[ $behaviour_extra == explicit ]] && _optparse_extra="if [[ \$1 == "true" ]]; then#NL$_optparse_extra#NLfi#NL" - _optparse_usage+="$_optparse_extra" + _optparse_usage+=$_optparse_extra } } - [[ "$behaviour_help" == "explicit" ]] && - _optparse_usage="if [[ \$1 == "true" ]]; then#NL$_optparse_usage#NLfi#NL" + [[ $behaviour_help == explicit ]] && + _optparse_usage="if [[ \$1 == true ]]; then#NL$_optparse_usage#NLfi#NL" - optparse_usage+="$_optparse_usage" + optparse_usage+=$_optparse_usage #echo "$_optparse_usage" } @@ -453,7 +484,9 @@ function optparse.define(){ [[ ! -z "$dispatch" ]] && { [[ -z "$dispatch_var" ]] && { - $has_variable && dispatch_var="\"\$${variable}\"" || dispatch_var="\"\$__arg_value\"" + $has_variable && + dispatch_var="\"\$${variable}\"" || + dispatch_var="\"\$__arg_value\"" } dispatch_caller="${dispatch} ${dispatch_var}; true;" } @@ -461,13 +494,13 @@ function optparse.define(){ [[ ! -z "$shortname" ]] && { optparse_process_short+=" ${shortname}) - __arg_errorname=\"$short\"; + __arg_errorname=$short; __arg_value=''; ( $flag || $has_val ) && { __arg_value=\"$val\"; } $has_variable && [[ -z \"\$__arg_value\" ]] && { - __arg_value=\"\$__arg_sremain\"; + __arg_value=$__arg_sremain; __arg_sremain=''; [[ -z \"\$__arg_value\" && ! -z \"\$1\" ]] && __arg_value=\"\$1\" && shift; } @@ -481,7 +514,7 @@ function optparse.define(){ [[ ! -z "$longname" ]] && { optparse_process_long+=" ${longname}) - __arg_errorname=\"$long\"; + __arg_errorname=$long; $has_val && { [[ ! -z \"\$__arg_value\" ]] && optparse.usage true 'ERROR: (${errorname}) does not accept user input' 1; __arg_value=\"$val\"; @@ -493,8 +526,12 @@ function optparse.define(){ ;;" } + $has_default && + local _def=DEF || + local _def=''; + $has_variable && optparse_variables_validate+=" - $optional || { [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true; };" + $optional || { [[ -z \${${variable}:-$_def} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true; };" true } @@ -519,31 +556,34 @@ function optparse.build(){ local value="${option#*=}"; case "$key" in - "name"|"description"|"usage_header"|"usage") + name|description|usage_header|usage) declare -g optparse_$key="$value" ;; - "allow") + allow) value=( $value ) for allowed in "${value[@]}"; do case "$allowed" in - "positional") - preserve_positional=true + positional) + local preserve_positional=true ;; - "unrecognized") - allow_unrecognized=true + unrecognized) + local allow_unrecognized=true ;; esac done ;; - "finally") + finally) _exec="#NL$value;" ;; esac done - local _has_additional=$([[ -z "$optparse_additional_handlers" ]] && echo "false" || echo "true") + [[ -z "$optparse_additional_handlers" ]] && + local _has_additional=false || + local _has_additional=true; - $_has_additional && preserve_positional=true + $_has_additional && + local preserve_positional=true $preserve_positional && { preserve_positional=" @@ -591,9 +631,13 @@ cat >&2 << EOH \$(printf "%${optparse_help_full_width}s %s" "Powered by optparse $optparse_version") \$(printf "%${optparse_help_full_width}s %s" "@see --optparse_license") EOH + + [[ "\$1" == "true" && ! -z "\$3" ]] && exit "\$3" || exit 3 } + + # Set default variable values $optparse_defaults diff --git a/scripts/octoscreen b/scripts/octoscreen index 70af1330..b6910fe4 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -20,10 +20,6 @@ EOL exit; } -[[ ! -f /etc/os-release ]] && echo "ERROR: We kinda need \`/etc/os-release\`, but I couldn't find it. Proooobably means we don't support your system. If you believe this is in error, please file a bug report." && exit 1; -source /etc/os-release -[[ $ID_LIKE != debian ]] && echo "ERROR: Yeah, no." && exit 1; - REPO="Z-Bolt/OctoScreen" MAIN="master" WGET_RAW="https://github.com/$REPO/raw/$MAIN" @@ -51,12 +47,12 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; [[ -z "$SOURCE_FILE" ]] && { echo -en "${CL}Fetching '{$LIBRARY}'..."; source <(curl -s -L "$WGET_RAW/scripts/$LIBRARY"); [[ $? -ne 0 ]] && { echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; continue; }; }; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); [[ $? -ne 0 ]] && { echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; }; done; echo -en "${CL}${CL}"; optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" -optparse.define short=m long=makedir description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has && echo.fatal 'Provide MakeDir AFTER \'build\' " default=$(pwd) -optparse.define short=b long=build description="Build for a specific Release Target [STRETCH|BUSTER|JESSIE]" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit -optparse.define long='nodep' description="Skip installing Apt Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag +optparse.define short=b long=build description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has build || echo.fatal \"Specify MakeDir AFTER 'build'\"; #" default=$(pwd) +optparse.define short=r long=release description="Release Target [STRETCH|BUSTER|JESSIE]" dispatch="octoscreen.tasks.has build || echo.fatal \"Specify Release Target AFTER 'build'\"; #" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit +optparse.define long=nodep description="Skip installing Apt Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag default="false" optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" -#optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag +optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag default="false" optparse.define.single name="install" description="Install/Upgrade OctoScreen" dispatch="octoscreen.tasks.add install" optparse.define.single name="remove" description="Remove OctoScreen" dispatch="octoscreen.tasks.add remove" @@ -73,6 +69,17 @@ function octoscreen.main(){ #Called after all args are parsed local _task_order="docker build lcd remove install" + [[ -f /etc/os-release ]] && { + source /etc/os-release + } || { + $AUTO_FORCE || echo "ERROR: We kinda need \`/etc/os-release\`, but I couldn't find it. Proooobably means we don't support your system. If you believe this is in error, please file a bug report." && exit 1; + }; + + $AUTO_FORCE || { + [[ $ID_LIKE != debian ]] && echo "ERROR: Yeah, no." && exit 1 + }; + + [[ -z "${OCTOSCREEN_TASKS[@]}" ]] && echo.error "Nothing to do. Please give me a purpose in life... I BEG YOU" && octoscreen.maybe.usage; echo "Welcome to the OctoScreen Manager" @@ -158,7 +165,7 @@ function octoscreen.dependencies.install(){ echo.notice "Executing \`$apt update\`" sudo $apt update - [[ ! -z $AUTO_YES ]] && apt+=' -y' + $AUTO_YES && apt+=' -y' echo.notice "Executing \`$apt install ${OCTOSCREEN_DEPENDENCIES[*]}\`" sudo $apt install ${OCTOSCREEN_DEPENDENCIES[*]} @@ -215,7 +222,9 @@ function octoscreen.task.install() { else echo.warn "Unable to determine the OctoScreen Version and Architecture from file: $deb_name" OCTOSCREEN_DEB_VERSION=unknown - list_input "The Package version and Release Architecture were unable to be determined, this may not end well. Would you like to continue?" yes_no force + $AUTO_FORCE && + local force="yes" || + list_input "The Package version and Release Architecture were unable to be determined, this may not end well. Would you like to continue?" yes_no force; if [ $force == 'yes' ]; then echo.warn "We will continue with installation, god speed." SYSTEM_ARCH=unknown @@ -307,7 +316,10 @@ function octoscreen.task.install() { } #? Maybe other tasks? - list_input "Shall I reboot your Pi now?" yes_no reboot + $AUTO_YES && + local reboot="yes" || + list_input "Shall I reboot your Pi now?" yes_no reboot; + if [ $reboot == 'yes' ]; then echo "Your system will now reboot!" sudo reboot @@ -323,16 +335,17 @@ function octoscreen.task.install() { function octoscreen.task.build(){ echo.debug "octoscreen.prepare.build()" + local _start=$SECONDS + [[ ! -z $OCTOSCREEN_DEB ]] && echo.error "Just so you know, we don't support outputting the build to a specific file, so, we won't be changing OCTOSCREEN_DEB ($OCTOSCREEN_DEB), this may mess with your install." ( grep 'PACKAGE_NAME = octoscreen' "$MAKE_DIR/Makefile" >/dev/null 2>&1 ) && - echo.debug "Buildign with Source Directory ($MAKE_DIR)" || + echo.debug "Building with Source Directory ($MAKE_DIR)" || echo.fatal "Make File does not seem to be for OctoScreen"; [[ -d $MAKE_DIR/build ]] && { echo.notice "Clearing the existing \`build\` directory ($MAKE_DIR/build)" - echo.info "Pausing for 5 seconds..." - sleep 5 + $AUTO_YES || echo.info "Pausing for 5 seconds... (press [enter] to continue)" && read -t 5; sudo rm -rf "$MAKE_DIR/build" } @@ -353,9 +366,7 @@ function octoscreen.task.build(){ echo "Building OctoScreen, this may take a bit." - echo.notice "Sleeping for 5 seconds, incase you want to abort..." - - sleep 5 + $AUTO_YES || echo.info "Pausing for 5 seconds... (press [enter] to continue)" && read -t 5; sudo $make_command @@ -363,7 +374,7 @@ function octoscreen.task.build(){ echo.fatal "Make exited unsuccessfully!"; } - echo.notice "Build Complete!" + echo.notice "Build Complete! ($(octoscreen.timer $_start))" BUILT_DEB=$(find $MAKE_DIR/build/ -name "*.deb" -print0 | xargs -r -0 ls -1 -t | head -1) @@ -400,15 +411,16 @@ function octoscreen.set.deb(){ function octoscreen.prepare.install(){ echo.debug "octoscreen.prepare.install()" - local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` + #local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` - echo.notice "Checking to see if OctoScreen is already installed..." + echo.notice "Checking if we can install, or if we need to re-install..." ( $OCTOSCREEN_INSTALLED && ! octoscreen.tasks.has remove ) && { - local question="OctoScreen is already installed. Would you like to re-install it?" + $AUTO_FORCE && + local reinstall="yes" || + list_input "OctoScreen is already installed. Would you like to re-install it?" yes_no reinstall; - list_input "$question" yes_no reinstall if [ $reinstall == 'yes' ]; then echo.notice "Excelent! We will remove and re-install OctoScreen." octoscreen.tasks.add remove @@ -498,12 +510,21 @@ function octoscreen.handle.unknown(){ ### Utility Functions +function octoscreen.timer(){ + local seconds=$1 + let "seconds=SECONDS-seconds" + let "hours=seconds/3600" + let "minutes=(seconds%3600)/60" + let "seconds=(seconds%3600)%60" + printf "%02d:%02d:%02d" $hours $minutes $seconds +} + function octoscreen.tasks.do(){ echo.debug "octoscreen.tasks.do($*)" local did_a_thing=false - [[ -z "$2" ]] && echo.fatal "Task execution requies at least an action AND a task to take it on" && return 1; + [[ -z "$2" ]] && echo.fatal "Task execution requies an action and atgleast one task to take it on" && return 1; [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; local do="$1"; shift; @@ -537,13 +558,17 @@ function octoscreen.tasks.has(){ echo.debug "octoscreen.tasks.has($1)" [[ -z "$1" ]] && echo.error "You can't search for nothing, that's bad, m'kay?" && return 1; [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; - echo.debug "Checking for OCTOSCREEN_TASK '$task' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'" + echo.debug "Checking for OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[*]}'" + local _IFS=$IFS if ( dlm=$'\x1F' ; IFS="$dlm" ; [[ "$dlm${OCTOSCREEN_TASKS[*]}$dlm" == *"$dlm${1}$dlm"* ]] ) ; then - echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[@]}'"; + IFS=$_IFS + echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[*]}'"; return 0; else + IFS=$_IFS echo.debug "task not found"; fi + IFS=$_IFS return 1 } @@ -598,4 +623,4 @@ function echo.chatty(){ echo -e "$message" } -. <( optparse.build name=$([[ "$DIR" =~ /proc/* ]] && echo '' || basename $0) description="OctoScreen Manager" allow=positional finally=octoscreen.main allow=unrecognized usage_header="${optparse_usage_header} command [command ...] [*.deb]") +. <( optparse.build name=$([[ "$DIR" =~ /proc/* ]] && echo '' || basename $0) description="OctoScreen Manager" finally=octoscreen.main usage_header="${optparse_usage_header} command [command ...] [*.deb]") From daff3ea807bebf96b7855218d819a280f99ed4ed Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:00:17 +0000 Subject: [PATCH 26/61] Install CLI along with DEB --- debian/octoscreen.postinst | 4 ++++ debian/rules | 2 ++ 2 files changed, 6 insertions(+) diff --git a/debian/octoscreen.postinst b/debian/octoscreen.postinst index 6e130764..97ca6095 100755 --- a/debian/octoscreen.postinst +++ b/debian/octoscreen.postinst @@ -45,6 +45,10 @@ if [ "$1" = configure ] && [ -d /etc/systemd/system/ ]; then fi fi +# Install the octoscreen CLI +if [ "$1" = configure ] && [ -d /usr/local/bin/ ]; then + ln -sf /etc/octoscreen/scripts/octoscreen /usr/local/bin/octoscreen +fi db_stop || true #DEBHELPER# diff --git a/debian/rules b/debian/rules index 55088c60..230649fb 100755 --- a/debian/rules +++ b/debian/rules @@ -25,6 +25,8 @@ override_dh_golang: override_dh_install: mkdir -p $(CURDIR)/debian/octoscreen/opt/octoscreen/ cp -r styles $(CURDIR)/debian/octoscreen/opt/octoscreen/ + mkdir -p $(CURDIR)/debian/local/octoscreen/scripts/ + cp -r scripts $(CURDIR)/debian/local/octoscreen/ rm -rf $(CURDIR)/debian/octoscreen/usr/share/gocode dh_install -XLICENSE From 0ffc22bc80949be1b6b6b287b67d247d864f0d57 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:02:17 +0000 Subject: [PATCH 27/61] My test --- scripts/octoscreen | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index b6910fe4..c37b2818 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -20,8 +20,8 @@ EOL exit; } -REPO="Z-Bolt/OctoScreen" -MAIN="master" +REPO="thebeline/OctoScreen" +MAIN="me_test" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("lib/optparse.bash" "lib/inquirer.bash" "lib/verbosity.bash") PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; From 80f5631a0bb4f83e28079de5bf8c68d8d64e9c8a Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:18:09 +0000 Subject: [PATCH 28/61] Wrong var and --nodep check --- scripts/octoscreen | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index b6910fe4..9689bb23 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -120,7 +120,7 @@ function octoscreen.dependencies.install(){ echo.debug "${dependency_count} dependencies queued to install: ${OCTOSCREEN_DEPENDENCIES[*]}" - [[ ! -z $SKIP_DEPENDENCIES ]] && echo.notice "Skipping dependencies per user request" && return 0 + $SKIP_DEPENDENCIES && echo.notice "Skipping dependencies per user request" && return 0 #local _apt_list_installed=() # @@ -190,7 +190,7 @@ function octoscreen.task.install() { local RELEASE_URL=$(curl -s "$RELEASES" | grep "browser_download_url.$RELEASE_ARCH" | cut -d '"' -f 4); - [[ -z "$RELEASE_URL" ]] && echo.fatal "Unable to find correct package for your Architecture (${arch})" + [[ -z "$RELEASE_URL" ]] && echo.fatal "Unable to find correct package for your Architecture (${SYSTEM_ARCH})" echo.info "Found matching Package URL: $RELEASE_URL" From 2ab0542502f7939677033203f83e78c59428b283 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:18:41 +0000 Subject: [PATCH 29/61] Docker Installer wasn't checking for failure --- scripts/octoscreen | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 9689bb23..ed8f6588 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -453,18 +453,25 @@ function octoscreen.prepare.remove(){ function octoscreen.task.docker(){ echo "Installing Docker... This may take a while..." - echo.warn "If this hangs on 'Scanning something something something...' just hit enter, should be good..." local _docker='~/get-docker.sh' + local _quiet='' + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _quiet+=' >/dev/null 2>&1' + + curl -fsSL get.docker.com -o $_docker $_quiet - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _docker+=' >/dev/null 2>&1' + [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" + + echo.warn "If this hangs on 'Scanning something something something...' just hit enter, should be good..." declare -g CHANNEL='stable' declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' - curl -fsSL get.docker.com -o $_docker - sh $_docker + sh $_docker $_quiet + + [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } function octoscreen.prepare.build(){ From 6f045aaf344fdb96940f3474d815d1707f1dd905 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:21:18 +0000 Subject: [PATCH 30/61] dock? --- scripts/octoscreen | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 92ea13ef..d561fca3 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -20,8 +20,8 @@ EOL exit; } -REPO="thebeline/OctoScreen" -MAIN="me_test" +REPO="Z-Bolt/OctoScreen" +MAIN="master" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("lib/optparse.bash" "lib/inquirer.bash" "lib/verbosity.bash") PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; @@ -459,7 +459,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _quiet+=' >/dev/null 2>&1' - curl -fsSL get.docker.com -o $_docker $_quiet + curl -fsSL get.docker.com -o "$_docker" $_quiet [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" From 500e8a62712ef5dfbd5f32d14d84125ad6162132 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:46:21 +0000 Subject: [PATCH 31/61] dock? --- scripts/octoscreen | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index d561fca3..c3fcf52d 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -20,8 +20,8 @@ EOL exit; } -REPO="Z-Bolt/OctoScreen" -MAIN="master" +REPO="thebeline/OctoScreen" +MAIN="me_test" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("lib/optparse.bash" "lib/inquirer.bash" "lib/verbosity.bash") PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; @@ -454,12 +454,20 @@ function octoscreen.prepare.remove(){ function octoscreen.task.docker(){ echo "Installing Docker... This may take a while..." - local _docker='~/get-docker.sh' - local _quiet='' + local _curl='curl -fsSL' - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _quiet+=' >/dev/null 2>&1' + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v' - curl -fsSL get.docker.com -o "$_docker" $_quiet + _curl+=' get.docker.com'; + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && { + _curl+=' 2>/dev/null' + _docker+=' > /dev/null 2>&1' + } + + echo.debug "Fetching Docker install '$_curl'" + + _docker=<( $_curl $_quiet ) [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" @@ -469,7 +477,7 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' - sh $_docker $_quiet + sh $_docker [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } From 05221cf1668fcd4417e66d6f19261382915f77a6 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:53:05 +0000 Subject: [PATCH 32/61] dock? --- scripts/octoscreen | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index c3fcf52d..b28298f7 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -454,22 +454,29 @@ function octoscreen.prepare.remove(){ function octoscreen.task.docker(){ echo "Installing Docker... This may take a while..." - local _curl='curl -fsSL' + local _docker="~/get_docker.sh" - [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v' - - _curl+=' get.docker.com'; - - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && { - _curl+=' 2>/dev/null' - _docker+=' > /dev/null 2>&1' - } - - echo.debug "Fetching Docker install '$_curl'" - - _docker=<( $_curl $_quiet ) - - [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" + [[ ! -f $_docker ]] && { + + echo.notice "Fetching Docker Install Script" + + local _curl='curl -fsSL' + + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && + _curl+='v'; + + _curl+=' get.docker.com'; + + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && + _curl+=' > $_docker_file 2>/dev/null'; + + echo.debug "Fetching Docker install '$_curl'" + + $_curl $_quiet + + [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" + + } || echo.notice "Docker Install Script exists, using that." echo.warn "If this hangs on 'Scanning something something something...' just hit enter, should be good..." @@ -477,6 +484,9 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && + _docker+=' > /dev/null 2>&1'; + sh $_docker [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." From fb384b75c402c21e8f9945d473a963212100455a Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:54:03 +0000 Subject: [PATCH 33/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index b28298f7..380543f0 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -468,7 +468,7 @@ function octoscreen.task.docker(){ _curl+=' get.docker.com'; [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && - _curl+=' > $_docker_file 2>/dev/null'; + _curl+=' > $_docker 2>/dev/null'; echo.debug "Fetching Docker install '$_curl'" From fe96f8619040adec8ebb70516f14ce4690d0632a Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:54:58 +0000 Subject: [PATCH 34/61] dock? --- scripts/octoscreen | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 380543f0..21ac986c 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -465,10 +465,10 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v'; - _curl+=' get.docker.com'; + _curl+=' get.docker.com > $_docker'; [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && - _curl+=' > $_docker 2>/dev/null'; + _curl+=' 2>/dev/null'; echo.debug "Fetching Docker install '$_curl'" From 8d867fe10877223c720c4aa7e9c0cbebf0ecde6e Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:56:04 +0000 Subject: [PATCH 35/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 21ac986c..ffd00a64 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -472,7 +472,7 @@ function octoscreen.task.docker(){ echo.debug "Fetching Docker install '$_curl'" - $_curl $_quiet + $_curl [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" From 6d83d3b96a728290de9258bd43c746ba87a901e2 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:57:03 +0000 Subject: [PATCH 36/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index ffd00a64..8b1e1b6a 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -470,7 +470,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _curl+=' 2>/dev/null'; - echo.debug "Fetching Docker install '$_curl'" + echo.debug "Fetching Docker Install Script ($_curl)" $_curl From 70c3676637bee6c6ec6adf31157250a0a0e9fb6b Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 20:57:57 +0000 Subject: [PATCH 37/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 8b1e1b6a..fff39c0f 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -470,7 +470,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _curl+=' 2>/dev/null'; - echo.debug "Fetching Docker Install Script ($_curl)" + echo.debug "Executing Curl ($_curl)" $_curl From 17589e306174e13a1cc68fcb2ce5f5ee00dfad1f Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:00:05 +0000 Subject: [PATCH 38/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index fff39c0f..27860db6 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -465,7 +465,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v'; - _curl+=' get.docker.com > $_docker'; + _curl+=" get.docker.com > $_docker"; [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _curl+=' 2>/dev/null'; From 9415c05819ceb761b1a95be0a29ce05499fbfbec Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:08:58 +0000 Subject: [PATCH 39/61] dock? --- scripts/octoscreen | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 27860db6..b7eeb27f 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -465,14 +465,14 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v'; - _curl+=" get.docker.com > $_docker"; + _curl+=" get.docker.com"; [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _curl+=' 2>/dev/null'; echo.debug "Executing Curl ($_curl)" - $_curl + (( $_curl > $_docker )) [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" @@ -487,7 +487,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _docker+=' > /dev/null 2>&1'; - sh $_docker + (( sh $_docker )) [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } From 3917b18b9120291e4436a7b2fec5fa9bd7b6d5e2 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:10:12 +0000 Subject: [PATCH 40/61] dock? --- scripts/octoscreen | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index b7eeb27f..30b0e52d 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -472,7 +472,7 @@ function octoscreen.task.docker(){ echo.debug "Executing Curl ($_curl)" - (( $_curl > $_docker )) + ( $_curl > $_docker ) [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" @@ -487,7 +487,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _docker+=' > /dev/null 2>&1'; - (( sh $_docker )) + ( sh $_docker ) [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } From 70f609216ec8d9f93a1c6a13d9d8647e2e5d130e Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:25:18 +0000 Subject: [PATCH 41/61] dock? --- scripts/octoscreen | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 30b0e52d..84d8a083 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -460,19 +460,19 @@ function octoscreen.task.docker(){ echo.notice "Fetching Docker Install Script" - local _curl='curl -fsSL' + local _wget='curl -fsSL' [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v'; - _curl+=" get.docker.com"; + _curl+=" get.docker.com -o $_docker"; [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _curl+=' 2>/dev/null'; echo.debug "Executing Curl ($_curl)" - ( $_curl > $_docker ) + $_curl [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" From a4993396d42dd01266517918582ad95b21cae1d9 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:27:27 +0000 Subject: [PATCH 42/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 84d8a083..e2e650ea 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -460,7 +460,7 @@ function octoscreen.task.docker(){ echo.notice "Fetching Docker Install Script" - local _wget='curl -fsSL' + local _curl='curl -fsSL' [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _curl+='v'; From 708f31456e618704b30aa465012db79f792bb632 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:30:14 +0000 Subject: [PATCH 43/61] dock? --- scripts/octoscreen | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index e2e650ea..dcc31e7f 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -456,6 +456,9 @@ function octoscreen.task.docker(){ local _docker="~/get_docker.sh" + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && + _docker+=' > /dev/null 2>&1'; + [[ ! -f $_docker ]] && { echo.notice "Fetching Docker Install Script" @@ -467,9 +470,6 @@ function octoscreen.task.docker(){ _curl+=" get.docker.com -o $_docker"; - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && - _curl+=' 2>/dev/null'; - echo.debug "Executing Curl ($_curl)" $_curl @@ -484,10 +484,7 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && - _docker+=' > /dev/null 2>&1'; - - ( sh $_docker ) + sh $_docker [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } From b6f8b7c9b6f7acb9b8b9c454905c8614388fab24 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:35:38 +0000 Subject: [PATCH 44/61] dock? --- scripts/octoscreen | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index dcc31e7f..f2b83a2c 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -472,7 +472,7 @@ function octoscreen.task.docker(){ echo.debug "Executing Curl ($_curl)" - $_curl + `$_curl` [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" @@ -484,7 +484,7 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' - sh $_docker + `sh $_docker` [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } From 288b72056755c27b2f6cc254e2fc7f9f83608e8e Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:36:30 +0000 Subject: [PATCH 45/61] dock? --- scripts/octoscreen | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index f2b83a2c..19220759 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -470,7 +470,7 @@ function octoscreen.task.docker(){ _curl+=" get.docker.com -o $_docker"; - echo.debug "Executing Curl ($_curl)" + echo.debug "Executing Curl (\`$_curl\`)" `$_curl` @@ -484,6 +484,8 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' + echo.debug "Executing Docker (\`$_docker\`)" + `sh $_docker` [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." From f41e0593e84a4001cb855dab0b7452f0fdcd1fc2 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:48:11 +0000 Subject: [PATCH 46/61] dock? --- scripts/octoscreen | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 19220759..3066f37b 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -463,18 +463,18 @@ function octoscreen.task.docker(){ echo.notice "Fetching Docker Install Script" - local _curl='curl -fsSL' + local wget='wget ' [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && - _curl+='v'; + _wget+='-v '; - _curl+=" get.docker.com -o $_docker"; + _wget+="get.docker.com -O $_docker"; - echo.debug "Executing Curl (\`$_curl\`)" + echo.debug "Executing WGET (\`$_wget\`)" - `$_curl` + `$_wget` - [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" + [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error Fetching (\`$_wget\`)" } || echo.notice "Docker Install Script exists, using that." From b298c37f2091799723ee058e67f0262a6a6cfa92 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 21:49:00 +0000 Subject: [PATCH 47/61] dock? --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 3066f37b..fe140131 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -463,7 +463,7 @@ function octoscreen.task.docker(){ echo.notice "Fetching Docker Install Script" - local wget='wget ' + local _wget='wget ' [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _wget+='-v '; From 5c9ee7c988b73168a6e6e91d40b5a83846ee54f3 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 22:11:50 +0000 Subject: [PATCH 48/61] grrrr --- scripts/octoscreen | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index fe140131..b4867079 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -19,7 +19,7 @@ EOL } || echo.error "Can't display License when quiet..." exit; } - +_IFS=$IFS REPO="thebeline/OctoScreen" MAIN="me_test" WGET_RAW="https://github.com/$REPO/raw/$MAIN" @@ -454,10 +454,11 @@ function octoscreen.prepare.remove(){ function octoscreen.task.docker(){ echo "Installing Docker... This may take a while..." - local _docker="~/get_docker.sh" + local _docker=$(mktemp) + local _quiet='' [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && - _docker+=' > /dev/null 2>&1'; + _quiet='> /dev/null 2>&1'; [[ ! -f $_docker ]] && { @@ -468,7 +469,7 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && _wget+='-v '; - _wget+="get.docker.com -O $_docker"; + _wget+="-O $_docker get.docker.com $_quiet"; echo.debug "Executing WGET (\`$_wget\`)" @@ -484,14 +485,15 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' - echo.debug "Executing Docker (\`$_docker\`)" + echo.debug "Executing Docker (\`$_docker $_quiet\`)" - `sh $_docker` + sh $_docker $_quiet [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } function octoscreen.prepare.build(){ + IFS=$_IFS echo.debug "octoscreen.prepare.build()" @@ -583,7 +585,6 @@ function octoscreen.tasks.has(){ [[ -z "$1" ]] && echo.error "You can't search for nothing, that's bad, m'kay?" && return 1; [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; echo.debug "Checking for OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[*]}'" - local _IFS=$IFS if ( dlm=$'\x1F' ; IFS="$dlm" ; [[ "$dlm${OCTOSCREEN_TASKS[*]}$dlm" == *"$dlm${1}$dlm"* ]] ) ; then IFS=$_IFS echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[*]}'"; From d9a05c35c467054c1e5b8ec27f7d55b14824b9e4 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 22:13:05 +0000 Subject: [PATCH 49/61] grrrr --- scripts/octoscreen | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index b4867079..14a64b7d 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -459,25 +459,21 @@ function octoscreen.task.docker(){ [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _quiet='> /dev/null 2>&1'; + + echo.notice "Fetching Docker Install Script" - [[ ! -f $_docker ]] && { - - echo.notice "Fetching Docker Install Script" - - local _wget='wget ' - - [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && - _wget+='-v '; - - _wget+="-O $_docker get.docker.com $_quiet"; - - echo.debug "Executing WGET (\`$_wget\`)" - - `$_wget` - - [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error Fetching (\`$_wget\`)" - - } || echo.notice "Docker Install Script exists, using that." + local _wget='wget ' + + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && + _wget+='-v '; + + _wget+="-O $_docker get.docker.com $_quiet"; + + echo.debug "Executing WGET (\`$_wget\`)" + + `$_wget` + + [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error Fetching (\`$_wget\`)" echo.warn "If this hangs on 'Scanning something something something...' just hit enter, should be good..." From cd2071fbfad6e0928a88cfd7c7a4b7c3b11e022d Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 12 Mar 2021 23:29:38 +0000 Subject: [PATCH 50/61] Yeah, something was buggy here, all fixed now, though --- scripts/octoscreen | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index ed8f6588..71bcdbd5 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -19,7 +19,7 @@ EOL } || echo.error "Can't display License when quiet..." exit; } - +_IFS=$IFS REPO="Z-Bolt/OctoScreen" MAIN="master" WGET_RAW="https://github.com/$REPO/raw/$MAIN" @@ -454,14 +454,26 @@ function octoscreen.prepare.remove(){ function octoscreen.task.docker(){ echo "Installing Docker... This may take a while..." - local _docker='~/get-docker.sh' + local _docker=$(mktemp) local _quiet='' - [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && _quiet+=' >/dev/null 2>&1' + [[ $VERBOSITY_CURRENT -lt $VERBOSITY_NOTICE ]] && + _quiet='> /dev/null 2>&1'; + + echo.notice "Fetching Docker Install Script" + + local _wget='wget ' + + [[ $VERBOSITY_CURRENT -ge $VERBOSITY_DEBUG ]] && + _wget+='-v '; - curl -fsSL get.docker.com -o $_docker $_quiet + _wget+="-O $_docker get.docker.com $_quiet"; - [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error fetching '$_docker'" + echo.debug "Executing WGET (\`$_wget\`)" + + `$_wget` + + [[ $? -ne 0 || ! -f $_docker ]] && echo.fatal "Error Fetching (\`$_wget\`)" echo.warn "If this hangs on 'Scanning something something something...' just hit enter, should be good..." @@ -469,12 +481,15 @@ function octoscreen.task.docker(){ declare -g DOWNLOAD_URL='' declare -g REPO_FILE='' + echo.debug "Executing Docker (\`$_docker $_quiet\`)" + sh $_docker $_quiet [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } function octoscreen.prepare.build(){ + IFS=$_IFS echo.debug "octoscreen.prepare.build()" @@ -566,7 +581,6 @@ function octoscreen.tasks.has(){ [[ -z "$1" ]] && echo.error "You can't search for nothing, that's bad, m'kay?" && return 1; [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; echo.debug "Checking for OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[*]}'" - local _IFS=$IFS if ( dlm=$'\x1F' ; IFS="$dlm" ; [[ "$dlm${OCTOSCREEN_TASKS[*]}$dlm" == *"$dlm${1}$dlm"* ]] ) ; then IFS=$_IFS echo.debug "Found OCTOSCREEN_TASK '$1' in OCTOSCREEN_TASKS '${OCTOSCREEN_TASKS[*]}'"; From f638817c084027e4d87cc3705a3aadea1b955d4b Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 20:13:30 +0000 Subject: [PATCH 51/61] Re-organized the CLI for readbility...ish --- scripts/octoscreen | 234 ++++++++++++++++++++++++++++----------------- 1 file changed, 148 insertions(+), 86 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 71bcdbd5..5b23a09c 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -67,6 +67,7 @@ echo.verbosity.init_optparse 0 function octoscreen.main(){ #Called after all args are parsed + # Tasks have to occur in an order, so we do them in order, no matter how they were passed. local _task_order="docker build lcd remove install" [[ -f /etc/os-release ]] && { @@ -100,12 +101,13 @@ function octoscreen.main(){ #Called after all args are parsed echo.chatty "We check them in the following order: $_task_order[@]" echo.chatty "First we execute and available \`prepare\` commands, then we install any registered dependencies, and then we execute the task it's self." - octoscreen.tasks.do prepare $_task_order + octoscreen.tasks.do init $_task_order [[ $? -eq 0 ]] && octoscreen.dependencies.install - # Tasks have to occur in an order, so we do them in order, no matter how they were passed. - [[ $? -eq 0 ]] && octoscreen.tasks.do task $_task_order + [[ $? -eq 0 ]] && octoscreen.tasks.do main $_task_order + + [[ $? -eq 0 ]] && octoscreen.tasks.do finish $_task_order [[ $? -eq 0 ]] || echo.fatal "Unknown error. ($?)" @@ -173,7 +175,54 @@ function octoscreen.dependencies.install(){ true } -function octoscreen.task.install() { + +############################################################################### +# Begin TASKS +############################################################################### + +############################################################################### +# Install Task +# +# Handles instalation of either a specified DEB package, or the latest release. +# +# Additionally handles "updating" or reinstalling via checking if OctoScreen is +# already installed. +# +# Dev Notes: At some point it MAY be bennificial for this to parse out the full +# set of available releases and provide the option for the user to select a +# non-recent release, or specify a specific version at the CLI and validate +# and select against the available releases. + +function octoscreen.task.install.init(){ + echo.debug "octoscreen.task.install.init()" + + #local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` + + echo.notice "Checking if we can install, or if we need to re-install..." + + ( $OCTOSCREEN_INSTALLED && ! octoscreen.tasks.has remove ) && { + + $AUTO_FORCE && + local reinstall="yes" || + list_input "OctoScreen is already installed. Would you like to re-install it?" yes_no reinstall; + + if [ $reinstall == 'yes' ]; then + echo.notice "Excelent! We will remove and re-install OctoScreen." + octoscreen.tasks.add remove + else + echo "OctoScreen is already installed, exiting." && exit + fi + } + + ### + # This really SHOULDN'T be nessesary, as the DEB should include these as + # dependencies, but this was in the install guide at the time this was + # developed, so it is here for now. + ### + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils +} + +function octoscreen.task.install.main() { local version_regex='' local deb_name='' @@ -253,7 +302,11 @@ function octoscreen.task.install() { exit 1 fi; - + ### + # This was from the install script this was ORIGINALLY based off from + # but it would be benificial to allow installing Plug-Ins, so it is + # left here for reference. + ### #if [ $DIRECTORY != "-" ]; then # plugins=( 'Display Layer Progress (mandatory)' 'Filament Manager' 'Preheat Button' 'Enclosure' 'Print Time Genius' 'Ultimaker Format Package' 'PrusaSlicer Thumbnails' ) # checkbox_input "Which plugins should I install (you can also install them via the Octoprint UI)?" plugins selected_plugins @@ -315,6 +368,9 @@ function octoscreen.task.install() { trap - EXIT } +} + +function octoscreen.task.install.finish() { #? Maybe other tasks? $AUTO_YES && local reboot="yes" || @@ -328,12 +384,48 @@ function octoscreen.task.install() { sudo service octoscreen start echo "OctoScreen has been successfully installed! Have a great day!" fi +} + +############################################################################### +# Build OctoScreen from Source +# +# Builds from the specified source directory. +# +# Dev Notes: Due to a certain dev being dumb, this currently executes `build` +# as `root` which is... Not great. Avoid using `sudo` when you can, and all. +# A better way would be to correctly set up `docker` so the current user can +# build WITHOUT `sudo`. For another day, perhaps. +# +# Also, balks if you specify a DEB. Pretty sure that is desired behaviour. + +function octoscreen.task.build.init(){ + + echo.debug "octoscreen.task.build.init()" + IFS=$_IFS + + [[ -z $VERSION_CODENAME ]] && echo.fatal "Unable to determine a Release Target (see --help)" + VERSION_CODENAME=${VERSION_CODENAME^^} + + [[ -z $MAKE_DIR ]] && echo.fatal "No Make Directory provided" + [[ -d $MAKE_DIR ]] || echo.fatal "Specified Make Directory is not a directory: $MAKE_DIR" + + while [[ -d $MAKE_DIR ]] && [[ ! -f $MAKE_DIR/Makefile ]]; do + echo.debug "$MAKE_DIR does not seem like a valid Make directory. Looking up." + local _make_dir=$( dirname $MAKE_DIR ) + [[ "$_make_dir" == "$MAKE_DIR" ]] && echo.debug "Looks like we are looping, breaking" && break; + MAKE_DIR=$_make_dir; + done + + [[ -f $MAKE_DIR/Makefile ]] && + echo.info "Found $MAKE_DIR/Makefile" || + echo.fatal "No Make File found in ($MAKE_DIR)"; + + octoscreen.task.docker.init - exit #? Maybe other tasks? } -function octoscreen.task.build(){ - echo.debug "octoscreen.prepare.build()" +function octoscreen.task.build.main(){ + echo.debug "octoscreen.task.build.main()" local _start=$SECONDS @@ -391,48 +483,17 @@ function octoscreen.task.build(){ } -function octoscreen.task.lcd(){ - echo.fatal "Installing the LCD is not implemented yet" - : -} +############################################################################### +# Remove/Uninstall OctoScreen -### Task Preparation Functions - -function octoscreen.set.deb(){ - - # wondering if we should do any checks here... - # thinking they should be done in build/instal - - !( octoscreen.tasks.has install ) && echo.warn "The target *.deb file SHOULD be specified after \`install\`" - - OCTOSCREEN_DEB="$1"; -} - -function octoscreen.prepare.install(){ - echo.debug "octoscreen.prepare.install()" - - #local found=`dpkg -l octoscreen | grep -oE "^(i|r)[^ ]+ "` - - echo.notice "Checking if we can install, or if we need to re-install..." - - ( $OCTOSCREEN_INSTALLED && ! octoscreen.tasks.has remove ) && { - - $AUTO_FORCE && - local reinstall="yes" || - list_input "OctoScreen is already installed. Would you like to re-install it?" yes_no reinstall; - - if [ $reinstall == 'yes' ]; then - echo.notice "Excelent! We will remove and re-install OctoScreen." - octoscreen.tasks.add remove - else - echo "OctoScreen is already installed, exiting." && exit - fi +function octoscreen.task.remove.init(){ + $OCTOSCREEN_INSTALLED || { + echo.error "OctoScreen is not installed, nothing to do" + octoscreen.tasks.remove remove } - - octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils } -function octoscreen.task.remove(){ +function octoscreen.task.remove.main(){ echo.notice "Removing OctoScreen" @@ -444,14 +505,35 @@ function octoscreen.task.remove(){ } -function octoscreen.prepare.remove(){ - $OCTOSCREEN_INSTALLED || { - echo.error "OctoScreen is not installed, nothing to do" - octoscreen.tasks.remove remove - } +############################################################################### +# Install/Configure LCD Screen + +function octoscreen.task.lcd.init(){ + echo.debug "octoscreen.task.lcd.init()" + echo.fatal "Installing the LCD is not implemented yet" + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils + : +} + +function octoscreen.task.lcd.main(){ + : +} + +############################################################################### +# Install and configure Docker +# This currently doesn't + +function octoscreen.task.docker.init() { + if command -v "docker" > /dev/null 2>&1; then + echo.debug "Docker is already installed." + octoscreen.tasks.has docker || octoscreen.tasks.remove docker + else + echo.debug "Docker is not installed." + octoscreen.tasks.has docker && octoscreen.tasks.add docker + fi } -function octoscreen.task.docker(){ +function octoscreen.task.docker.main(){ echo "Installing Docker... This may take a while..." local _docker=$(mktemp) @@ -488,40 +570,23 @@ function octoscreen.task.docker(){ [[ $? -ne 0 ]] && echo.fatal "Docker Installer exited Unsucessfully." } -function octoscreen.prepare.build(){ - IFS=$_IFS - - echo.debug "octoscreen.prepare.build()" - - [[ -z $VERSION_CODENAME ]] && echo.fatal "Unable to determine a Release Target (see --help)" - VERSION_CODENAME=${VERSION_CODENAME^^} - - [[ -z $MAKE_DIR ]] && echo.fatal "No Make Directory provided" - [[ -d $MAKE_DIR ]] || echo.fatal "Specified Make Directory is not a directory: $MAKE_DIR" - - while [[ -d $MAKE_DIR ]] && [[ ! -f $MAKE_DIR/Makefile ]]; do - echo.debug "$MAKE_DIR does not seem like a valid Make directory. Looking up." - local _make_dir=$( dirname $MAKE_DIR ) - [[ "$_make_dir" == "$MAKE_DIR" ]] && echo.debug "Looks like we are looping, breaking" && break; - MAKE_DIR=$_make_dir; - done - - [[ -f $MAKE_DIR/Makefile ]] && - echo.info "Found $MAKE_DIR/Makefile" || - echo.fatal "No Make File found in ($MAKE_DIR)"; + + + + + +############################################################################### +# Begin UTILITY FUNCTIONS +############################################################################### + +function octoscreen.set.deb(){ - command -v "docker" > /dev/null 2>&1 && - echo.debug "Docker IS installed." || - octoscreen.tasks.add docker; + # wondering if we should do any checks here... + # thinking they should be done in build/install - # need to recall what the dependencies are... - # octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils + !( octoscreen.tasks.has install ) && echo.warn "The target *.deb file SHOULD be specified after \`install\`" -} - -function octoscreen.prepare.lcd(){ - echo.debug "octoscreen.prepare.lcd()" - octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils + OCTOSCREEN_DEB="$1"; } function octoscreen.handle.unknown(){ @@ -529,9 +594,6 @@ function octoscreen.handle.unknown(){ octoscreen.maybe.usage } - -### Utility Functions - function octoscreen.timer(){ local seconds=$1 let "seconds=SECONDS-seconds" From bfa537d6ced6e46a9036b9e01b196acfe8f9458b Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 20:16:40 +0000 Subject: [PATCH 52/61] Changed the order, so LCD has priority. --- scripts/octoscreen | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 5b23a09c..c415fad1 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -68,7 +68,7 @@ echo.verbosity.init_optparse 0 function octoscreen.main(){ #Called after all args are parsed # Tasks have to occur in an order, so we do them in order, no matter how they were passed. - local _task_order="docker build lcd remove install" + local _task_order="lcd docker build remove install" [[ -f /etc/os-release ]] && { source /etc/os-release @@ -107,7 +107,7 @@ function octoscreen.main(){ #Called after all args are parsed [[ $? -eq 0 ]] && octoscreen.tasks.do main $_task_order - [[ $? -eq 0 ]] && octoscreen.tasks.do finish $_task_order + [[ $? -eq 0 ]] && octoscreen.tasks.do finally $_task_order [[ $? -eq 0 ]] || echo.fatal "Unknown error. ($?)" @@ -370,7 +370,7 @@ function octoscreen.task.install.main() { } -function octoscreen.task.install.finish() { +function octoscreen.task.install.finally() { #? Maybe other tasks? $AUTO_YES && local reboot="yes" || @@ -519,6 +519,10 @@ function octoscreen.task.lcd.main(){ : } +function octoscreen.task.lcd.finally(){ + : +} + ############################################################################### # Install and configure Docker # This currently doesn't From 5a5d919e9860b2f7a26f94c804cfecb3fee82cdb Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 21:28:23 +0000 Subject: [PATCH 53/61] Added the LCD installer. --- scripts/octoscreen | 100 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index c415fad1..4c718bd9 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -94,6 +94,8 @@ function octoscreen.main(){ #Called after all args are parsed $OCTOSCREEN_INSTALLED && [[ "${found:1:1}" != "i" ]] && ! octoscreen.tasks.has remove && echo.warn "OctoScreen is KINDA installed, but it is in a bad way. We suggest re-installing." + # ALSO a bad way: Having `default.target` exist. + # sudo rm -rf /etc/systemd/system/default.target echo.info "Beginning Task List" @@ -510,17 +512,105 @@ function octoscreen.task.remove.main(){ function octoscreen.task.lcd.init(){ echo.debug "octoscreen.task.lcd.init()" - echo.fatal "Installing the LCD is not implemented yet" - octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils - : + octoscreen.dependencies.add libgtk-3-0 xserver-xorg xinit x11-xserver-utils git build-essential xorg-dev xutils-dev x11proto-dri2-dev libltdl-dev libtool automake libdrm-dev } function octoscreen.task.lcd.main(){ - : + + local __pwd=$(pwd) + local __install_waveshare=true + local __install_fbturbo=true + + #check if LCD SHOW IS ALREADY INSTALLED, SKIP IF SO + if ls /boot/overlays/waveshare*.dtbo > /dev/null 2>&1; then + __install_waveshare=false + fi + + # /boot/overlays/waveshare*.dtbo + + $__install_waveshare && { + [[ -d LCD-show ]] || { + echo "Cloning LCD-show"; + git clone https://github.com/waveshare/LCD-show.git; + } + + [[ -d LCD-show ]] || + echo.fatal "Unable to clone LCD-show"; + + { chmod 755 LCD-show/* && cd LCD-show/; } || + echo.fatal "Failed to set permissions and enter LCD-show."; + + echo "Executing LCD-show" + # This WOULD be the option to NOT reboot, but... Alas, looks like we need it + #systemd-inhibit sudo bash ./LCD35-show + + # ALLLLLLL OF THIS NEEDS OPTIONS + sudo bash ./LCD35-show + ## System will now reboot, we need to do something about this, I'll figure something out... + + # MOOT, as system will reboot, but for feels, I'll spell it out + cd $__pwd + sudo reboot now + } || { + echo.notice "Waveshare is installed. Skipping." + } + + # Check is FBTurbo is installed, and skip if so + if [[ -f /usr/share/X11/xorg.conf.d/99-fbturbo.conf || -f /usr/share/X11/xorg.conf.d/99-calibration.conf]]; then + __install_fbturbo=false + fi + + $__install_fbturbo && { + [[ -d xf86-video-fbturbo ]] || { + echo "Cloning FBTurbo."; + git clone https://github.com/ssvb/xf86-video-fbturbo.git; + } + + [[ -d xf86-video-fbturbo ]] || + echo.fatal "Failed cloning FBTurbo."; + + cd xf86-video-fbturbo + + { autoreconf -vi && ./configure --prefix=/usr && make; } || + echo.fatal "Failed to build FBTurbo."; + + sudo sh -c 'make install && cp xorg.conf /etc/X11/xorg.conf' || + echo.fatal "Failed to Install X11 or copy X11 Configuration"; + + cd $__pwd + + # Does not reboot, nor does it need to. + # Continue + } || { + echo.notice "FBTurbo is installed. Skipping." + } + + local __res=$(xrandr -d :0.0 2>/dev/null | grep -oP "(?<=current )[0-9]+ x [0-9]+") + read -r -a __res <<< "$__res" + + if [[ ${__res[0]} < 548 ]] || [[ ${__res[2]} < 348 ]]; then + + echo.info "Configuring the /boot/config.txt for small screens." + + # The 800x533 thing is really only needed for small resolutions... Whatever the 3.5 is, I think + sudo sh -c 'cp /boot/config.txt /boot/config.txt.bak && \ + sed -i -re "s/^\w*(hdmi_cvt.*)$/#\1/g" /boot/config.txt && \ + echo "hdmi_cvt=800 533 60 6 0 0 0" >> /boot/config.txt' || { + echo.fatal "Failed to configure Boot Config."; + } + + fi + } function octoscreen.task.lcd.finally(){ - : + # Note about re-running/configuring raspicam + echo.warn "If you are using a Raspberry Pi Camera Module (RaspiCam), you will need to re-activate it using \`raspi-config\`" + # Or maybe detect, if we can, and execute `raspi-config` automatically? + + + # also maybe fix the resolutiion in the config, if we did that in the `main`? + # sed -i -re "s/^\w*(OCTOSCREEN_RESOLUTION.*)$/OCTOSCREEN_RESOLUTION=800x533/g" /etc/octoscreen/config } ############################################################################### From bf8bc9fad29c605d95bbdeadb7860c3877759d6f Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 21:43:41 +0000 Subject: [PATCH 54/61] Added the LCD flag for installing LCD drivers. --- scripts/octoscreen | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 4c718bd9..c96ff7b9 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -47,9 +47,10 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; [[ -z "$SOURCE_FILE" ]] && { echo -en "${CL}Fetching '{$LIBRARY}'..."; source <(curl -s -L "$WGET_RAW/scripts/$LIBRARY"); [[ $? -ne 0 ]] && { echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; continue; }; }; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); [[ $? -ne 0 ]] && { echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; }; done; echo -en "${CL}${CL}"; optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" +optparse.define short=l long=lcd description="Install drivers for 3.5 inch LCD display" dispatch="octoscreen.tasks.add lcd; #" optparse.define short=b long=build description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has build || echo.fatal \"Specify MakeDir AFTER 'build'\"; #" default=$(pwd) optparse.define short=r long=release description="Release Target [STRETCH|BUSTER|JESSIE]" dispatch="octoscreen.tasks.has build || echo.fatal \"Specify Release Target AFTER 'build'\"; #" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit -optparse.define long=nodep description="Skip installing Apt Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag default="false" +optparse.define long=nodep description="Skip installing ALL Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag default="false" optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag default="false" From 532e9fce48b7268edb14827b31228a53c73f39bb Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 21:47:48 +0000 Subject: [PATCH 55/61] Made it specific to 3.5 inch display. The commented line would be un-commented when we allow for optioning, and the lcd35 hidden (but still active) for a time, for backwards-sake. --- scripts/octoscreen | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index c96ff7b9..6294703e 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -47,7 +47,8 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; [[ -z "$SOURCE_FILE" ]] && { echo -en "${CL}Fetching '{$LIBRARY}'..."; source <(curl -s -L "$WGET_RAW/scripts/$LIBRARY"); [[ $? -ne 0 ]] && { echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; continue; }; }; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); [[ $? -ne 0 ]] && { echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; }; done; echo -en "${CL}${CL}"; optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" -optparse.define short=l long=lcd description="Install drivers for 3.5 inch LCD display" dispatch="octoscreen.tasks.add lcd; #" +optparse.define long=lcd35 description="Install drivers for 3.5 inch LCD display" dispatch="octoscreen.tasks.add lcd; #" +#optparse.define short=l long=lcd description="Install drivers for LCD display" dispatch="octoscreen.tasks.add lcd; #" optparse.define short=b long=build description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has build || echo.fatal \"Specify MakeDir AFTER 'build'\"; #" default=$(pwd) optparse.define short=r long=release description="Release Target [STRETCH|BUSTER|JESSIE]" dispatch="octoscreen.tasks.has build || echo.fatal \"Specify Release Target AFTER 'build'\"; #" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit optparse.define long=nodep description="Skip installing ALL Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag default="false" From 6b1b9719111a7c2205edafb32acaa39d42c09259 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 22:15:04 +0000 Subject: [PATCH 56/61] Syntax --- scripts/octoscreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index c22d4863..3bbe69f0 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -558,7 +558,7 @@ function octoscreen.task.lcd.main(){ } # Check is FBTurbo is installed, and skip if so - if [[ -f /usr/share/X11/xorg.conf.d/99-fbturbo.conf || -f /usr/share/X11/xorg.conf.d/99-calibration.conf]]; then + if [[ -f /usr/share/X11/xorg.conf.d/99-fbturbo.conf || -f /usr/share/X11/xorg.conf.d/99-calibration.conf ]]; then __install_fbturbo=false fi From 0c82dd1756715b4420138b41fddaf26606773aa4 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 22:19:30 +0000 Subject: [PATCH 57/61] Changed the task function format. Fixing Calls. --- scripts/octoscreen | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 3bbe69f0..9729068d 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -702,7 +702,7 @@ function octoscreen.timer(){ function octoscreen.tasks.do(){ echo.debug "octoscreen.tasks.do($*)" - local did_a_thing=false + local did_a_thing=0 [[ -z "$2" ]] && echo.fatal "Task execution requies an action and atgleast one task to take it on" && return 1; [[ -z "$OCTOSCREEN_TASKS" ]] && echo.debug "There are, like, NO tasks, so... Nothing to do." && return 1; @@ -711,7 +711,7 @@ function octoscreen.tasks.do(){ for task in $@; do ( octoscreen.tasks.has $task ) && { - task="octoscreen.$do.${task}" + task="octoscreen.task.${task}.${do}" echo.debug "Fully qualified callback name: $task" @@ -731,7 +731,7 @@ function octoscreen.tasks.do(){ echo.chatty "'did_a_thing' status: $did_a_thing" - return "$did_a_thing" + return $did_a_thing } function octoscreen.tasks.has(){ From 301d69b9ad8116dbabab79e1397f6bb1e7eacd10 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 22:28:32 +0000 Subject: [PATCH 58/61] Correct Repo and Branch. This WAS correct, but somehow in testing I buggered it up. Kindly ignore... ;-) --- scripts/octoscreen | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 9729068d..7070d1b3 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -20,8 +20,8 @@ EOL exit; } _IFS=$IFS -REPO="thebeline/OctoScreen" -MAIN="me_test" +REPO="Z-Bolt/OctoScreen" +MAIN="master" WGET_RAW="https://github.com/$REPO/raw/$MAIN" LIBRARIES=("lib/optparse.bash" "lib/inquirer.bash" "lib/verbosity.bash") PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; @@ -622,10 +622,10 @@ function octoscreen.task.lcd.finally(){ function octoscreen.task.docker.init() { if command -v "docker" > /dev/null 2>&1; then echo.debug "Docker is already installed." - octoscreen.tasks.has docker || octoscreen.tasks.remove docker + octoscreen.tasks.has docker && octoscreen.tasks.remove docker else echo.debug "Docker is not installed." - octoscreen.tasks.has docker && octoscreen.tasks.add docker + octoscreen.tasks.has docker || octoscreen.tasks.add docker fi } From 3159fa0fa1cfd4192042cc91e90c4f33473f263b Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 19 Mar 2021 22:59:59 +0000 Subject: [PATCH 59/61] Prioritize TRUE for truthy checks. --- scripts/octoscreen | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/octoscreen b/scripts/octoscreen index 7070d1b3..2e0d2544 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -288,7 +288,7 @@ function octoscreen.task.install.main() { echo.debug "Parsed DEB Version: $OCTOSCREEN_DEB_VERSION" - false && { + true || { if [ -d "/home/pi/OctoPrint/venv" ]; then DIRECTORY="/home/pi/OctoPrint/venv" elif [ -d "/home/pi/oprint" ]; then @@ -343,7 +343,7 @@ function octoscreen.task.install.main() { echo "Installing OctoScreen "$OCTOSCREEN_DEB_VERSION, $DEB_ARCH"" - [[ ! -z $RELEASE_URL ]] && { + [[ -z $RELEASE_URL ]] || { echo.notice "Downloading Remote Deb File From: $RELEASE_URL" local command="wget -O $OCTOSCREEN_DEB $RELEASE_URL" @@ -363,11 +363,12 @@ function octoscreen.task.install.main() { } - [[ ! -f $OCTOSCREEN_DEB ]] && echo.fatal "After all this work, it seems like the Package doesn't actually exist: $OCTOSCREEN_DEB" + [[ -f $OCTOSCREEN_DEB ]] || + echo.fatal "After all this work, it seems like the Package doesn't actually exist: $OCTOSCREEN_DEB" sudo dpkg -i $OCTOSCREEN_DEB - [[ ! -z $RELEASE_URL ]] && { + [[ -z $RELEASE_URL ]] || { rm -f $OCTOSCREEN_DEB trap - EXIT } From 667e3e76b8e7697d8f7fb5e8bda695d7236b51bf Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 26 Mar 2021 15:44:28 +0000 Subject: [PATCH 60/61] Missed an escape. --- scripts/lib/optparse.bash | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/lib/optparse.bash b/scripts/lib/optparse.bash index 94f5a47e..b3d9cb52 100644 --- a/scripts/lib/optparse.bash +++ b/scripts/lib/optparse.bash @@ -471,6 +471,10 @@ function optparse.define(){ $has_default && [[ ! -z "$variable" ]] && optparse_defaults+="#NL[[ -z \$${variable} ]] && ${variable}='${default}'" + $has_default && + local _def=DEF || + local _def=''; + local validate_variable="$is_list && { valid=false for i in $list; do @@ -478,7 +482,7 @@ function optparse.define(){ done \$valid || optparse.usage false \"ERROR: invalid value for argument \\\"\$__arg_errorname\\\"\" 1 } - $has_variable && [[ -z \${${variable}:-$($has_default && echo 'DEF' || echo '')} ]] && optparse.usage false \"ERROR: (\$__arg_errorname) requires input value\" 1 || true" + $has_variable && [[ -z \${${variable}:-$_def} ]] && optparse.usage false \"ERROR: (\$__arg_errorname) requires input value\" 1 || true" local dispatch_caller="# No Dispatcher" @@ -500,7 +504,7 @@ function optparse.define(){ __arg_value=\"$val\"; } $has_variable && [[ -z \"\$__arg_value\" ]] && { - __arg_value=$__arg_sremain; + __arg_value=\"\$__arg_sremain\"; __arg_sremain=''; [[ -z \"\$__arg_value\" && ! -z \"\$1\" ]] && __arg_value=\"\$1\" && shift; } @@ -526,10 +530,6 @@ function optparse.define(){ ;;" } - $has_default && - local _def=DEF || - local _def=''; - $has_variable && optparse_variables_validate+=" $optional || { [[ -z \${${variable}:-$_def} ]] && optparse.usage true 'ERROR: (${errorname}) not set' 1 || true; };" From 2d909f265952888cf660722fa5ddc27b222432f8 Mon Sep 17 00:00:00 2001 From: Michael J Mulligan Date: Fri, 26 Mar 2021 17:41:31 +0000 Subject: [PATCH 61/61] Restructured the call order a bit, and bug fix for optparse. --- scripts/lib/optparse.bash | 18 ++++----- scripts/lib/verbosity.bash | 4 +- scripts/octoscreen | 82 +++++++++++++++++++++++--------------- 3 files changed, 58 insertions(+), 46 deletions(-) diff --git a/scripts/lib/optparse.bash b/scripts/lib/optparse.bash index b3d9cb52..b1580b59 100644 --- a/scripts/lib/optparse.bash +++ b/scripts/lib/optparse.bash @@ -109,7 +109,7 @@ function optparse.throw_error(){ function optparse._log(){ local type="$1" local message="$2" - echo "OPTPARSE $type: $message" + >&2 echo "OPTPARSE $type: $message" } function optparse.warn(){ @@ -468,21 +468,22 @@ function optparse.define(){ #echo "$_optparse_usage" } - $has_default && [[ ! -z "$variable" ]] && + $has_default && $has_variable && optparse_defaults+="#NL[[ -z \$${variable} ]] && ${variable}='${default}'" $has_default && local _def=DEF || local _def=''; - local validate_variable="$is_list && { + local validate_variable="valid=true + $is_list && \$valid && { valid=false for i in $list; do [[ \$__arg_value == \$i ]] && valid=true && break done - \$valid || optparse.usage false \"ERROR: invalid value for argument \\\"\$__arg_errorname\\\"\" 1 } - $has_variable && [[ -z \${${variable}:-$_def} ]] && optparse.usage false \"ERROR: (\$__arg_errorname) requires input value\" 1 || true" + \$valid || optparse.usage false \"ERROR: invalid value for argument \\\"\$__arg_key\\\"\" 1; + $has_variable && [[ -z \${${variable}:-$_def} ]] && optparse.usage false \"ERROR: (\$__arg_key) requires input value\" 1 || true;" local dispatch_caller="# No Dispatcher" @@ -498,7 +499,6 @@ function optparse.define(){ [[ ! -z "$shortname" ]] && { optparse_process_short+=" ${shortname}) - __arg_errorname=$short; __arg_value=''; ( $flag || $has_val ) && { __arg_value=\"$val\"; @@ -518,7 +518,6 @@ function optparse.define(){ [[ ! -z "$longname" ]] && { optparse_process_long+=" ${longname}) - __arg_errorname=$long; $has_val && { [[ ! -z \"\$__arg_value\" ]] && optparse.usage true 'ERROR: (${errorname}) does not accept user input' 1; __arg_value=\"$val\"; @@ -556,9 +555,6 @@ function optparse.build(){ local value="${option#*=}"; case "$key" in - name|description|usage_header|usage) - declare -g optparse_$key="$value" - ;; allow) value=( $value ) for allowed in "${value[@]}"; do @@ -724,4 +720,4 @@ EOF [[ -z "$optparse_preserve" ]] && optparse.unset } -optparse.init && true +[[ -z $OPTPARSE_DELAY_INIT ]] || optparse.init diff --git a/scripts/lib/verbosity.bash b/scripts/lib/verbosity.bash index adbddb12..31c6a22c 100644 --- a/scripts/lib/verbosity.bash +++ b/scripts/lib/verbosity.bash @@ -1,6 +1,6 @@ #!/user/bib/env bash -VERBOSITY_CURRENT=0 +VERBOSITY_CURRENT=${VERBOSITY_CURRENT:-0} VERBOSITY_FATAL=-3 VERBOSITY_ERROR=-2 VERBOSITY_QUIET=-1 @@ -20,8 +20,8 @@ VERBOSITY_INFO_FORMAT='\e[96m%s%s\e[0m: %s' VERBOSITY_DEBUG_FORMAT='\e[94m%s%s\e[0m: %s' VERBOSITY_HELL_FORMAT='\e[102m\e[95m\e[5m\e[30m\e[2m' + function echo.verbosity.init_optparse() { - VERBOSITY_CURRENT=0 declare -F 'optparse.define' > /dev/null diff --git a/scripts/octoscreen b/scripts/octoscreen index 9729068d..9e55dd3f 100755 --- a/scripts/octoscreen +++ b/scripts/octoscreen @@ -28,59 +28,68 @@ PWD="$(pwd)"; DIR=''; SOURCE="${BASH_SOURCE[0]:-$0}"; RELEASE_ARCH='' VERBOSITY_PREFIX='OCTOSCREEN ' +#VERBOSITY_CURRENT=3 + +OPTPARSE_DELAY_INIT=true + OCTOSCREEN_TASKS=() OCTOSCREEN_DEPENDENCIES=() OCTOSCREEN_DEB='' + yes_no=( 'yes' 'no' ) SYSTEM_ARCH=$(uname -m) declare -A ARCHITECTURES=( [arm.*]=*armhf.deb ) -# Prelim, just check if we support the current architecture... -for __ARCH in "${!ARCHITECTURES[@]}"; do [[ `expr "$SYSTEM_ARCH" : "^$__ARCH\$"` -gt 0 ]] && RELEASE_ARCH="${ARCHITECTURES[$__ARCH]}" && break; done; -[[ -z $RELEASE_ARCH ]] && { echo "We are sorry, but we do not support your system achitecture ($SYSTEM_ARCH). Exiting"; exit 1; } - while [[ "$SOURCE" != /dev/fd/* && -L "$SOURCE" ]]; do DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; SOURCE="$(readlink "$SOURCE")"; [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"; done; DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"; ### Load Bash Dependencies echo -e "Loading OctoScreen Manager dependencies, please wait...\n"; CL='\e[1A\e[K'; for LIBRARY in ${LIBRARIES[*]}; do SOURCE_FILE=''; SOURCE=''; [[ -f "$DIR/$LIBRARY" ]] && { SOURCE_FILE="$DIR/$LIBRARY"; } || { [[ -f "$PWD/$LIBRARY" ]] && SOURCE_FILE="$PWD/$LIBRARY"; } || { [[ -f "$PWD/scripts/$LIBRARY" ]] && SOURCE_FILE="$PWD/scripts/$LIBRARY"; }; [[ -z "$SOURCE_FILE" ]] && { echo -en "${CL}Fetching '{$LIBRARY}'..."; source <(curl -s -L "$WGET_RAW/scripts/$LIBRARY"); [[ $? -ne 0 ]] && { echo " ERROR Fetching dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; continue; }; }; echo -en "${CL}Loading '{$LIBRARY}' from: $SOURCE_FILE..."; source <(cat "$SOURCE_FILE"); [[ $? -ne 0 ]] && { echo " ERROR Loading dependency '$LIBRARY'!"; exit 1; } || { echo ' SUCCESS'; }; done; echo -en "${CL}${CL}"; -optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" -optparse.define long=lcd35 description="Install drivers for 3.5 inch LCD display" dispatch="octoscreen.tasks.add lcd; #" -#optparse.define short=l long=lcd description="Install drivers for LCD display" dispatch="octoscreen.tasks.add lcd; #" -optparse.define short=b long=build description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has build || echo.fatal \"Specify MakeDir AFTER 'build'\"; #" default=$(pwd) -optparse.define short=r long=release description="Release Target [STRETCH|BUSTER|JESSIE]" dispatch="octoscreen.tasks.has build || echo.fatal \"Specify Release Target AFTER 'build'\"; #" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit -optparse.define long=nodep description="Skip installing ALL Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag default="false" - -optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" -optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag default="false" - -optparse.define.single name="install" description="Install/Upgrade OctoScreen" dispatch="octoscreen.tasks.add install" -optparse.define.single name="remove" description="Remove OctoScreen" dispatch="octoscreen.tasks.add remove" -optparse.define.single name=build description="Build OctoScreen" dispatch="octoscreen.tasks.add build" -optparse.define.single name="*.deb" description="Target for Install/Upgrade and/or Build" dispatch="octoscreen.set.deb \"\$__arg\"" -optparse.define.single name="*" dispatch="octoscreen.handle.unknown \"\$__arg\"" help=hide - -echo.verbosity.init_optparse 0 - - ### Primary Functions: See bottom for other Utility Functions +function octoscreen.init(){ + + [[ -f /etc/os-release ]] && { + set -a + . /etc/os-release + set +a + } || { + echo.fatal "We kinda need \`/etc/os-release\`, but I couldn't find it. Proooobably means we don't support your system. If you believe this is in error, please file a bug report." + } + + # Prelim, just check if we support the current architecture... + for __ARCH in "${!ARCHITECTURES[@]}"; do [[ `expr "$SYSTEM_ARCH" : "^$__ARCH\$"` -gt 0 ]] && RELEASE_ARCH="${ARCHITECTURES[$__ARCH]}" && break; done; + + optparse.init name=$([[ "$DIR" =~ /proc/* ]] && echo '' || basename $0) description="OctoScreen Manager" usage_header="${optparse_usage_header} command [command ...] [*.deb]" + + optparse.define long=license description="The OctoScreen license" dispatch="octoscreen.license" + optparse.define long=lcd35 description="Install drivers for 3.5 inch LCD display" dispatch="octoscreen.tasks.add lcd; #" + #optparse.define short=l long=lcd description="Install drivers for LCD display" dispatch="octoscreen.tasks.add lcd; #" + optparse.define short=b long=build description="Specify a make directory for build" variable='MAKE_DIR' dispatch="octoscreen.tasks.has build || echo.fatal \"Specify MakeDir AFTER 'build'\"" default=$(pwd) + optparse.define short=r long=release description="Release Target [STRETCH|BUSTER|JESSIE]" dispatch="octoscreen.tasks.has build || echo.fatal \"Specify Release Target AFTER 'build'\"" variable=VERSION_CODENAME default=${VERSION_CODENAME^^} extra=explicit + optparse.define long=nodep description="Skip installing ALL Dependencies (DISCOURAGED)" variable=SKIP_DEPENDENCIES flag default="false" + + optparse.define short=y long=yes description="Auto-Confirm OctoScreen yes/no options" variable=AUTO_YES optional flag default="false" + optparse.define long=force description="Continue with dubious data. Caution, combined with --yes, this can do bad things..." variable=AUTO_FORCE optional flag default="false" + + optparse.define.single name="install" description="Install/Upgrade OctoScreen" dispatch="octoscreen.tasks.add install" + optparse.define.single name="remove" description="Remove OctoScreen" dispatch="octoscreen.tasks.add remove" + optparse.define.single name=build description="Build OctoScreen" dispatch="octoscreen.tasks.add build" + optparse.define.single name="*.deb" description="Target for Install/Upgrade and/or Build" dispatch="octoscreen.set.deb \"\$__arg\"" + optparse.define.single name="*" dispatch="octoscreen.handle.unknown \"\$__arg\"" help=hide + + echo.verbosity.init_optparse 0 +} + function octoscreen.main(){ #Called after all args are parsed # Tasks have to occur in an order, so we do them in order, no matter how they were passed. local _task_order="lcd docker build remove install" - [[ -f /etc/os-release ]] && { - source /etc/os-release - } || { - $AUTO_FORCE || echo "ERROR: We kinda need \`/etc/os-release\`, but I couldn't find it. Proooobably means we don't support your system. If you believe this is in error, please file a bug report." && exit 1; - }; - - $AUTO_FORCE || { - [[ $ID_LIKE != debian ]] && echo "ERROR: Yeah, no." && exit 1 - }; + $AUTO_FORCE || + [[ $ID_LIKE != debian ]] && echo.fatal "This currently only runs on Debian."; [[ -z "${OCTOSCREEN_TASKS[@]}" ]] && echo.error "Nothing to do. Please give me a purpose in life... I BEG YOU" && octoscreen.maybe.usage; @@ -204,6 +213,8 @@ function octoscreen.task.install.init(){ echo.notice "Checking if we can install, or if we need to re-install..." + [[ -z $RELEASE_ARCH ]] && echo.fatal "We are sorry, but we do not support your system achitecture ($SYSTEM_ARCH)"; + ( $OCTOSCREEN_INSTALLED && ! octoscreen.tasks.has remove ) && { $AUTO_FORCE && @@ -802,4 +813,9 @@ function echo.chatty(){ echo -e "$message" } -. <( optparse.build name=$([[ "$DIR" =~ /proc/* ]] && echo '' || basename $0) description="OctoScreen Manager" finally=octoscreen.main usage_header="${optparse_usage_header} command [command ...] [*.deb]") +octoscreen.init + +. <( optparse.build ) + +octoscreen.main +