Skip to content

Instantly share code, notes, and snippets.

@gabrieleara
Created November 20, 2019 09:43
Show Gist options
  • Save gabrieleara/093deff6f8e31fbb9fc260ce067a2d9f to your computer and use it in GitHub Desktop.
Save gabrieleara/093deff6f8e31fbb9fc260ce067a2d9f to your computer and use it in GitHub Desktop.

Revisions

  1. gabrieleara created this gist Nov 20, 2019.
    377 changes: 377 additions & 0 deletions install-utility
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,377 @@
    #!/bin/bash

    set -e

    ############################## DEFAULT PARAMETERS ##############################

    # Indicates whether we want to install or remove one or multiple packages
    # TODO: Also autoremove can be used, to force additional cleanup
    install_remove="install"

    # The list of packages to install in a single apt command
    list_apt_packages=""

    # If set to 1 local alternatives to packages are ignored
    no_alternative='0'

    # Check arguments only
    dry_run='0'

    # TODO: something to set a shell as default

    ################################# PACKET LISTS #################################

    # Predefined lists of packets (substitute _ with - when using the script)
    exfat="exfat-fuse exfat-utils"
    sysperf="htop hwloc cpufrequtils stress"
    p7zip="p7zip-full p7zip-rar"
    gnome_extras="gnome-tweak-tool gnome-sushi gparted"
    utils="tree mlocate gnuplot grub-customizer"
    shells="zsh"

    # This is too long, broken in two assignments
    dev="git build-essential module-assistant cmake apt-file linux-headers-generic"
    dev="$dev manpages-posix manpages-posix-dev colordiff valgrind"

    ############################# PACKET ALTERNATIVES ##############################

    # Default alternatives to actual packages (can be ignored with --no-alternative)
    vim="vim-gtk3"

    ########################### OTHER SUPPORTED PACKAGES ###########################

    # Other known supported packets
    # handbrake handbrake-cli, spotify-client, vlc, grub-customizer, google-chrome,
    # audacity, skype/skypeforlinux, telegram/telegram-desktop, nodejs, blender
    # TODO: FOR NOW BLENDER IS PROVIDED FROM UNIVERSE, NOT FROM ppa:thomas-schiex/blender
    # TODO: obs-studio, synergy, clion, mailspring, android-studio, android-sys-dev
    # TODO: kodi?, albert?, docker? (unsupported on eoan by default)

    ################# FULL LIST OF AVAILABLE INSTALLABLE PACKAGES ##################
    ### CAN BE USED TO INSTALL EVERYTHING IN THE SYSTEM, USE WITH CAUTION THOUGH ###

    full="$exfat $sysperf $p7zip $gnome_extras $utils $shells $dev vim"
    full_others="telegram google-chrome code skype" # TODO: nativefier-whatsapp nativefier-overleaf

    ################################## VARIABLES ###################################

    # List of packages to install
    packages=""

    # List of other kinds of packages to install manually
    # (not to be included in a single apt call)
    other_packages=""

    ################################## FUNCTIONS ###################################

    function toshortopt() {
    case $1 in
    --autoremove) echo '-a' ;;
    --remove) echo '-r' ;;
    --no-alternative) echo '-N' ;;
    --dry-run) echo '-D' ;;
    --help) echo '-h' ;;
    *) echo "$1" ;;
    esac
    }

    function tolongopt() {
    case $1 in
    -a) echo '--autoremove' ;;
    -r) echo '--remove' ;;
    -N) echo '--no-alternative' ;;
    -D) echo '--dry-run' ;;
    -h) echo '--help' ;;
    *) echo "$1" ;;
    esac
    }


    function parse_parameters() {
    # With this we convert all parameters to short options,
    # to use getopts to parse them
    for arg in "$@" ; do
    shift
    set -- "$@" "`toshortopt "$arg"`"
    done

    OPTMAX="$#"
    OPTIND=1
    while [ $OPTIND -le $OPTMAX ] ;
    do
    # Use getopts to parse parameters
    while getopts "ahrDN" opt ;
    do
    case "${opt}" in
    a)
    install_remove='autoremove'
    ;;
    r)
    install_remove='remove'
    ;;
    N)
    no_alternative='1'
    ;;
    D)
    dry_run='1'
    ;;
    h)
    # Print help and terminate script
    print_help
    exit 0
    ;;
    esac
    done

    # Parse other long parameters
    while [ $OPTIND -le $OPTMAX ] && ! [ "`echo "${!OPTIND}" | cut -c1-1`" = '-' ] ;
    do
    current="${!OPTIND}"
    case "$current" in
    exfat)
    packages="$packages $exfat"
    ;;
    sysperf)
    packages="$packages $sysperf"
    ;;
    p7zip)
    packages="$packages $p7zip"
    ;;
    gnome-extras)
    packages="$packages $gnome_extras"
    ;;
    utils)
    packages="$packages $utils"
    ;;
    shells)
    packages="$packages $shells"
    ;;
    dev)
    packages="$packages $dev"
    ;;
    full)
    packages="$packages $full"
    ;;
    # Following ones are alternatives, they can be disabled
    vim)
    if [ "$no_alternative" -eq "0" ] ; then
    packages="$packages $vim"
    else
    packages="$packages vim"
    fi
    ;;
    # Packages that cannot be installed with apt directly
    telegram|telegram-desktop)
    other_packages="$other_packages telegram"
    ;;
    google-chrome)
    packages="$packages chrome-gnome-shell"
    other_packages="$other_packages google-chrome"
    ;;
    code)
    other_packages="$other_packages code"
    ;;
    skype|skypeforlinux)
    other_packages="$other_packages skype"
    ;;
    nativefier-whatsapp)
    packages="$packages nodejs git"
    other_packages="$other_packages nativefier webinstall nativefier-whatsapp"
    ;;
    nativefier-overleaf)
    packages="$packages nodejs git"
    other_packages="$other_packages nativefier webinstall nativefier-overleaf"
    ;;
    nativefier|webinstall)
    packages="$packages nodejs git"
    other_packages="$other_packages nativefier webinstall"
    ;;
    # Unrecognized strings that do not start with -
    *)
    # Any unrecognized parameter will be forwarded to APT, use with caution!
    # If this is a known package name then it's fine.
    packages="$packages $current"
    ;;
    esac

    OPTIND=$((OPTIND + 1))
    done

    # Start again if not done
    done
    }

    function print_help() {
    # TODO:
    echo "This is a very helpful help output!"
    }

    function ask_sudo_passwd() {
    echo "You will be prompted to insert your sudo password, this is needed to "
    echo "avoid prompting you when there is actually something to do"
    echo "YOU CAN CHECK THE SOURCE OF THIS SCRIPT FOR THE FUNCTION ask_sudo_passwd AND NOTICE THAT THERE IS NOTHING MALICIOUS WITH THIS"
    echo ""
    echo "Also please, avoid locking your pc during the installation, otherwise some commands may get stuck on sudo prompts..."
    echo ""
    echo "Enter your sudo password now:"
    sudo echo ""
    echo ""
    echo "Thank you!"
    echo ""
    }

    function repositories() {
    # Enable standard repositories
    sudo apt-add-repository main --no-update -y
    sudo apt-add-repository universe --no-update -y
    sudo apt-add-repository restricted --no-update -y
    sudo apt-add-repository multiverse --no-update -y
    }

    function install_pre_execute() {
    for package_name in $packages $other_packages ; do
    echo "PRE-EXECUTING $package_name"
    case "$package_name" in
    gimp)
    if [ "$no_alternative" -eq "0" ] ; then
    sudo add-apt-repository ppa:otto-kesselgulasch/gimp -y --no-update
    fi
    ;;
    spotify-client)
    install_repo_spotify
    ;;
    nodejs)
    install_repo_nodejs
    ;;
    esac
    done
    }

    function install_post_execute() {
    echo ""
    }

    function install_packages() {
    # First print what will be done:
    echo "INSTALLING THE FOLLOWING PACKAGES"
    echo "["
    echo "$packages"
    echo "]"

    # Install command
    sudo apt update
    sudo apt install -y $packages
    }

    function install_others() {
    echo "INSTALLING THE FOLLOWING PACKAGES"
    echo "["
    echo "$other_packages"
    echo "]"

    for package_name in $other_packages ; do
    case "$package_name" in
    telegram)
    install_telegram
    ;;
    google-chrome)
    download_install "google-chrome" "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
    ;;
    code)
    download_install "code" "https://go.microsoft.com/fwlink/?LinkID=760868"
    ;;
    skype)
    # TODO: add an alias because skypeforlinux is a terrible command
    download_install "skype" "https://go.skype.com/skypeforlinux-64.deb"
    ;;
    webinstall)
    cd /tmp
    git clone https://gist.github.com/684882880c8c057858732b5e40032aa8.git webinstall
    sudo cp webinstall/webinstall /usr/local/bin/webinstall
    sudo chmod a+x /usr/local/bin/webinstall
    rm -r -f webinstall
    cd - > /dev/null
    ;;
    nativefier-whatsapp)
    echo "If your language is different than English or Italian, WhatsApp won't work!"
    echo "" > /tmp/whatsapp-fix.js
    echo "if (document.body.innerText.replace(/\n/g, ' ').search(/WHATSAPP WEB.*whatsapp works with.*to use whatsapp.*update/i) === 0)" >> /tmp/whatsapp-fix.js
    echo "navigator.serviceWorker.getRegistration().then(function (r) { r.unregister(); document.location.reload() });" >> /tmp/whatsapp-fix.js
    echo "if (document.body.innerText.replace(/\n/g, ' ').search(/WHATSAPP WEB.*whatsapp.*funziona.*per usare whatsapp.*aggiorna/i) === 0)" >> /tmp/whatsapp-fix.js
    echo "navigator.serviceWorker.getRegistration().then(function (r) { r.unregister(); document.location.reload() });" >> /tmp/whatsapp-fix.js

    webinstall -n Whatsapp --tray --single-instance --inject /tmp/whatsapp-fix.js web.whatsapp.com
    rm /tmp/whatsapp-fix.js
    ;;
    nativefier-overleaf)
    webinstall -n Overleaf www.overleaf.com
    ;;
    nativefier)
    sudo npm install nativefier -g
    ;;

    *)
    echo "Error: unrecognized package $package_name"
    ;;
    esac
    done
    }

    function download_install() {
    # Argument 1 is the readable name for the user
    # Argument 2 is the link for download
    # They are both required

    echo "Installing $1..."

    wget $2 -O /tmp/temp_installer.deb
    sudo dpkg -i /tmp/temp_installer.deb || sudo apt-get install -f -y
    rm /tmp/temp_installer.deb
    }

    function install_repo_spotify() {
    curl -sS https://download.spotify.com/debian/pubkey.gpg | sudo apt-key add -
    echo "deb http://repository.spotify.com stable non-free" | sudo tee /etc/apt/sources.list.d/spotify.list
    }
    function install_repo_nodejs() {
    curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
    }

    function install_telegram() {
    cd /tmp
    wget https://telegram.org/dl/desktop/linux -O tsetup.tar.xz
    tar xf tsetup.tar.xz
    sudo mv -f Telegram /opt/
    sudo ln -fs /opt/Telegram/Telegram /usr/local/bin/telegram
    sudo ln -fs /opt/Telegram/Telegram /usr/local/bin/telegram-desktop

    # Not really secure, how else can I enable the updater while being still secure? ACL?
    sudo chmod -R a+w /opt/Telegram/*
    rm tsetup.tar.xz
    cd -

    echo "Installed Telegram. Start it with telegram or telegram-desktop."
    }


    ############################### MAIN SCRIPT FLOW ###############################

    parse_parameters "$@"

    # Sort and filter-out duplicates
    packages=$(echo $packages | xargs -n1 | sort -u | xargs)

    # Actual installation commands for (most) packages
    if [ "$dry_run" = "1" ] ; then
    echo "PRINTING CONFIGURATION:"
    echo "LIST OF ALL PACKAGES TO INSTALL:"
    echo "$packages"
    exit 0
    fi

    ask_sudo_passwd
    repositories
    install_pre_execute
    install_packages
    install_post_execute
    install_others