Last active
October 11, 2018 20:38
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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