#!/usr/bin/env bash set -eou pipefail check-deps() { local err=false if ! [[ -x "$(command -v psql)" ]]; then cat >&2 <<-__EOF__ Error: psql is not executable! Ensure it is installed and executable! __EOF__ err=true fi if ! [[ -x "$(command -v sqlx)" ]]; then cat >&2 <<-__EOF__ Error: sqlx is not executable! Install it with: cargo install --version=0.7.2 sqlx-cli --features postgres Then ensure it can be ran by you! __EOF__ err=true fi if [[ "${err}" == true ]]; then return 1 fi return 0 } init-db() { local container_name="${1}" local db_user="${2}" local db_password="${3}" local db_name="${4}" local db_port="${5}" local skip_docker="${6}" local check_deps_ret check_deps_ret=$(check-deps) if ((check_deps_ret != 0)); then printf "Missing some required dependencies, unable to setup a dev environment! Exiting.\n" >&2 exit "${check_deps_ret}" fi if ((skip_docker == 0)); then if docker container inspect "${container_name}" >/dev/null 2>&1; then printf "Container %s exists. Removing it.\n" "${container_name}" >&2 docker container stop "${container_name}" >/dev/null 2>&1 || true docker container rm "${container_name}" >/dev/null 2>&1 printf "Stopped container %s\n" "${container_name}" >&2 fi printf "Starting container %s\n" "${container_name}" docker run \ --name "${container_name}" \ -e POSTGRES_USER="${db_user}" \ -e POSTGRES_PASSWORD="${db_password}" \ -e POSTGRES_DB="${db_name}" \ -p "${db_port}":5432 \ -d postgres \ postgres -N 1000 >/dev/null printf "Container %s started\n" "${container_name}" fi local max_wait=10 local curr_attempts=0 until PGPASSWORD="${db_password}" psql -h "0.0.0.0" -U "${db_user}" -p "${db_port}" -d "postgres" -c '\q' >/dev/null 2>&1; do printf "Postgress is still unavailable -- waiting\n" >&2 curr_attempts=$((curr_attempts + 1)) if ((curr_attempts == max_wait)); then printf "Unable to contact the postgres container after %s seconds! Exiting.\n" "${max_wait}" >&2 exit 1 fi sleep 1 done printf "Postgres is up and running on port %s\n" "${db_port}" >&2 local db_url="postgres://${db_user}:${db_password}@0.0.0.0:${db_port}/${db_name}" printf "Creating database with sqlx\n" DATABASE_URL="${db_url}" sqlx database create printf "Database created\n" >&2 printf "Migrating database with sqlx\n" DATABASE_URL="${db_url}" sqlx migrate run printf "Finished migration\n" >&2 printf "Exporting Environment Variables\n" >&2 printf -- "-------------------------------\n" >&2 export DATABASE_URL="${db_url}" export APP__APPLICATION__HOST="localhost" export APP__APPLICATION__PORT="3000" export APP__DATABASE__HOST="localhost" export APP__DATABASE__PORT="${db_port}" export APP__DATABASE__USERNAME="${db_user}" export APP__DATABASE__PASSWORD="${db_password}" export APP__DATABASE__NAME="${db_name}" export APP__DATABASE__REQUIRE_SSL="false" for var in \ DATABASE_URL \ APP__APPLICATION__HOST \ APP__APPLICATION__PORT \ APP__DATABASE__HOST \ APP__DATABASE__PORT \ APP__DATABASE__USERNAME \ APP__DATABASE__PASSWORD \ APP__DATABASE__NAME \ APP__DATABASE__REQUIRE_SSL; do printf " Exported %s = %s\n" "${var}" "${!var}" done cat >&2 <<- __EOF__ ================================ Done Setting up Dev Environment! ================================ __EOF__ } usage() { cat <<-__EOF__ Usage: $(basename "${0}") -c Container-Name -u User -p DBPass -d DBName -P DBPort -c | --container-name Sets the name of the docker container to be ran. Example: --container-name "My New Container Name" -u | --db-user The username to use for the database. Example: --db-user "User" -p | --db-password The database user's password. As a note, do not use a live database with this. This is meant for a dev environment where exposing this password has little to no security impact. Example: --db-password "password" -d | --db-name The database name to use. Example: --db-name "My Database Name" -P | --db-port The port used to access the database. Example: --db-port 1337 -s | --skip-docker If this flag is used, all docker container setup will be skipped. Example: --skip-docker -h | --help | -? Shows this usage menu. Example: --help __EOF__ } main() { local container_name="${CONTAINER_NAME:="Whitelist-API-DB"}" local db_user="${DB_USER:=postgres}" local db_password="${DB_PASSWORD:=password}" local db_name="${DB_NAME:=whitelist}" local db_port="${DB_PORT:=5432}" local skip_docker="${SKIP_DOCKER:=0}" set +u while :; do case "${1}" in -h | -\? | --help) usage # Display a usage synopsis. exit ;; --) # End of all options. break ;; -c | --container-name) shift container_name="${1}" ;; -u | --db-user) shift db_user="${1}" ;; -p | --db-password) shift db_password="${1}" ;; -d | --db-name) shift db_name="${1}" ;; -P | --db-port) shift db_port="${1}" ;; -s | --skip-docker) shift skip_docker=1 ;; -?*) printf 'Unknown option: %s\n' "$1" >&2 usage exit 1 ;; *) # Default case: No more options, so break out of the loop. break ;; esac shift done set -u init-db "${container_name}" "${db_user}" "${db_password}" "${db_name}" "${db_port}" "${skip_docker}" } main "${@}"