Last active
May 19, 2019 14:19
-
-
Save olefasting/6e8263471887eadaa4e11921c66a6dcd to your computer and use it in GitHub Desktop.
Script for managing a VSCode project, based on Haxe, Heaps.io and CastleDB
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
#!/usr/bin/env bash | |
set -e | |
function on_error() { | |
echo "exit 1" | |
exit 1 | |
} | |
trap on_error ERR | |
function add_spaces() { | |
local to_s="$1" | |
local s="${to_s//./ }" | |
local s="${s//_/ }" | |
echo "$s" | |
unset to_s | |
unset s | |
return 0 | |
} | |
function uppercase_first() { | |
local to_uc="$1" | |
local arr=($(echo $to_uc | tr " " "\n")) | |
for w in "${arr[@]}"; do | |
local uc="${uc}"$(echo ${w}|cut -c1|tr [a-z] [A-Z]) | |
local uc="${uc}"$(echo ${w}|cut -c2-) | |
done | |
echo "$uc" | |
unset to_uc | |
unset arr | |
unset uc | |
return 0 | |
} | |
function to_camel_case() { | |
local to_cc="$1" | |
local cc=$(add_spaces "${to_cc}") | |
local cc=$(uppercase_first "${cc}") | |
local cc="${cc// /}" | |
echo "$cc" | |
unset cc | |
unset to_cc | |
return 0 | |
} | |
function create_file() { | |
local body="$1" | |
local path="$2" | |
[ -z "$body" ] && echo "Warning: No body specified when calling 'create_file' function for file '$path'" | |
if [ -z "$path" ]; then | |
echo "Error: No file path specified when calling 'create_file' function" | |
return 1 | |
fi | |
local dir="${path%/*}" | |
if [ "$path" != "$dir" ] && [ ! -e "$dir" ]; then | |
mkdir -p "$dir" | |
fi | |
echo "$body" > "$path" | |
unset dir | |
unset path | |
unset body | |
return 0 | |
} | |
function gen_js_vscode_launch_json() { | |
local body="\ | |
{ | |
// $APEX_CREATED_FILE_HEADER | |
\"version\": \"0.2.0\", | |
\"configurations\": [ | |
{ | |
\"type\": \"chrome\", | |
\"request\": \"launch\", | |
\"name\": \"Launch Chrome against localhost\", | |
\"url\": \"file://\${workspaceFolder}/$APEX_DIST_DIR/js/index.html\", | |
\"webRoot\": \"\${workspaceFolder}\" | |
} | |
] | |
}" | |
echo "$body" | |
unset body | |
return 0 | |
} | |
function gen_js_vscode_tasks_json() { | |
local body="\ | |
{ | |
// $APEX_CREATED_FILE_HEADER | |
\"version\": \"2.0.0\", | |
\"tasks\": [ | |
{ | |
\"type\": \"haxe\", | |
\"args\": \"active configuration\", | |
\"problemMatcher\": [ | |
\"\$haxe-absolute\", | |
\"\$haxe\", | |
\"\$haxe-error\", | |
\"\$haxe-trace\" | |
], | |
\"group\": { | |
\"kind\": \"build\", | |
\"isDefault\": true | |
} | |
} | |
] | |
}" | |
echo "$body" | |
unset body | |
return 0 | |
} | |
function gen_hl_vscode_launch_json() { | |
if [ "$APEX_HL_DEBUG_ATTACH" == "true" ]; then | |
local name="Attach to HashLink process" | |
local request=attach | |
else | |
local name="Launch with HashLink" | |
local request=launch | |
fi | |
local body="\ | |
{ | |
// $APEX_CREATED_FILE_HEADER | |
\"version\": \"0.2.0\", | |
\"configurations\": [ | |
{ | |
\"name\": \"$name\", | |
\"request\": \"$request\", | |
\"port\": $APEX_HL_DEBUG_PORT, | |
\"type\": \"hl\", | |
\"hxml\": \"$APEX_HXML_FNAME\", | |
\"cwd\": \"\${workspaceFolder}\", | |
\"preLaunchTask\": { | |
\"type\" : \"haxe\", | |
\"args\" : \"active configuration\" | |
} | |
} | |
] | |
}" | |
echo "$body" | |
unset body | |
unset request | |
unset name | |
return 0 | |
} | |
function gen_hl_vscode_tasks_json() { | |
local body="\ | |
{ | |
// $APEX_CREATED_FILE_HEADER | |
\"version\": \"2.0.0\", | |
\"tasks\": [ | |
{ | |
\"type\": \"hxml\", | |
\"file\": \"$APEX_HXML_FNAME\", | |
\"problemMatcher\": [ | |
\"\$haxe-absolute\", | |
\"\$haxe\", | |
\"\$haxe-error\", | |
\"\$haxe-trace\" | |
], | |
\"group\": { | |
\"kind\": \"build\", | |
\"isDefault\": true | |
} | |
} | |
] | |
}" | |
echo "$body" | |
unset body | |
return 0 | |
} | |
function create_vscode_config() { | |
[ -e .vscode ] && mkdir -p .vscode | |
case "$APEX_TARGET" in | |
"js") | |
create_file "$(gen_js_vscode_launch_json)" ".vscode/launch.json" | |
create_file "$(gen_js_vscode_tasks_json)" ".vscode/tasks.json" | |
;; | |
"hl") | |
create_file "$(gen_hl_vscode_launch_json)" ".vscode/launch.json" | |
create_file "$(gen_hl_vscode_tasks_json)" ".vscode/tasks.json" | |
;; | |
*) | |
echo "Error: Invalid or no target specified ($APEX_TARGET)" | |
esac | |
echo "!!! remember to install the Haxe Extension Pack for vscode !!!" | |
return 0 | |
} | |
function create_cdb_src() { | |
local mpath="$APEX_SRC_DIR" | |
[ ! -z "$APEX_CDB_SRC_PACKAGE" ] && local mpath="$mpath/$APEX_CDB_SRC_PACKAGE" | |
[ ! -e "$mpath" ] && mkdir -p "$mpath" | |
local loader_body="\ | |
/* $APEX_CREATED_FILE_HEADER */" | |
[ ! -z "$APEX_CDB_SRC_PACKAGE" ] && local loader_body="\ | |
$loader_body | |
package $APEX_CDB_SRC_PACKAGE;" | |
local loader_body="\ | |
$loader_body | |
class Loader { | |
public static function loadAll() {" | |
for f in "${APEX_CDB_FILES[@]}"; do | |
local body="\ | |
/* $APEX_CREATED_FILE_HEADER */" | |
[ ! -z "$APEX_CDB_SRC_PACKAGE" ] && local body="\ | |
$body | |
package $APEX_CDB_SRC_PACKAGE;" | |
local body="\ | |
$body | |
private typedef Init = haxe.macro.MacroType<[cdb.Module.build(\"$f\")]>;" | |
local fname="${f##*/}" | |
local mfname="${fname%.*}" | |
local mfname=$(to_camel_case "${mfname}") | |
create_file "$body" "$mpath/$mfname.hx" | |
local loader_body="$loader_body | |
$mfname.load(haxe.Resource.getString(\"$f\"));" | |
unset body | |
unset mfname | |
unset fname | |
done | |
local loader_body="$loader_body | |
} | |
}" | |
create_file "$loader_body" "$mpath/Loader.hx" | |
create_target_files | |
echo "!!! remember to call '$([ ! -z $APEX_CDB_SRC_PACKAGE ] && echo $APEX_CDB_SRC_PACKAGE.)Loader.loadAll' before accessing castledb data in code !!!" | |
echo | |
unset loader_body | |
unset mpath | |
return 0 | |
} | |
function gen_js_css() { | |
if [ -z "$APEX_WINDOW_SIZE" ]; then | |
local width="100%" | |
local height="100%" | |
else | |
local width="${APEX_WINDOW_SIZE%x*}px" | |
local height="${APEX_WINDOW_SIZE##*x}px" | |
fi | |
local body="\ | |
/* $APEX_CREATED_FILE_HEADER */ | |
html, body { | |
height: 100%; | |
} | |
body { | |
margin: 0; | |
padding: 0; | |
background-color: #000000; | |
} | |
#body-container { | |
height: 100%; | |
padding: 0; | |
margin: 0; | |
display: -webkit-box; | |
display: -moz-box; | |
display: -ms-flexbox; | |
display: -webkit-flex; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
#canvas-container { | |
width: $width; | |
} | |
canvas#webgl { | |
width: $width; | |
height: $height; | |
}" | |
echo "$body" | |
unset body | |
return 0 | |
} | |
function gen_js_html() { | |
local page_title="$APEX_NAME" | |
local js_fname="$APEX_SHORTNAME.js" | |
local body="\ | |
<!-- $APEX_CREATED_FILE_HEADER --> | |
<!DOCTYPE> | |
<html> | |
<head> | |
<meta charset=\"utf-8\" /> | |
<title>$page_title</title> | |
<link rel="stylesheet" type="text/css" href="style.css" /> | |
</head> | |
<body> | |
<div id=\"body-container\"> | |
<div id=\"canvas-container\"> | |
<canvas id=\"webgl\"></canvas> | |
<script type=\"text/javascript\" src=\"./$js_fname\"></script> | |
</div> | |
</div> | |
</body> | |
</html>" | |
echo "$body" | |
unset body | |
unset css | |
unset fname | |
unset page_title | |
return 0 | |
} | |
function gen_common_hxml() { | |
local common="\ | |
-cp $APEX_SRC_DIR | |
-D resourcePath=\"$APEX_RES_DIR\"" | |
[ "$APEX_ENV" == "production" ] && local common="\ | |
$common | |
-D analyzer-optimize" | |
[ -z "$APEX_WINDOW_SIZE" ] || local common="\ | |
$common | |
-D windowSize=$APEX_WINDOW_SIZE" | |
if [ "$APEX_USE_CDB" != "false" ]; then | |
for fname in "${APEX_CDB_FILES[@]}"; do | |
local common="\ | |
$common | |
-resource $fname" | |
done | |
fi | |
local common="\ | |
$common | |
-lib $APEX_LIBS | |
-main $APEX_ENTRY_FUNCTION" | |
echo "$common" | |
unset common | |
return 0 | |
} | |
function gen_js_hxml() { | |
local body=$(gen_common_hxml) | |
local body="\ | |
$body | |
--js $APEX_DIST_DIR/js/$APEX_SHORTNAME.js" | |
[ "$APEX_ENV" == "development" ] && local body="\ | |
$body | |
-debug" | |
echo "$body" | |
unset body | |
return 0 | |
} | |
function gen_hl_hxml() { | |
local body=$(gen_common_hxml) | |
local body="\ | |
$body | |
-hl $APEX_DIST_DIR/hl/$APEX_SHORTNAME.hl" | |
echo "$body" | |
unset body | |
return 0 | |
} | |
function setup_haxelib_repo() { | |
if [ ! -e $(which haxelib) ]; then | |
echo "Warning: The haxelib binary could not be found in \$PATH, please prepare haxelib repo manually, or install haxelib and run this script again" | |
else | |
echo "creating new haxelib repo" | |
haxelib newrepo | |
echo "installing dependencies" | |
local arr=( $APEX_LIBS ) | |
for lib in "${arr[@]}"; do | |
haxelib install "$lib" | |
done | |
fi | |
unset arr | |
return 0 | |
} | |
function create_target_files() { | |
case "$APEX_TARGET" in | |
"js") | |
[ ! -e "$APEX_DIST_DIR/$APEX_TARGET" ] && mkdir -p "$APEX_DIST_DIR/$APEX_TARGET" | |
create_file "$(gen_js_hxml)" "$APEX_HXML_FNAME" | |
create_file "$(gen_js_css)" "$APEX_DIST_DIR/js/style.css" | |
create_file "$(gen_js_html)" "$APEX_DIST_DIR/js/index.html" | |
return 0 | |
;; | |
"hl") | |
create_file "$(gen_hl_hxml)" "$APEX_HXML_FNAME" | |
return 0 | |
;; | |
*) | |
echo "Error: Invalid or no target specified ($APEX_TARGET)" | |
return 1 | |
esac | |
} | |
[ -f .env ] && source .env | |
[ -z "$APEX_SHORTNAME" ] && APEX_SHORTNAME="${PWD##*/}" | |
[ -z "$APEX_NAME" ] && APEX_NAME=$(to_camel_case "${APEX_SHORTNAME}") | |
case "$APEX_ENV" in | |
"prod"|"production") | |
APEX_ENV="production" | |
;; | |
#"dev"|"devel"|"development") | |
#;; | |
*) | |
APEX_ENV="development" | |
;; | |
esac | |
[ -z "$APEX_TARGET" ] && APEX_TARGET="js" | |
if [ -z "$APEX_LIBS" ]; then | |
APEX_LIBS="heaps" | |
[ "$APEX_TARGET" == "hl" ] && APEX_LIBS="hlsdl $APEX_LIBS" | |
fi | |
[ -z "$APEX_ENTRY_FUNCTION" ] && APEX_ENTRY_FUNCTION="Main" | |
[ -z "$APEX_HXML_FNAME" ] && APEX_HXML_FNAME="build.hxml" | |
[ -z "$APEX_SRC_DIR" ] && APEX_SRC_DIR="src" | |
[ ! -e "$APEX_SRC_DIR" ] && mkdir -p "$APEX_SRC_DIR" | |
[ -z "$APEX_DIST_DIR" ] && APEX_DIST_DIR="dist" | |
[ ! -e "$APEX_DIST_DIR" ] && mkdir -p "$APEX_DIST_DIR" | |
[ -z "$APEX_RES_DIR" ] && APEX_RES_DIR="res" | |
[ ! -e "$APEX_RES_DIR" ] && mkdir -p "$APEX_RES_DIR" | |
[ -z "$APEX_DATA_DIR" ] && APEX_DATA_DIR="data" | |
[ ! -e "$APEX_DATA_DIR" ] && mkdir -p "$APEX_DATA_DIR" | |
[ "$APEX_USE_CDB" != "false" ] && APEX_USE_CDB="true" | |
if [ "$APEX_USE_CDB" != "false" ]; then | |
[ -z "$APEX_CDB_SRC_PACKAGE" ] && APEX_CDB_SRC_PACKAGE="db" | |
APEX_CDB_FILES=( $(find "$APEX_DATA_DIR" -type f | grep .cdb) ) | |
[[ "$APEX_LIBS" =~ (castle) ]] || APEX_LIBS="$APEX_LIBS castle" | |
else | |
unset APEX_CDB_FILES | |
fi | |
[[ "$APEX_WINDOW_SIZE" =~ ^[0-9]{2,6}x[0-9]{2,6}$ ]] || unset APEX_WINDOW_SIZE | |
[ -z "$APEX_CREATED_FILE_HEADER" ] && APEX_CREATED_FILE_HEADER="This file was autogenerated by the $APEX_NAME management script, and it should not be modified" | |
[[ "$APEX_HL_DEBUG_PORT" =~ ^[0-9]{1,8}$ ]] || APEX_HL_DEBUG_PORT=6112 | |
[ "$APEX_HL_DEBUG_ATTACH" != "true" ] && APEX_HL_DEBUG_ATTACH=false | |
echo "'$APEX_NAME' project setup utility" | |
echo | |
case "$1" in | |
"vscode") | |
echo "starting vscode config setup" | |
echo | |
create_vscode_config | |
;; | |
"haxe") | |
echo "starting haxelib repo setup" | |
echo | |
rm -rf .haxelib | |
setup_haxelib_repo | |
echo | |
echo "haxelib repo setup successful!" | |
;; | |
"cdb") | |
if [ "$APEX_USE_CDB" != "true" ]; then | |
echo "cdb must be enabled by setting the env var 'APEX_USE_CDB' to \"true\" before cdb setup can be performed" | |
else | |
echo "starting cdb setup" | |
echo | |
create_cdb_src | |
case "$APEX_TARGET" in | |
"js") | |
create_file "$(gen_js_hxml)" "$APEX_HXML_FNAME" | |
;; | |
"hl") | |
create_file "$(gen_hl_hxml)" "$APEX_HXML_FNAME" | |
;; | |
*) | |
echo "Warning: Unable to determine target, so a new hxml file could not be generated" | |
;; | |
esac | |
echo "cdb setup successful!" | |
fi | |
;; | |
"full") | |
echo "starting full project setup" | |
echo | |
create_vscode_config | |
[ ! -e .haxelib ] && setup_haxelib_repo | |
[ "$APEX_USE_CDB" == "true" ] && create_cdb_src | |
create_target_files | |
echo "full project setup successful!" | |
;; | |
"cfg") | |
echo "env config (examine script src for more):" | |
echo " APEX_NAME = '$APEX_NAME'" | |
echo " APEX_ENV = '$APEX_ENV'" | |
echo " APEX_TARGET = '$APEX_TARGET'" | |
echo " APEX_HXML_FNAME = '$APEX_HXML_FNAME'" | |
echo " APEX_DIST_DIR = '$APEX_DIST_DIR'" | |
echo " APEX_RES_DIR = '$APEX_RES_DIR'" | |
[ -z "$APEX_CDB_FILES" ] || echo " APEX_CDB_FILES = '$APEX_CDB_FILES'" | |
[ -z "$APEX_WINDOW_SIZE" ] || echo " APEX_WINDOW_SIZE = '$APEX_WINDOW_SIZE'" | |
if [ "$APEX_TARGET" == "hl" ]; then | |
echo " APEX_HL_DEBUG_PORT = '$APEX_HL_DEBUG_PORT'" | |
echo " APEX_HL_DEBUG_ATTACH = '$APEX_HL_DEBUG_ATTACH'" | |
_hl_path=$(which hl) | |
if [ -e "$_hl_path" ]; then | |
echo | |
echo "hashlink appears to be installed ($_hl_path)" | |
else | |
echo | |
echo "WARNING: hashlink not found in PATH" | |
fi | |
unset _hl_path | |
fi | |
;; | |
*) | |
echo "management script for Visual Studio Code projects, based on" | |
echo "Haxe, Heaps.io and CastleDB" | |
echo | |
echo "usage:" | |
echo " $0 <command>" | |
echo | |
echo "commands:" | |
echo " vscode: visual studio code settings for building and debugging" | |
echo " haxe: haxelib repo setup (overwrites any existing repo)" | |
echo " cdb: castledb setup" | |
echo " full: full setup" | |
echo " cfg: show a summary of the env configuration" | |
echo | |
echo "copyright 2019 (c) Ole A. Sjo Fasting <oafasting@gmail.com>" | |
echo | |
echo "license: MIT" | |
;; | |
esac | |
echo | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment