Skip to content

Instantly share code, notes, and snippets.

@ScottDillman
Last active October 11, 2018 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ScottDillman/81d36986eaf25dc60419953abca199ef to your computer and use it in GitHub Desktop.
Save ScottDillman/81d36986eaf25dc60419953abca199ef to your computer and use it in GitHub Desktop.
Bash script to set up an isolated node environment, and an app with Aurelia framework with Electron or plain Typescript for application prototyping
#!/bin/bash
#===============================================================================
#title : newApp.sh
#description : This script will generate a skeleton electron app using
# : UniteJS and the Aurelia framework as well as creating
# : an isolated Node.js environment
#author : scott@bitwise.ninja
#date : 20180903
#version : 0.1
#usage : bash newApp.sh
#notes : Edit user settings before running
#bash_version : 4.3.48(1)-release
#===============================================================================
# version="0.1"
#
# This is an optional arguments-only example of Argbash potential
#
# ARG_OPTIONAL_SINGLE([nodejs],[j],[node.js version to install])
# ARG_OPTIONAL_SINGLE([type],[y],[type of project (typescript,electron,node)],[node])
# ARG_OPTIONAL_SINGLE([root],[r],[root directory for project],[skeleton])
# ARG_OPTIONAL_SINGLE([package],[p],[new package name],[skeleton])
# ARG_OPTIONAL_SINGLE([title],[t],[new package title],[Skeleton App])
# ARG_OPTIONAL_SINGLE([description],[d],[new package description],[skeleton app for prototyping])
# ARG_OPTIONAL_SINGLE([keywords],[k],[comma separated list of keywords],[skeleton,prototype,example])
# ARG_OPTIONAL_SINGLE([organization],[o],[new package organization],[skeleton club])
# ARG_OPTIONAL_SINGLE([copyright],[c],[new package description],[2018 skeleton club])
# ARG_OPTIONAL_SINGLE([website],[w],[new package website],[http://skeleton.app])
# ARG_OPTIONAL_SINGLE([namespace],[n],[new package namespace],[skeleton.app])
# ARG_OPTIONAL_SINGLE([author],[a],[new package author],[Skullhead Boneyhands])
# ARG_OPTIONAL_SINGLE([email],[e],[email],[sboneyhands@skeleton.app])
# ARG_OPTIONAL_SINGLE([authorsite],[i],[author website],[http://boneyhands.com])
# ARG_OPTIONAL_SINGLE([output],[u],[output directory],[webapp])
# ARG_HELP([Node app project skeleton generator])
# ARGBASH_GO()
# needed because of Argbash --> m4_ignore([
### START OF CODE GENERATED BY Argbash v2.6.1 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
test -n "$_ret" || _ret=1
test "$_PRINT_HELP" = yes && print_help >&2
echo "$1" >&2
exit ${_ret}
}
begins_with_short_option()
{
local first_option all_short_options
all_short_options='jyrptdkocwnaeiuh'
first_option="${1:0:1}"
test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
}
# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_nodejs=
_arg_type="node"
_arg_root="skeleton"
_arg_package="skeleton"
_arg_title="Skeleton App"
_arg_description="skeleton app for prototyping"
_arg_keywords="skeleton,prototype,example"
_arg_organization="skeleton club"
_arg_copyright="2018 skeleton club"
_arg_website="http://skeleton.app"
_arg_namespace="skeleton.app"
_arg_author="Skullhead Boneyhands"
_arg_email="sboneyhands@skeleton.app"
_arg_authorsite="http://boneyhands.com"
_arg_output="webapp"
print_help ()
{
printf '%s\n' "Node app project skeleton generator"
printf 'Usage: %s [-j|--nodejs <arg>] [-y|--type <arg>] [-r|--root <arg>] [-p|--package <arg>] [-t|--title <arg>] [-d|--description <arg>] [-k|--keywords <arg>] [-o|--organization <arg>] [-c|--copyright <arg>] [-w|--website <arg>] [-n|--namespace <arg>] [-a|--author <arg>] [-e|--email <arg>] [-i|--authorsite <arg>] [-u|--output <arg>] [-h|--help]\n' "$0"
printf '\t%s\n' "-j,--nodejs: node.js version to install (no default)"
printf '\t%s\n' "-y,--type: type of project (typescript,electron,node) (default: 'typescript')"
printf '\t%s\n' "-r,--root: root directory for project (default: 'skeleton')"
printf '\t%s\n' "-p,--package: new package name (default: 'skeleton')"
printf '\t%s\n' "-t,--title: new package title (default: 'Skeleton App')"
printf '\t%s\n' "-d,--description: new package description (default: 'skeleton app for prototyping')"
printf '\t%s\n' "-k,--keywords: comma separated list of keywords (default: 'skeleton,prototype,example')"
printf '\t%s\n' "-o,--organization: new package organization (default: 'skeleton club')"
printf '\t%s\n' "-c,--copyright: new package description (default: '2018 skeleton club')"
printf '\t%s\n' "-w,--website: new package website (default: 'http://skeleton.app')"
printf '\t%s\n' "-n,--namespace: new package namespace (default: 'skeleton.app')"
printf '\t%s\n' "-a,--author: new package author (default: 'Skullhead Boneyhands')"
printf '\t%s\n' "-e,--email: email (default: 'sboneyhands@skeleton.app')"
printf '\t%s\n' "-i,--authorsite: author website (default: 'http://boneyhands.com')"
printf '\t%s\n' "-u,--output: output directory (default: 'webapp')"
printf '\t%s\n' "-h,--help: Prints help"
}
parse_commandline ()
{
while test $# -gt 0
do
_key="$1"
case "$_key" in
-j|--nodejs)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_nodejs="$2"
shift
;;
--nodejs=*)
_arg_nodejs="${_key##--nodejs=}"
;;
-j*)
_arg_nodejs="${_key##-j}"
;;
-y|--type)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_type="$2"
shift
;;
--type=*)
_arg_type="${_key##--type=}"
;;
-y*)
_arg_type="${_key##-y}"
;;
-r|--root)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_root="$2"
shift
;;
--root=*)
_arg_root="${_key##--root=}"
;;
-r*)
_arg_root="${_key##-r}"
;;
-p|--package)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_package="$2"
shift
;;
--package=*)
_arg_package="${_key##--package=}"
;;
-p*)
_arg_package="${_key##-p}"
;;
-t|--title)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_title="$2"
shift
;;
--title=*)
_arg_title="${_key##--title=}"
;;
-t*)
_arg_title="${_key##-t}"
;;
-d|--description)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_description="$2"
shift
;;
--description=*)
_arg_description="${_key##--description=}"
;;
-d*)
_arg_description="${_key##-d}"
;;
-k|--keywords)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_keywords="$2"
shift
;;
--keywords=*)
_arg_keywords="${_key##--keywords=}"
;;
-k*)
_arg_keywords="${_key##-k}"
;;
-o|--organization)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_organization="$2"
shift
;;
--organization=*)
_arg_organization="${_key##--organization=}"
;;
-o*)
_arg_organization="${_key##-o}"
;;
-c|--copyright)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_copyright="$2"
shift
;;
--copyright=*)
_arg_copyright="${_key##--copyright=}"
;;
-c*)
_arg_copyright="${_key##-c}"
;;
-w|--website)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_website="$2"
shift
;;
--website=*)
_arg_website="${_key##--website=}"
;;
-w*)
_arg_website="${_key##-w}"
;;
-n|--namespace)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_namespace="$2"
shift
;;
--namespace=*)
_arg_namespace="${_key##--namespace=}"
;;
-n*)
_arg_namespace="${_key##-n}"
;;
-a|--author)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_author="$2"
shift
;;
--author=*)
_arg_author="${_key##--author=}"
;;
-a*)
_arg_author="${_key##-a}"
;;
-e|--email)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_email="$2"
shift
;;
--email=*)
_arg_email="${_key##--email=}"
;;
-e*)
_arg_email="${_key##-e}"
;;
-i|--authorsite)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_authorsite="$2"
shift
;;
--authorsite=*)
_arg_authorsite="${_key##--authorsite=}"
;;
-i*)
_arg_authorsite="${_key##-i}"
;;
-u|--output)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_output="$2"
shift
;;
--output=*)
_arg_output="${_key##--output=}"
;;
-u*)
_arg_output="${_key##-u}"
;;
-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
PACKAGENAME="${_arg_package}"
TITLE="${_arg_title}"
DESCRIPTION="${_arg_description}"
KEYWORDS="${_arg_description}"
ORGANIZATION="${_arg_organization}"
COPYRIGHT="${_arg_copyright}"
WEBSITE="${_arg_website}"
NAMESPACE="${_arg_namespace}"
AUTHOR="${_arg_author}"
AUTHOREMAIL="${_arg_email}"
AUTHORWEBSITE="${_arg_website}"
OUTPUTDIRECTORY="${_arg_output}"
red="\e[0;31m"
green="\e[0;32m"
yellow="\e[0;33m"
blue="\e[0;34m"
white="\e[1;37m"
TOA="\e[0m" # No Color
function logStd () {
echo -e "${white}$1${TOA}" 1>&2
}
function logError () {
echo -e "${red}$1${TOA}" 1>&2
}
function logWarn () {
echo -e "${yellow}$1${TOA}" 1>&2
}
function logInfo () {
echo -e "${green}$1${TOA}" 1>&2
}
function logDebug () {
echo -e "${blue}$1${TOA}" 1>&2
}
function logBanner(){
logInfo "============================================================================="
logStd "= ${1}"
logInfo "============================================================================="
}
## =============================================================================
## BUILD ISOLATED NODE ENV
## =============================================================================
## node platform settings
NODE_DIST=https://nodejs.org/dist/
NODE_ARCH=$(uname -m)
NODE_ARCH=${NODE_ARCH/86_}
NODE_OS=$OSTYPE
if [[ $OSTYPE = *"msys"* ]]; then
NODE_OS='win'
fi
if [[ $OSTYPE = *"cygwin"* ]]; then
NODE_OS='win'
fi
if [[ $OSTYPE = *"win32"* ]]; then
NODE_OS='win'
fi
if [[ $OSTYPE = *"linux"* ]]; then
NODE_OS='linux'
fi
if [[ $OSTYPE = *"darwin"* ]]; then
NODE_OS='darwin'
fi
depends="true"
if [[ $NODE_OS = "win" ]]; then
hash 7z 2>/dev/null
if [[ $? -ne 0 ]]; then
logError "Error: 7z is not installed."
logStd 'You can download the command line version of 7Zip from https://www.7-zip.org/download.html'
depends="false"
fi
else
hash jq 2>/dev/null
if [[ $? -ne 0 ]]; then
logError 'Error: jq is not installed.'
logStd 'You can download the command line version of jq from https://stedolan.github.io/jq'
depends="false"
fi
hash wget 2>/dev/null
if [[ $? -ne 0 ]]; then
echo $red 'Error: wget is not installed.'
if [[ $NODE_OS = "win" ]]; then
logStd 'You can download the command line version of wget from http://gnuwin32.sourceforge.net/packages/wget.htm'
else
logStd 'You should install wget using your OS package manager of choice..'
fi
depends="false"
fi
fi
if [[ "${depends}" != "true" ]]; then
logError "THERE ARE MISSIGN DEPENDENCIES!!"
exit -1
fi
## get node versions available
version_json=$(wget --quiet -O- "https://nodejs.org/dist/index.json")
## override node version from command line
if [[ $_arg_nodejs ]]; then
NODE_VER=$_arg_nodejs
logInfo "Looking for node version: [${NODE_VER}]"
echo ${version_json} | jq -e '.[] | select(.version | contains("'${NODE_VER}'"))' > /dev/null
if [ $? -eq 0 ]; then
logInfo 'Node version OK...'
else
logInfo "Error: Node version [${NODE_VER}] could not be found..."
logStd "Availble versions include:"
echo
versions=$(echo ${version_json} | jq -e '.[].version')
logStd ${versions}
exit -1
fi
else
### get latest node version
version=$(echo ${version_json} | jq -e 'first(.[].version)')
version="${version%\"}"
NODE_VER=${version#\"}
logDebug "Latest node version is : ${NODE_VER}"
fi
set -e
## some settings to help with errors
if [[ $NODE_OS != "win" ]]; then
set -o errexit -o nounset -o noclobber -o pipefail
shopt -s nullglob
set -e
fi
mkdir -p "${_arg_root}"
cd "${_arg_root}"
## store node at the root of project
## remember to add this to your .gitignore
NODE_PATH=$PWD/node
## support Linux and Windows (MSYS2 bash) environments
## requires tar or 7z with wget
if [[ $NODE_OS != "win" ]]; then NODE_PATH="$NODE_PATH/bin"; fi
NPM_CONFIG_ROOT=$PWD/npmrc
## clean up existing installs
rm -f boot_node.sh
rm -rf $PWD/npmrc
rm -rf node
## create download url
if [[ $NODE_OS = "win" ]]; then
filestr="node-$NODE_VER-$NODE_OS-${NODE_ARCH}.7z"; output="node.7z";
else
filestr="node-${NODE_VER}-$NODE_OS-${NODE_ARCH}.tar.xz"; output="node.tar.xz";
fi
logBanner "Downloading Node: ${NODE_VER}"
## download node binary package
wget ${NODE_DIST}${NODE_VER}/${filestr} -O ${output}
logBanner "Extracting Node: ${NODE_VER}"
## extract to node install dir
if [[ $NODE_OS = "win" ]]; then
7z x node.7z; mv node-${NODE_VER}-${NODE_OS}-${NODE_ARCH} node; rm node.7z;
else
tar xvf node.tar.xz; mv node-${NODE_VER}-${NODE_OS}-${NODE_ARCH} node; rm node.tar.xz;
fi
logBanner "Creating env boot script in $PWD"
echo '#!/bin/bash' > boot_node.sh
echo export PATH=$NODE_PATH:$PWD/node:./node_modules/.bin:$PWD/node_modules/.bin:$PWD/npmrc/.npm_global:$PWD/npmrc/.npm_global/bin:$PATH >> boot_node.sh
echo export NPM_CONFIG_ROOT=$NPM_CONFIG_ROOT >> boot_node.sh
echo export NPM_CONFIG_USERCONFIG=$NPM_CONFIG_ROOT/.npmrc >> boot_node.sh
echo export NPM_CONFIG_GLOBALCONFIG=$NPM_CONFIG_ROOT/.npmrc >> boot_node.sh
echo export NPM_CONFIG_USERPREFIX=$NPM_CONFIG_ROOT/.npm_user >> boot_node.sh
echo export NPM_CONFIG_PREFIX=$NPM_CONFIG_ROOT/.npm_global >> boot_node.sh
echo export NPM_CONFIG_CACHE=$NPM_CONFIG_ROOT/.npm >> boot_node.sh
logBanner "Sourcing boot script..."
source ./boot_node.sh
logBanner "Installing yarn package manager into local node: ${NODE_VER}"
npm install yarn -g
echo -e '\n\n'
logBanner "Installation info for: ${NODE_VER}"
node --version
logInfo '============================================================================='
which node
which yarn
which npm
logInfo '============================================================================='
logBanner "Creating ${_arg_type} project [${_arg_package}]..."
if [[ ${_arg_type} = 'node' ]]; then
## we only want the node bits
exit 0
## =============================================================================
## Create command-line Typescript project
## =============================================================================
elif [[ ${_arg_type} = 'typescript' ]]; then
npx typescript-starter "${_arg_package}" -d "${_arg_description}" --strict --yarn --no-circleci --no-install --no-vscode --node
cd "${_arg_package}"
yarn install
elif [[ ${_arg_type} = 'electron' ]]; then
## =============================================================================
## Create Electron web app using Aurealia
## =============================================================================
## install UniteJS and gulp
## based on variables defined above
logBanner "Installing UniteJS"
yarn global add unitejs-cli
logBanner "Installing Gulp"
yarn global add gulp
## config UniteJS and generate project skeleton
logBanner "Configuring project"
unite configure --packageName="$PACKAGENAME" \
--profile=AureliaTypeScript \
--unitTestFramework=MochaChai \
--e2eTestFramework=MochaChai \
--packageManager=Yarn \
--title="$TITLE" \
--shortName="$PACKAGENAME" \
--description="$DESCRIPTION" \
--keywords="$KEYWORDS" \
--organization="$ORGANIZATION" \
--copyright="$COPYRIGHT" \
--webSite="$WEBSITE" \
--namespace="$NAMESPACE" \
--author="$AUTHOR" \
--authorEmail="$AUTHOREMAIL" \
--authorWebSite="$AUTHORWEBSITE" \
--outputDirectory="$OUTPUTDIRECTORY"
## change to project directory
cd webapp
logBanner "Add Electron platform to project"
## add electron
unite platform --operation=add --platformName=Electron
logBanner "Enter webapp directory ${_arg_output}"
## change to web app directory
cd www
## build web app
logBanner "Installing dependencies"
yarn install
logBanner "Installing Gulp"
yarn add gulp
logBanner "Building project"
gulp build
logBanner "Running unit tests"
gulp unit
logBanner "Running end to end tests"
gulp e2e-install --drivers=chrome@2.36
gulp e2e
logBanner "Building Electron app"
gulp platform-electron-dev
gulp build --buildConfiguration=prod
logBanner "Running end to end tests on app"
gulp e2e
logBanner "Packaging application"
gulp platform-electron-package --buildConfiguration=prod
fi
# ] <-- needed because of Argbash
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment