#!/usr/bin/env bash resolve_compose_env_path() { local env_path="${1:-}" local dir_part="" local base_part="" if [[ -z "${env_path}" ]]; then echo "" return 1 fi if [[ "${env_path}" == /* ]]; then echo "${env_path}" return 0 fi if [[ -e "${env_path}" ]]; then dir_part="$(cd "$(dirname "${env_path}")" && pwd)" base_part="$(basename "${env_path}")" echo "${dir_part}/${base_part}" return 0 fi dir_part="$(dirname "${env_path}")" base_part="$(basename "${env_path}")" if [[ -d "${dir_part}" ]]; then dir_part="$(cd "${dir_part}" && pwd)" echo "${dir_part}/${base_part}" return 0 fi echo "${env_path}" return 0 } read_compose_project_name_from_env() { local env_path="${1:-}" local line="" env_path="$(resolve_compose_env_path "${env_path}" || true)" if [[ -z "${env_path}" || ! -f "${env_path}" ]]; then return 1 fi line="$(grep -m1 -E '^COMPOSE_PROJECT_NAME=' "${env_path}" || true)" if [[ -z "${line}" ]]; then return 1 fi echo "${line#*=}" | tr -d '\r' } sanitize_compose_project_name() { local raw="${1:-}" raw="$(printf '%s' "${raw}" | tr '[:upper:]' '[:lower:]')" raw="$(printf '%s' "${raw}" | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')" if [[ -z "${raw}" ]]; then raw="nuqloud" fi if [[ ! "${raw}" =~ ^[a-z0-9] ]]; then raw="nc-${raw}" fi printf '%s\n' "${raw}" } derive_compose_project_name_seed() { local env_path="${1:-}" local base_dir="" env_path="$(resolve_compose_env_path "${env_path}" || true)" if [[ -n "${env_path}" ]]; then base_dir="$(basename "$(dirname "${env_path}")")" fi sanitize_compose_project_name "${base_dir}" } set_compose_project_name_in_env() { local env_path="${1:-}" local project_name="${2:-}" local escaped tmp env_path="$(resolve_compose_env_path "${env_path}" || true)" if [[ -z "${env_path}" || -z "${project_name}" ]]; then return 1 fi escaped="${project_name//\\/\\\\}" escaped="${escaped//&/\\&}" escaped="${escaped//|/\\|}" tmp="$(mktemp)" if grep -q -E '^COMPOSE_PROJECT_NAME=' "${env_path}"; then sed -E "s|^COMPOSE_PROJECT_NAME=.*$|COMPOSE_PROJECT_NAME=${escaped}|" "${env_path}" > "${tmp}" else cat "${env_path}" > "${tmp}" printf '\nCOMPOSE_PROJECT_NAME=%s\n' "${project_name}" >> "${tmp}" fi mv "${tmp}" "${env_path}" } export_compose_project_name_from_env() { local env_path="${1:-}" local project_name="" project_name="$(read_compose_project_name_from_env "${env_path}" || true)" if [[ -z "${project_name}" ]]; then project_name="$(derive_compose_project_name_seed "${env_path}")" export COMPOSE_PROJECT_NAME="${project_name}" return 1 fi export COMPOSE_PROJECT_NAME="${project_name}" return 0 } warn_missing_compose_project_name() { local env_path="${1:-}" local display_path="${env_path:-.env.devprod}" echo "Warning: COMPOSE_PROJECT_NAME is not set in ${display_path}." echo "Folder renames can attach a cloud to new Docker volumes." echo "Pin it with:" echo " ./scripts/ensure-compose-project-name.sh --env-file ${display_path} --project-name " }