From f8dd87318933390fa3eaff9000f8a14ccf36edbf Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Sat, 26 Sep 2026 20:41:03 -0700 Subject: [PATCH] Fixes modrinth publish script. --- .env.example | 21 +++++- tools/backup-server.sh | 43 +++++++++++- tools/deploy-plugin.sh | 39 ++++++++++- tools/publish-modrinth.sh | 133 +++++++++++++++++++++++++++++++------- tools/restore-server.sh | 43 +++++++++++- tools/setup-env.sh | 39 ----------- tools/start-server.sh | 45 ++++++++++++- 7 files changed, 289 insertions(+), 74 deletions(-) delete mode 100755 tools/setup-env.sh diff --git a/.env.example b/.env.example index 7fe0eda..da300c3 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,24 @@ -# Dev-server config for this project's tools/ scripts. -# Plain KEY=value only (no shell expansion). Environment variables take precedence. +# Configuration for tools/*.sh. Values are read as KEY=value data, not executed. +# Unquoted values may contain spaces; matching outer quotes are removed. +# Paper server PAPER_VERSION=26.2 PAPER_BUILD=129 +PAPER_USER_AGENT="majinnaibu-plugin-dev/1.0 (https://github.com/majinnaibu)" +JAVA_OPTS="-Xms2G -Xmx2G" +STOP_TIMEOUT=60 MINECRAFT_SERVER_JAR=paper-26.2-129.jar -# Relative paths are resolved from this directory; ~/ is expanded. +# Relative paths are resolved from the project root; ~/ is expanded. MINECRAFT_SERVER_PATH=./server MINECRAFT_BACKUP_PATH=./backups + +# Modrinth publishing +# Release version is read from Gradle and checked against the jar's plugin.yml. +MODRINTH_TOKEN= +MODRINTH_PROJECT_ID=5NYwxysp +MODRINTH_CHANGELOG="Release 0.2.2" +MODRINTH_GAME_VERSIONS=1.21,1.21.1,1.21.2,1.21.3,1.21.4,1.21.5,1.21.6,1.21.7 +MODRINTH_LOADERS=paper +MODRINTH_VERSION_TYPE= +MODRINTH_DEPENDENCIES= +MODRINTH_FILE= diff --git a/tools/backup-server.sh b/tools/backup-server.sh index 8ba750a..41234d1 100755 --- a/tools/backup-server.sh +++ b/tools/backup-server.sh @@ -8,8 +8,47 @@ set -euo pipefail TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=setup-env.sh -source "$TOOLS_DIR/setup-env.sh" +PROJECT_ROOT="$(cd "$TOOLS_DIR/.." && pwd)" +if [[ ! -r "$PROJECT_ROOT/.env" ]]; then + echo "Error: $PROJECT_ROOT/.env is missing or unreadable. Copy .env.example to .env and set its values." >&2 + exit 1 +fi +load_project_env() { + local env_line env_key env_value first_char last_char + while IFS= read -r env_line || [[ -n "$env_line" ]]; do + env_line="${env_line%$'\r'}" + [[ "$env_line" =~ ^[[:space:]]*(#|$) ]] && continue + [[ "$env_line" == *=* ]] || continue + + env_key="${env_line%%=*}" + env_value="${env_line#*=}" + env_key="${env_key#"${env_key%%[![:space:]]*}"}" + env_key="${env_key%"${env_key##*[![:space:]]}"}" + [[ "$env_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue + env_value="${env_value#"${env_value%%[![:space:]]*}"}" + env_value="${env_value%"${env_value##*[![:space:]]}"}" + + if (( ${#env_value} >= 2 )); then + first_char="${env_value:0:1}" + last_char="${env_value:$((${#env_value} - 1)):1}" + if [[ "$first_char" == "$last_char" && ( "$first_char" == '"' || "$first_char" == "'" ) ]]; then + env_value="${env_value:1:$((${#env_value} - 2))}" + fi + fi + + if [[ -z "${!env_key:-}" ]]; then + export "$env_key=$env_value" + fi + done < "$PROJECT_ROOT/.env" +} +load_project_env + +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH:-MCServer}" +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH/#\~/$HOME}" +[[ "$MINECRAFT_SERVER_PATH" == /* ]] || MINECRAFT_SERVER_PATH="$PROJECT_ROOT/$MINECRAFT_SERVER_PATH" +MINECRAFT_BACKUP_PATH="${MINECRAFT_BACKUP_PATH:-backups}" +MINECRAFT_BACKUP_PATH="${MINECRAFT_BACKUP_PATH/#\~/$HOME}" +[[ "$MINECRAFT_BACKUP_PATH" == /* ]] || MINECRAFT_BACKUP_PATH="$PROJECT_ROOT/$MINECRAFT_BACKUP_PATH" FORCE=false LABEL="" diff --git a/tools/deploy-plugin.sh b/tools/deploy-plugin.sh index 5844528..dc6dd6d 100755 --- a/tools/deploy-plugin.sh +++ b/tools/deploy-plugin.sh @@ -4,8 +4,43 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -# shellcheck source=setup-env.sh -source "$SCRIPT_DIR/setup-env.sh" +if [[ ! -r "$PROJECT_ROOT/.env" ]]; then + echo "Error: $PROJECT_ROOT/.env is missing or unreadable. Copy .env.example to .env and set its values." >&2 + exit 1 +fi +load_project_env() { + local env_line env_key env_value first_char last_char + while IFS= read -r env_line || [[ -n "$env_line" ]]; do + env_line="${env_line%$'\r'}" + [[ "$env_line" =~ ^[[:space:]]*(#|$) ]] && continue + [[ "$env_line" == *=* ]] || continue + + env_key="${env_line%%=*}" + env_value="${env_line#*=}" + env_key="${env_key#"${env_key%%[![:space:]]*}"}" + env_key="${env_key%"${env_key##*[![:space:]]}"}" + [[ "$env_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue + env_value="${env_value#"${env_value%%[![:space:]]*}"}" + env_value="${env_value%"${env_value##*[![:space:]]}"}" + + if (( ${#env_value} >= 2 )); then + first_char="${env_value:0:1}" + last_char="${env_value:$((${#env_value} - 1)):1}" + if [[ "$first_char" == "$last_char" && ( "$first_char" == '"' || "$first_char" == "'" ) ]]; then + env_value="${env_value:1:$((${#env_value} - 2))}" + fi + fi + + if [[ -z "${!env_key:-}" ]]; then + export "$env_key=$env_value" + fi + done < "$PROJECT_ROOT/.env" +} +load_project_env + +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH:-MCServer}" +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH/#\~/$HOME}" +[[ "$MINECRAFT_SERVER_PATH" == /* ]] || MINECRAFT_SERVER_PATH="$PROJECT_ROOT/$MINECRAFT_SERVER_PATH" if [[ -z "$MINECRAFT_SERVER_PATH" ]]; then echo "Error: MINECRAFT_SERVER_PATH environment variable is not set." diff --git a/tools/publish-modrinth.sh b/tools/publish-modrinth.sh index 7add438..6f2c33c 100755 --- a/tools/publish-modrinth.sh +++ b/tools/publish-modrinth.sh @@ -4,15 +4,44 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -# Load project config; credentials stay in the project .env. -# shellcheck source=setup-env.sh -source "$SCRIPT_DIR/setup-env.sh" +if [[ ! -r "$PROJECT_ROOT/.env" ]]; then + echo "Error: $PROJECT_ROOT/.env is missing or unreadable. Copy .env.example to .env and set its values." >&2 + exit 1 +fi +load_project_env() { + local env_line env_key env_value first_char last_char + while IFS= read -r env_line || [[ -n "$env_line" ]]; do + env_line="${env_line%$'\r'}" + [[ "$env_line" =~ ^[[:space:]]*(#|$) ]] && continue + [[ "$env_line" == *=* ]] || continue + + env_key="${env_line%%=*}" + env_value="${env_line#*=}" + env_key="${env_key#"${env_key%%[![:space:]]*}"}" + env_key="${env_key%"${env_key##*[![:space:]]}"}" + [[ "$env_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue + env_value="${env_value#"${env_value%%[![:space:]]*}"}" + env_value="${env_value%"${env_value##*[![:space:]]}"}" + + if (( ${#env_value} >= 2 )); then + first_char="${env_value:0:1}" + last_char="${env_value:$((${#env_value} - 1)):1}" + if [[ "$first_char" == "$last_char" && ( "$first_char" == '"' || "$first_char" == "'" ) ]]; then + env_value="${env_value:1:$((${#env_value} - 2))}" + fi + fi + + if [[ -z "${!env_key:-}" ]]; then + export "$env_key=$env_value" + fi + done < "$PROJECT_ROOT/.env" +} +load_project_env # Required env: # MODRINTH_TOKEN -# MODRINTH_PROJECT_ID or MODRINTH_PROJECT_SLUG -# MODRINTH_VERSION -# MODRINTH_GAME_VERSIONS (optional, comma-separated list, default from project set) +# MODRINTH_PROJECT_ID (project ID or slug) +# MODRINTH_GAME_VERSIONS (optional comma-separated list; defaults to 1.21 through 1.21.7) # MODRINTH_LOADERS (optional, comma-separated, default paper) # MODRINTH_CHANGELOG (optional) # Optional: @@ -20,19 +49,43 @@ source "$SCRIPT_DIR/setup-env.sh" # MODRINTH_FILE (optional path to the jar; defaults to build/libs/*.jar) MODRINTH_TOKEN="${MODRINTH_TOKEN:-}" -MODRINTH_PROJECT_ID="${MODRINTH_PROJECT_ID:-${MODRINTH_PROJECT_SLUG:-5NYwxysp}}" -MODRINTH_VERSION="${MODRINTH_VERSION:-${VERSION:-$(grep -E '^version=' gradle.properties | head -n1 | cut -d= -f2-)}}" +MODRINTH_PROJECT_ID="${MODRINTH_PROJECT_ID:-5NYwxysp}" MODRINTH_CHANGELOG="${MODRINTH_CHANGELOG:-Auto release via publish-modrinth.sh}" MODRINTH_GAME_VERSIONS="${MODRINTH_GAME_VERSIONS:-1.21,1.21.1,1.21.2,1.21.3,1.21.4,1.21.5,1.21.6,1.21.7}" MODRINTH_LOADERS="${MODRINTH_LOADERS:-paper}" +MODRINTH_VERSION_TYPE="${MODRINTH_VERSION_TYPE:-}" MODRINTH_FILE="${MODRINTH_FILE:-}" MODRINTH_DEPENDENCIES="${MODRINTH_DEPENDENCIES:-}" +MODRINTH_VERSION=$( + "$PROJECT_ROOT/gradlew" -q -p "$PROJECT_ROOT" properties --property version \ + | sed -n 's/^version: //p' +) +if [[ -z "$MODRINTH_VERSION" ]]; then + echo "Error: could not determine the project version from Gradle." >&2 + exit 1 +fi +if [[ -z "$MODRINTH_VERSION_TYPE" ]]; then + if [[ "$MODRINTH_VERSION" == *-* ]]; then + MODRINTH_VERSION_TYPE="beta" + else + MODRINTH_VERSION_TYPE="release" + fi +fi +case "$MODRINTH_VERSION_TYPE" in + release|beta|alpha) ;; + *) echo "Error: MODRINTH_VERSION_TYPE must be release, beta, or alpha." >&2; exit 1 ;; +esac +MODRINTH_VERSION_NAME="ScoreKeeper $MODRINTH_VERSION" + +if [[ -n "$MODRINTH_FILE" && "$MODRINTH_FILE" != /* ]]; then + MODRINTH_FILE="$PROJECT_ROOT/$MODRINTH_FILE" +fi + if [[ -z "$MODRINTH_TOKEN" ]]; then echo "Error: MODRINTH_TOKEN is not set in $PROJECT_ROOT/.env" >&2 exit 1 fi - if [[ -z "$MODRINTH_FILE" ]]; then MODRINTH_FILE=$(ls -t "$PROJECT_ROOT"/build/libs/*.jar 2>/dev/null | grep -v -- '-all\.jar$' | head -n1 || true) fi @@ -40,27 +93,61 @@ if [[ -z "$MODRINTH_FILE" || ! -f "$MODRINTH_FILE" ]]; then echo "Error: no jar found for Modrinth upload. Build the project first or set MODRINTH_FILE." >&2 exit 1 fi +if ! command -v unzip >/dev/null; then + echo "Error: 'unzip' is required to verify the plugin version in the jar." >&2 + exit 1 +fi +JAR_VERSION=$(unzip -p "$MODRINTH_FILE" plugin.yml 2>/dev/null | sed -n 's/^version: //p' | head -n1 || true) +if [[ -z "$JAR_VERSION" ]]; then + echo "Error: could not read the plugin version from $MODRINTH_FILE." >&2 + exit 1 +fi +if [[ "$JAR_VERSION" != "$MODRINTH_VERSION" ]]; then + echo "Error: jar version $JAR_VERSION does not match Gradle version $MODRINTH_VERSION. Rebuild the plugin and retry." >&2 + exit 1 +fi csv_to_json_array() { jq -cn --arg csv "$1" '$csv | split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0))' } MODRINTH_GAME_VERSIONS_JSON=$(csv_to_json_array "$MODRINTH_GAME_VERSIONS") MODRINTH_LOADERS_JSON=$(csv_to_json_array "$MODRINTH_LOADERS") - if [[ -n "$MODRINTH_DEPENDENCIES" ]]; then - MODRINTH_DEPENDENCIES_ARG=(--form "dependencies=$MODRINTH_DEPENDENCIES") + if ! MODRINTH_DEPENDENCIES_JSON=$(jq -ce 'if type == "array" then . else error("dependencies must be a JSON array") end' <<<"$MODRINTH_DEPENDENCIES"); then + echo "Error: MODRINTH_DEPENDENCIES must be a JSON array." >&2 + exit 1 + fi else - MODRINTH_DEPENDENCIES_ARG=() + MODRINTH_DEPENDENCIES_JSON='[]' fi -curl -fsSL \ - -X POST "https://api.modrinth.com/v2/version" \ - -H "Authorization: $MODRINTH_TOKEN" \ - -F "project_id=$MODRINTH_PROJECT_ID" \ - -F "version_number=$MODRINTH_VERSION" \ - -F "changelog=$MODRINTH_CHANGELOG" \ - -F "game_versions=${MODRINTH_GAME_VERSIONS_JSON}" \ - -F "loaders=${MODRINTH_LOADERS_JSON}" \ - -F "file=@$MODRINTH_FILE" \ - "${MODRINTH_DEPENDENCIES_ARG[@]}" \ - | jq . +MODRINTH_DATA=$(jq -cn \ + --arg project_id "$MODRINTH_PROJECT_ID" \ + --arg name "$MODRINTH_VERSION_NAME" \ + --arg version_number "$MODRINTH_VERSION" \ + --arg version_type "$MODRINTH_VERSION_TYPE" \ + --arg changelog "$MODRINTH_CHANGELOG" \ + --argjson featured false \ + --argjson dependencies "$MODRINTH_DEPENDENCIES_JSON" \ + --argjson game_versions "$MODRINTH_GAME_VERSIONS_JSON" \ + --argjson loaders "$MODRINTH_LOADERS_JSON" \ + '{project_id: $project_id, name: $name, version_number: $version_number, version_type: $version_type, featured: $featured, changelog: $changelog, dependencies: $dependencies, game_versions: $game_versions, loaders: $loaders, file_parts: ["file"], primary_file: "file"}') + +CURL_ARGS=( + -X POST "https://api.modrinth.com/v2/version" + -H "Authorization: $MODRINTH_TOKEN" + -F "data=$MODRINTH_DATA;type=application/json" + -F "file=@$MODRINTH_FILE" +) + +HTTP_RESPONSE=$(curl -sS -w $'\n%{http_code}' "${CURL_ARGS[@]}") +HTTP_STATUS="${HTTP_RESPONSE##*$'\n'}" +HTTP_BODY="${HTTP_RESPONSE%$'\n'*}" +if [[ "$HTTP_STATUS" != 2?? ]]; then + echo "Error: Modrinth API returned HTTP $HTTP_STATUS:" >&2 + if ! printf '%s\n' "$HTTP_BODY" | jq -r '.description // .error // .' >&2; then + printf '%s\n' "$HTTP_BODY" >&2 + fi + exit 1 +fi +printf '%s\n' "$HTTP_BODY" | jq . diff --git a/tools/restore-server.sh b/tools/restore-server.sh index 63403bf..0718b70 100755 --- a/tools/restore-server.sh +++ b/tools/restore-server.sh @@ -9,8 +9,47 @@ set -euo pipefail TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=setup-env.sh -source "$TOOLS_DIR/setup-env.sh" +PROJECT_ROOT="$(cd "$TOOLS_DIR/.." && pwd)" +if [[ ! -r "$PROJECT_ROOT/.env" ]]; then + echo "Error: $PROJECT_ROOT/.env is missing or unreadable. Copy .env.example to .env and set its values." >&2 + exit 1 +fi +load_project_env() { + local env_line env_key env_value first_char last_char + while IFS= read -r env_line || [[ -n "$env_line" ]]; do + env_line="${env_line%$'\r'}" + [[ "$env_line" =~ ^[[:space:]]*(#|$) ]] && continue + [[ "$env_line" == *=* ]] || continue + + env_key="${env_line%%=*}" + env_value="${env_line#*=}" + env_key="${env_key#"${env_key%%[![:space:]]*}"}" + env_key="${env_key%"${env_key##*[![:space:]]}"}" + [[ "$env_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue + env_value="${env_value#"${env_value%%[![:space:]]*}"}" + env_value="${env_value%"${env_value##*[![:space:]]}"}" + + if (( ${#env_value} >= 2 )); then + first_char="${env_value:0:1}" + last_char="${env_value:$((${#env_value} - 1)):1}" + if [[ "$first_char" == "$last_char" && ( "$first_char" == '"' || "$first_char" == "'" ) ]]; then + env_value="${env_value:1:$((${#env_value} - 2))}" + fi + fi + + if [[ -z "${!env_key:-}" ]]; then + export "$env_key=$env_value" + fi + done < "$PROJECT_ROOT/.env" +} +load_project_env + +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH:-MCServer}" +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH/#\~/$HOME}" +[[ "$MINECRAFT_SERVER_PATH" == /* ]] || MINECRAFT_SERVER_PATH="$PROJECT_ROOT/$MINECRAFT_SERVER_PATH" +MINECRAFT_BACKUP_PATH="${MINECRAFT_BACKUP_PATH:-backups}" +MINECRAFT_BACKUP_PATH="${MINECRAFT_BACKUP_PATH/#\~/$HOME}" +[[ "$MINECRAFT_BACKUP_PATH" == /* ]] || MINECRAFT_BACKUP_PATH="$PROJECT_ROOT/$MINECRAFT_BACKUP_PATH" ASSUME_YES=false SAFETY_BACKUP=true diff --git a/tools/setup-env.sh b/tools/setup-env.sh deleted file mode 100755 index c0d4405..0000000 --- a/tools/setup-env.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -# Source (bash or zsh) to export the shared server config from ../.env -# (relative to this script): -# PAPER_VERSION, PAPER_BUILD, MINECRAFT_SERVER_PATH, MINECRAFT_SERVER_JAR, MINECRAFT_BACKUP_PATH - -_setup_env_self="${BASH_SOURCE[0]:-${(%):-%x}}" -_setup_env_root="$(cd "$(dirname "$_setup_env_self")/.." && pwd)" -_setup_env_file="${MINECRAFT_ENV_FILE:-$_setup_env_root/.env}" - -if [[ -f "$_setup_env_file" ]]; then - while IFS= read -r _line || [[ -n "$_line" ]]; do - _line="${_line%$'\r'}" - [[ "$_line" =~ ^[[:space:]]*(#|$) ]] && continue - _key="${_line%%=*}" - _value="${_line#*=}" - _key="${_key//[[:space:]]/}" - [[ "$_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue - _value="${_value#\"}"; _value="${_value%\"}" - _value="${_value#\'}"; _value="${_value%\'}" - eval "_current=\"\${$_key:-}\"" - [[ -z "$_current" ]] && export "$_key=$_value" - done < "$_setup_env_file" -fi - -PAPER_VERSION="${PAPER_VERSION:-}" -PAPER_BUILD="${PAPER_BUILD:-}" -MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH:-MCServer}" -MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH/#\~/$HOME}" -[[ "$MINECRAFT_SERVER_PATH" == /* ]] || MINECRAFT_SERVER_PATH="$_setup_env_root/$MINECRAFT_SERVER_PATH" -MINECRAFT_BACKUP_PATH="${MINECRAFT_BACKUP_PATH:-backups}" -MINECRAFT_BACKUP_PATH="${MINECRAFT_BACKUP_PATH/#\~/$HOME}" -[[ "$MINECRAFT_BACKUP_PATH" == /* ]] || MINECRAFT_BACKUP_PATH="$_setup_env_root/$MINECRAFT_BACKUP_PATH" - -if [[ -z "${MINECRAFT_SERVER_JAR:-}" && -n "$PAPER_VERSION" && -n "$PAPER_BUILD" ]]; then - MINECRAFT_SERVER_JAR="paper-${PAPER_VERSION}-${PAPER_BUILD}.jar" -fi - -export PAPER_VERSION PAPER_BUILD MINECRAFT_SERVER_PATH MINECRAFT_SERVER_JAR MINECRAFT_BACKUP_PATH -unset _setup_env_self _setup_env_root _setup_env_file _line _key _value _current diff --git a/tools/start-server.sh b/tools/start-server.sh index d4ddce5..4f0dba1 100755 --- a/tools/start-server.sh +++ b/tools/start-server.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Downloads (if missing) and runs a Paper server via the Fill v3 API. -# Server settings come from ../.env relative to this script (see setup-env.sh). +# Server settings come from the project .env file. # # Env vars: # JAVA_OPTS Extra JVM args (default: -Xms2G -Xmx2G) @@ -8,8 +8,47 @@ set -euo pipefail TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=setup-env.sh -source "$TOOLS_DIR/setup-env.sh" +PROJECT_ROOT="$(cd "$TOOLS_DIR/.." && pwd)" +if [[ ! -r "$PROJECT_ROOT/.env" ]]; then + echo "Error: $PROJECT_ROOT/.env is missing or unreadable. Copy .env.example to .env and set its values." >&2 + exit 1 +fi +load_project_env() { + local env_line env_key env_value first_char last_char + while IFS= read -r env_line || [[ -n "$env_line" ]]; do + env_line="${env_line%$'\r'}" + [[ "$env_line" =~ ^[[:space:]]*(#|$) ]] && continue + [[ "$env_line" == *=* ]] || continue + + env_key="${env_line%%=*}" + env_value="${env_line#*=}" + env_key="${env_key#"${env_key%%[![:space:]]*}"}" + env_key="${env_key%"${env_key##*[![:space:]]}"}" + [[ "$env_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue + env_value="${env_value#"${env_value%%[![:space:]]*}"}" + env_value="${env_value%"${env_value##*[![:space:]]}"}" + + if (( ${#env_value} >= 2 )); then + first_char="${env_value:0:1}" + last_char="${env_value:$((${#env_value} - 1)):1}" + if [[ "$first_char" == "$last_char" && ( "$first_char" == '"' || "$first_char" == "'" ) ]]; then + env_value="${env_value:1:$((${#env_value} - 2))}" + fi + fi + + if [[ -z "${!env_key:-}" ]]; then + export "$env_key=$env_value" + fi + done < "$PROJECT_ROOT/.env" +} +load_project_env + +PAPER_VERSION="${PAPER_VERSION:-}" +PAPER_BUILD="${PAPER_BUILD:-}" +MINECRAFT_SERVER_JAR="${MINECRAFT_SERVER_JAR:-}" +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH:-MCServer}" +MINECRAFT_SERVER_PATH="${MINECRAFT_SERVER_PATH/#\~/$HOME}" +[[ "$MINECRAFT_SERVER_PATH" == /* ]] || MINECRAFT_SERVER_PATH="$PROJECT_ROOT/$MINECRAFT_SERVER_PATH" [[ -n "$PAPER_VERSION" ]] || { echo "Error: PAPER_VERSION is not set (see .env)." >&2; exit 1; }