diff --git a/install.sh b/install.sh index 6c9b474..d42c48d 100755 --- a/install.sh +++ b/install.sh @@ -5,21 +5,21 @@ CONFIG_DIR="/boot/firmware" DATESTAMP=`date "+%Y-%m-%d-%H-%M-%S"` CONFIG_BACKUP=false APT_HAS_UPDATED=false -RESOURCES_TOP_DIR=$HOME/Pimoroni -VENV_BASH_SNIPPET=$RESOURCES_TOP_DIR/auto_venv.sh -VENV_DIR=$HOME/.virtualenvs/pimoroni +RESOURCES_TOP_DIR="$HOME/Pimoroni" +VENV_BASH_SNIPPET="$RESOURCES_TOP_DIR/auto_venv.sh" +VENV_DIR="$HOME/.virtualenvs/pimoroni" WD=`pwd` USAGE="./install.sh (--unstable)" POSITIONAL_ARGS=() FORCE=false UNSTABLE=false PYTHON="python" +CMD_ERRORS=false user_check() { if [ $(id -u) -eq 0 ]; then - printf "Script should not be run as root. Try './install.sh'\n" - exit 1 + fatal "Script should not be run as root. Try './install.sh'\n" fi } @@ -54,29 +54,34 @@ inform() { } warning() { - echo -e "$(tput setaf 1)$1$(tput sgr0)" + echo -e "$(tput setaf 1)⚠ WARNING:$(tput sgr0) $1" +} + +fatal() { + echo -e "$(tput setaf 1)⚠ FATAL:$(tput sgr0) $1" + exit 1 } find_config() { if [ ! -f "$CONFIG_DIR/$CONFIG_FILE" ]; then CONFIG_DIR="/boot" - if [ ! -f "$CONFIG_DIR/$CONFIG_FILE"]; then - warning "Could not find $CONFIG_FILE!" - exit 1 + if [ ! -f "$CONFIG_DIR/$CONFIG_FILE" ]; then + fatal "Could not find $CONFIG_FILE!" + fi + else + if [ -f "/boot/$CONFIG_FILE" ] && [ ! -L "/boot/$CONFIG_FILE" ]; then + warning "Oops! It looks like /boot/$CONFIG_FILE is not a link to $CONFIG_DIR/$CONFIG_FILE" + warning "You might want to fix this!" fi - else - if [ -f "/boot/$CONFIG_FILE" ] && [ ! -L "/boot/$CONFIG_FILE" ]; then - warning "Oops! It looks like /boot/$CONFIG_FILE is not a link to $CONFIG_DIR/$CONFIG_FILE" - warning "You might want to fix this!" - fi fi - inform "Using $CONFIG_FILE in $CONFIG_DIR" + inform "Using $CONFIG_FILE in $CONFIG_DIR" } venv_bash_snippet() { - inform "Checking for $VENV_BASH_SNIPPET\n" + inform "Checking for $VENV_BASH_SNIPPET\n" if [ ! -f $VENV_BASH_SNIPPET ]; then - inform "Creating $VENV_BASH_SNIPPET\n" + inform "Creating $VENV_BASH_SNIPPET\n" + mkdir -p $RESOURCES_TOP_DIR cat << EOF > $VENV_BASH_SNIPPET # Add "source $VENV_BASH_SNIPPET" to your ~/.bashrc to activate # the Pimoroni virtual environment automagically! @@ -96,23 +101,32 @@ venv_check() { PYTHON_BIN=`which $PYTHON` if [[ $VIRTUAL_ENV == "" ]] || [[ $PYTHON_BIN != $VIRTUAL_ENV* ]]; then printf "This script should be run in a virtual Python environment.\n" - if confirm "Would you like us to create one for you?"; then + if confirm "Would you like us to create and/or use a default one?"; then + printf "\n" if [ ! -f $VENV_DIR/bin/activate ]; then - inform "Creating virtual Python environment in $VENV_DIR, please wait...\n" + inform "Creating a new virtual Python environment in $VENV_DIR, please wait...\n" mkdir -p $VENV_DIR /usr/bin/python3 -m venv $VENV_DIR --system-site-packages venv_bash_snippet + source $VENV_DIR/bin/activate else - inform "Found existing virtual Python environment in $VENV_DIR\n" + inform "Activating existing virtual Python environment in $VENV_DIR\n" + printf "source $VENV_DIR/bin/activate\n" + source $VENV_DIR/bin/activate fi - inform "Activating virtual Python environment in $VENV_DIR..." - inform "source $VENV_DIR/bin/activate\n" - source $VENV_DIR/bin/activate - else - exit 1 + printf "\n" + fatal "Please create and/or activate a virtual Python environment and try again!\n" fi fi + printf "\n" +} + +check_for_error() { + if [ $? -ne 0 ]; then + CMD_ERRORS=true + warning "^^^ 😬" + fi } function do_config_backup { @@ -132,6 +146,7 @@ function do_config_backup { function apt_pkg_install { PACKAGES=() PACKAGES_IN=("$@") + # Check the list of packages and only run update/install if we need to for ((i = 0; i < ${#PACKAGES_IN[@]}; i++)); do PACKAGE="${PACKAGES_IN[$i]}" if [ "$PACKAGE" == "" ]; then continue; fi @@ -143,12 +158,14 @@ function apt_pkg_install { done PACKAGES="${PACKAGES[@]}" if ! [ "$PACKAGES" == "" ]; then - echo "Installing missing packages: $PACKAGES" + printf "\n" + inform "Installing missing packages: $PACKAGES" if [ ! $APT_HAS_UPDATED ]; then sudo apt update APT_HAS_UPDATED=true fi sudo apt install -y $PACKAGES + check_for_error if [ -f "$UNINSTALLER" ]; then echo "apt uninstall -y $PACKAGES" >> $UNINSTALLER fi @@ -156,7 +173,9 @@ function apt_pkg_install { } function pip_pkg_install { + # A null Keyring prevents pip stalling in the background PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring $PYTHON -m pip install --upgrade "$@" + check_for_error } while [[ $# -gt 0 ]]; do @@ -186,30 +205,33 @@ while [[ $# -gt 0 ]]; do esac done +printf "Installing $LIBRARY_NAME...\n\n" + user_check venv_check if [ ! -f `which $PYTHON` ]; then - printf "Python path $PYTHON not found!\n" - exit 1 + fatal "Python path $PYTHON not found!\n" fi PYTHON_VER=`$PYTHON --version` -printf "$LIBRARY_NAME Python Library: Installer\n\n" - inform "Checking Dependencies. Please wait..." +# Install toml and try to read pyproject.toml into bash variables + pip_pkg_install toml CONFIG_VARS=`$PYTHON - < $UNINSTALLER printf "It's recommended you run these steps manually.\n" printf "If you want to run the full script, open it in\n" @@ -244,19 +270,23 @@ exit 1 source $VIRTUAL_ENV/bin/activate EOF -if $UNSTABLE; then - warning "Installing unstable library from source.\n\n" -else - printf "Installing stable library from pypi.\n\n" -fi +printf "\n" inform "Installing for $PYTHON_VER...\n" + +# Install apt packages from pyproject.toml / tool.pimoroni.apt_packages apt_pkg_install "${APT_PACKAGES[@]}" + +printf "\n" + if $UNSTABLE; then + warning "Installing unstable library from source.\n" pip_pkg_install . else + inform "Installing stable library from pypi.\n" pip_pkg_install $LIBRARY_NAME fi + if [ $? -eq 0 ]; then success "Done!\n" echo "$PYTHON -m pip uninstall $LIBRARY_NAME" >> $UNINSTALLER @@ -266,6 +296,8 @@ cd $WD find_config +# Run the setup commands from pyproject.toml / tool.pimoroni.commands + for ((i = 0; i < ${#SETUP_CMDS[@]}; i++)); do CMD="${SETUP_CMDS[$i]}" # Attempt to catch anything that touches config.txt and trigger a backup @@ -273,13 +305,18 @@ for ((i = 0; i < ${#SETUP_CMDS[@]}; i++)); do do_config_backup fi eval $CMD + check_for_error done +printf "\n" + +# Add the config.txt entries from pyproject.toml / tool.pimoroni.configtxt + for ((i = 0; i < ${#CONFIG_TXT[@]}; i++)); do CONFIG_LINE="${CONFIG_TXT[$i]}" if ! [ "$CONFIG_LINE" == "" ]; then do_config_backup - inform "Adding $CONFIG_LINE to $CONFIG_DIR/$CONFIG_FILE\n" + inform "Adding $CONFIG_LINE to $CONFIG_DIR/$CONFIG_FILE" sudo sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG_DIR/$CONFIG_FILE if ! grep -q "^$CONFIG_LINE" $CONFIG_DIR/$CONFIG_FILE; then printf "$CONFIG_LINE\n" | sudo tee --append $CONFIG_DIR/$CONFIG_FILE @@ -287,6 +324,10 @@ for ((i = 0; i < ${#CONFIG_TXT[@]}; i++)); do fi done +printf "\n" + +# Just a straight copy of the examples/ dir into ~/Pimoroni/board/examples + if [ -d "examples" ]; then if confirm "Would you like to copy examples to $RESOURCES_DIR?"; then inform "Copying examples to $RESOURCES_DIR" @@ -298,9 +339,12 @@ fi printf "\n" +# Use pdoc to generate basic documentation from the installed module + if confirm "Would you like to generate documentation?"; then + inform "Installing pdoc. Please wait..." pip_pkg_install pdoc - printf "Generating documentation.\n" + inform "Generating documentation.\n" $PYTHON -m pdoc $LIBRARY_NAME -o $RESOURCES_DIR/docs > /dev/null if [ $? -eq 0 ]; then inform "Documentation saved to $RESOURCES_DIR/docs" @@ -310,6 +354,22 @@ if confirm "Would you like to generate documentation?"; then fi fi -success "\nAll done!" -inform "If this is your first time installing you should reboot for hardware changes to take effect.\n" -inform "Find uninstall steps in $UNINSTALLER\n" +printf "\n" + +if [ "$CMD_ERRORS" = true ]; then + warning "One or more setup commands appear to have failed." + printf "This might prevent things from working properly.\n" + printf "Make sure your OS is up to date and try re-running this installer.\n" + printf "If things still don't work, report this or find help at $GITHUB_URL.\n\n" +else + success "\nAll done!" +fi + +printf "If this is your first time installing you should reboot for hardware changes to take effect.\n" +printf "Find uninstall steps in $UNINSTALLER\n\n" + +if [ "$CMD_ERRORS" = true ]; then + exit 1 +else + exit 0 +fi \ No newline at end of file