#!/bin/bash set -eo pipefail version="0.5" MAKERVERSE_HOME=${MAKERVERSE_HOME:-${HOME}} # Figure out where the git checkout directory lives, if any: if [[ -z "$MAKERVERSE_SRC_DIR" ]]; then # Otherwise, the parent directory of this script should (hopefully) work. MAKERVERSE_SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" && pwd)" fi if [[ ! -d "$MAKERVERSE_SRC_DIR" ]]; then echo "Could not find the Makerverse installation at $MAKERVERSE_SRC_DIR" echo "Please try downloading or cloning the project at this location." exit 1 fi MAKERVERSE_GIT_DIR="${MAKERVERSE_SRC_DIR}" MAKERVERSE_LAUNCH_METHOD=${MAKERVERSE_LAUNCH_METHOD:-docker} MAKERVERSE_SETTINGS_FILE="${MAKERVERSE_HOME}/.makerverse" MAKERVERSE_WATCH_DIR="${MAKERVERSE_WATCH_DIR:-${MAKERVERSE_HOME}/gcode}" MAKERVERSE_PORT="${MAKERVERSE_PORT:-8000}" # Scan dependency versions if [[ $(which node) ]]; then nv=$(node -v) else nv="" fi if [[ $(which docker) ]]; then if ! docker info >/dev/null 2>&1; then dv="-" # not running else dv=$(docker version --format '{{.Server.Version}}') fi else dv="" fi # Set defaults & arguments git_repo="https://github.com/makermadecnc/makerverse.git" docker_img="makerverse/core" _arg_channel="latest" if [[ ! -z "$MAKERVERSE_CHANNEL" ]]; then _arg_channel="$MAKERVERSE_CHANNEL" elif [[ -f "$MAKERVERSE_SETTINGS_FILE" ]]; then if [[ $(cat "$MAKERVERSE_SETTINGS_FILE" | grep "\"prereleases\": true") ]]; then _arg_channel="prerelease" fi fi _arg_update="on" # Set default launch method when none provided. if [[ ! -z "$dv" ]]; then _arg_launch_method="docker" elif [[ "$nv" =~ "v12." ]]; then _arg_launch_method="node" else # Docker = fallback default (but no version, will error). _arg_launch_method="docker" fi # Use git to checkout or update the Makerverse directory. checkout() { if [[ ! $(which git) ]]; then echo "Please install git and run this script again." exit 1 fi if [[ -d "$MAKERVERSE_GIT_DIR" ]]; then cd "$MAKERVERSE_GIT_DIR" if [[ "$_arg_update" != "on" ]]; then echo "Skipping pull for git repository at $MAKERVERSE_GIT_DIR" else echo "Updating Makerverse from source code located in $MAKERVERSE_GIT_DIR..." if [ ! -z "$(git status --porcelain)" ]; then echo "Git history is not clean. You might try the following:" echo "git stash" echo "git checkout master" echo "git reset --hard origin/master" exit 1 fi git pull echo "Checking out master and reverting changes..." git checkout origin/master git reset --hard origin/master fi else echo "Checking out Makerverse into $MAKERVERSE_GIT_DIR..." git clone "$git_repo" "$MAKERVERSE_GIT_DIR" cd "$MAKERVERSE_GIT_DIR" fi } # Prompt for installation, giving prompt $1 on aptitude and $2 for downloads installPrompt() { if [[ $(which apt) ]]; then echo "You appear to be on a Debian system (e.g., Ubuntu, Raspbian). Here is the one-line install script:" echo "$1" else echo "Please try the downloads page:" echo "$2" fi echo "Run this script again once the install is complete." } createSettings() { if [[ ! -f "$MAKERVERSE_SETTINGS_FILE" ]]; then echo "No settings found at ${MAKERVERSE_SETTINGS_FILE}. This may be the first time Makerverse has run." if [[ -d "$MAKERVERSE_SETTINGS_FILE" ]]; then rm -rf "$MAKERVERSE_SETTINGS_FILE" fi url="https://raw.githubusercontent.com/makermadecnc/makerverse/master/$1" wget -q "$url" -O "$MAKERVERSE_SETTINGS_FILE" fi } # Main launch method launch() { method="${1}" channel="${2}" echo "Makerverse:${channel} settings: ${MAKERVERSE_SETTINGS_FILE} (project at: ${MAKERVERSE_GIT_DIR})" if [ "$method" = "node" ]; then createSettings ".makerverse.default" # Update Makerverse, build, and run the Node.js application directly. if [[ "$nv" =~ "v12." ]]; then echo "NodeJS $nv detected" elif [[ -z "$nv" ]]; then echo "Could not detect NodeJS. Please install version 12.xx.x:" installPrompt "curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -" \ "https://nodejs.org/en/download/" exit 1 else echo "NodeJS was not version 12.x" echo "Please consider using NVM to support multiple versions of NodeJS." echo "Run this script again once 'node -v' begins with '12.x'." exit 1 fi checkout npm install npm run build-prod node ./bin/makerverse -p "${MAKERVERSE_PORT}" elif [ "$method" = "docker" ] || [ "$method" = "" ]; then createSettings ".makerverse.docker" # Launch via a docker image if [[ "$dv" = "-" ]]; then echo "Docker is not running." exit 1 elif [[ ! -z "$dv" ]]; then echo "Docker v${dv} detected" else echo "Docker version could not be detected." installPrompt "curl -sSL https://get.docker.com | sh" "https://www.docker.com/products/docker-desktop" exit 1 fi docker_tagged="${docker_img}:${channel}" if [[ "$_arg_update" = "on" ]]; then echo "Removing old versions (pruning docker)..." docker system prune --force echo "Updating $docker_tagged..." docker pull "$docker_tagged" fi echo "Killing prior instances..." docker kill makerverse || true echo "Launching $docker_tagged..." docker run --rm --privileged --name makerverse \ -p "${MAKERVERSE_PORT}:8000" \ -v /dev:/dev \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$MAKERVERSE_WATCH_DIR:/home/node/gcode" \ -v "$MAKERVERSE_SETTINGS_FILE:/home/node/.makerverse" \ -v "$MAKERVERSE_SRC_DIR:/home/node/makerverse" \ "$docker_tagged" else echo "Invalid launch method: ${method}" exit 1 fi } # ARG_OPTIONAL_SINGLE([launch_method],[l],[Either 'node' or 'docker'],[docker]) # ARG_OPTIONAL_SINGLE([channel],[c],[Launch from a specific release channel]) # ARG_OPTIONAL_BOOLEAN([update],[u],[Update the application before launching],[on]) # ARG_VERSION([echo v$version]) # ARG_HELP([Makerverse launch script for bootstraping dependencies and starting the application.]) # ARGBASH_GO() # needed because of Argbash --> m4_ignore([ ### START OF CODE GENERATED BY Argbash v2.9.0 one line above ### # Argbash is a bash code generator used to get arguments parsing right. # Argbash is FREE SOFTWARE, see https://argbash.io for more info # Generated online by https://argbash.io/generate die() { local _ret="${2:-1}" test "${_PRINT_HELP:-no}" = yes && print_help >&2 echo "$1" >&2 exit "${_ret}" } begins_with_short_option() { local first_option all_short_options='lcuvh' first_option="${1:0:1}" test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 } print_help() { printf '%s\n' "Makerverse launch script for bootstraping dependencies and starting the application." printf 'Usage: %s [-l|--launch_method ] [-c|--channel ] [-u|--(no-)update] [-v|--version] [-h|--help]\n' "$0" printf '\t%s\n' "-l, --launch_method: Either 'node' or 'docker' (default: 'docker')" printf '\t%s\n' "-c, --channel: Launch from a specific release channel (no default)" printf '\t%s\n' "-u, --update, --no-update: Update the application before launching (on by default)" printf '\t%s\n' "-v, --version: Prints version" printf '\t%s\n' "-h, --help: Prints help" } parse_commandline() { while test $# -gt 0 do _key="$1" case "$_key" in -l|--launch_method) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 _arg_launch_method="$2" shift ;; --launch_method=*) _arg_launch_method="${_key##--launch_method=}" ;; -l*) _arg_launch_method="${_key##-l}" ;; -c|--channel) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 _arg_channel="$2" shift ;; --channel=*) _arg_channel="${_key##--channel=}" ;; -c*) _arg_channel="${_key##-c}" ;; -u|--no-update|--update) _arg_update="on" test "${1:0:5}" = "--no-" && _arg_update="off" ;; -u*) _arg_update="on" _next="${_key##-u}" if test -n "$_next" -a "$_next" != "$_key" then { begins_with_short_option "$_next" && shift && set -- "-u" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." fi ;; -v|--version) echo v$version exit 0 ;; -v*) echo v$version exit 0 ;; -h|--help) print_help exit 0 ;; -h*) print_help exit 0 ;; *) _PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1 ;; esac shift done } parse_commandline "$@" # OTHER STUFF GENERATED BY Argbash ### END OF CODE GENERATED BY Argbash (sortof) ### ]) # [ <-- needed because of Argbash launch "$_arg_launch_method" "$_arg_channel" # ] <-- needed because of Argbash