#!/usr/bin/env bash # Make sure the current directory is the location of this script to simplify matters cd "$(dirname $(readlink -f $0))"; if [ ! -d "${PWD}/.git" ]; then echo -e "\033[1m\033[31mError: The .git folder does not appear to exist. Please ensure you clone this repository with git, like this:\n\n\tgit clone https://github.com/ConnectedHumber/Air-Quality-Web.git\n\033[0m"; exit 1; fi ################ ### Settings ### ################ # The name of this project project_name="Air Quality Mapper"; # The path to the lantern build engine git submodule lantern_path="./lantern-build-engine"; ### # Custom Settings ### # Put any custom settings here. # Client-side build output cache_dir="./.cache"; build_output_folder="./app"; # Database settings for ssh port forwarding task database_host="db.connectedhumber.org"; database_name="aq_db"; # Minimum major version of npm min_npm_version_major="6"; ############################################################################### # Check out the lantern git submodule if needed if [ ! -f "${lantern_path}/lantern.sh" ]; then git submodule update --init "${lantern_path}"; fi source "${lantern_path}/lantern.sh"; if [[ "$#" -lt 1 ]]; then echo -e "${FBLE}${project_name}${RS} build script"; echo -e " by Starbeamrainbowlabs"; echo -e "${LC}Powered by the lantern build engine, v${version}${RS}"; echo -e ""; echo -e "${CSECTION}Usage${RS}"; echo -e " ./build ${CTOKEN}{action}${RS} ${CTOKEN}{action}${RS} ${CTOKEN}{action}${RS} ..."; echo -e ""; echo -e "${CSECTION}Available actions${RS}"; echo -e " ${CACTION}setup${RS} - Perform initial setup"; echo -e " ${CACTION}setup-dev${RS} - Perform additional setup for development environments. Run after ${CACTION}setup${RS}."; echo -e " ${CACTION}database${RS} - Connect to the database via SSH & open MariaDB CLI connection, prompting for a password"; echo -e " ${CACTION}dev-server${RS} - Start a development server"; echo -e " ${CACTION}dev-server-stop${RS} - Stop the currently running development server"; echo -e " ${CACTION}client${RS} - Build the client web app"; echo -e " ${CACTION}client-watch${RS} - Watch for changes to the client code & rebuild automatically"; echo -e " ${CACTION}docs${RS} - Render the documentation"; echo -e " ${CACTION}ci${RS} - Perform CI tasks"; echo -e " ${LC}${CACTION}archive${RS} - CI: Create release archive"; echo -e ""; exit 1; fi ############################################################################### # ███████ ███████ ████████ ██ ██ ██████ # ██ ██ ██ ██ ██ ██ ██ # ███████ █████ ██ ██ ██ ██████ # ██ ██ ██ ██ ██ ██ # ███████ ███████ ██ ██████ ██ task_download-composer() { if [ -f "${cache_dir}/composer" ]; then return 0; fi [ ! -d "${cache_dir}" ] && mkdir "${cache_dir}"; task_begin "Downloading composer"; curl "https://getcomposer.org/composer.phar" -o "${cache_dir}/composer"; exit_code=$?; chmod +x "${cache_dir}/composer"; task_end ${exit_code}; } task_setup() { stage_begin "Setting up"; task_begin "Checking environment"; check_command git true; check_command php true; check_command node true; check_command npm true; if [ ! -w "${PWD}" ]; then task_end 1 "${HC}${FRED}Error: Can't write to the repository directory! This usually you have a permission error of some kind. Try using sudo to run this build command as the user that owns this cloned repository."; fi npm_version_major="$(npm --version | head -c 1)"; if [[ "${npm_version_major}" -lt "${min_npm_version_major}" ]]; then echo "${FRED}${HC}Error: Your version of npm is too far out of date. You're running version $(npm --version), but version 6+ is required."; fi task_end $?; task_begin "Initialising submodules"; git submodule update --init; task_end $?; task_begin "Installing client dependencies"; echo -e "${HC}Not including developement dependencies. To complete setup for development, execute the ${CACTION}setup-dev${RS} ${HC}build task.${RS}"; npm install --production; task_end $?; tasks_run download-composer; task_begin "Installing server dependencies"; "${cache_dir}/composer" install --no-dev; task_end $?; if [ ! -d "./data" ]; then task_begin "Setting up initial data folder"; mkdir "./data"; chmod 0700 "./data"; echo -e "# -------[ Custom Settings File - Last updated $(date) ]-------" >"./data/settings.toml"; echo -e '[database]\nusername = "INSERT_DATABASE_USERNAME_HERE"\npassword = "INSERT_DATABASE_PASSWORD_HERE";' >>"./data/settings.toml"; chmod 0600 "./data/settings.toml"; echo -e "${HC}Don't forget to edit './data/settings.toml' to specify the database username and password${RS}"; echo -e ""; task_end $?; fi stage_end $?; } task_setup-dev() { task_begin "Checking environment"; check_command mysql true optional; task_end $?; task_begin "Installing client development dependencies"; npm install; task_end $?; task_begin "Installing server development dependencies"; "${cache_dir}/composer" install; task_end $?; } # ██████ ███████ ██ ██ # ██ ██ ██ ██ ██ # ██ ██ █████ ██ ██ # ██ ██ ██ ██ ██ # ██████ ███████ ████ task_database() { task_begin "Connecting to the database"; set-title "Database"; ssh -TN "${database_host}" -L 3306:localhost:3306 & ssh_pid=$!; sleep 1; mysql --host 127.0.0.1 --port 3306 --database "${database_name}" --user "${USER}" --password; kill "${ssh_pid}"; wait; sleep 0.5; task_end $?; } task_dev-server() { task_begin "Starting development server"; php -S [::1]:40482 & exit_code=$?; echo $! >/tmp/micro-lantern-dev-server.pid; task_end $?; # Should be 0 unless php died for some reason sleep 1; } task_dev-server-stop() { task_begin "Stopping development server"; kill "$(cat /tmp/micro-lantern-dev-server.pid)"; rm /tmp/micro-lantern-dev-server.pid; task_end $?; } # ██████ ██ ██ ███████ ███ ██ ████████ # ██ ██ ██ ██ ████ ██ ██ # ██ ██ ██ █████ ██ ██ ██ ██ # ██ ██ ██ ██ ██ ██ ██ ██ # ██████ ███████ ██ ███████ ██ ████ ██ task_client() { task_begin "Packaging Javascript"; node_modules/rollup/bin/rollup --sourcemap --config rollup.config.js; task_end $? "Error: rollup packing failed!"; task_begin "Copying html"; cp client_src/index.html "${build_output_folder}"; task_end $?; # task_begin "Copying css"; # # FUTURE: Package this up too? # cp -r client_src/css/ "${build_output_folder}"; # task_end $?; } task_client-watch() { set-title "Client Watcher"; echo -e "Watching for changes."; while :; do # : = infinite loop # Wait for an update # inotifywait's non-0 exit code forces an exit for some reason :-/ inotifywait -qr --event modify --format '%:e %f' client_src; # Rebuild the client code - spawn a sub-process to avoid the hard exit # This still doesn't work though, which is *really* annoying stage_begin "Rebuilding client code"; ./build client; stage_end $?; done } # ██████ ██████ ██████ ███████ # ██ ██ ██ ██ ██ ██ # ██ ██ ██ ██ ██ ███████ # ██ ██ ██ ██ ██ ██ # ██████ ██████ ██████ ███████ task_docs() { task_begin "Rendering docs"; node_modules/.bin/nightdocs --config nightdocs.toml; task_end $?; } # ██████ ██ # ██ ██ # ██ ██ # ██ ██ # ██████ ██ task_ci() { tasks_run setup setup-dev NODE_ENV="production" tasks_run client docs archive; } task_archive() { # We include the data directory here because we assume that this task is ONLY run in a CI environment, so it should only contain the default setup generated by an earlier task. tar -cafv "${ARCHIVE}/Air-Quality-Web.tar.gz" app/ __nightdocs/ lib/ logic/ vendor/ data/ *.php *.md LICENSE version settings.default.toml } ######################################################################### tasks_run $@;