mirror of
https://github.com/okxlin/appstore.git
synced 2026-09-23 00:00:59 +00:00
96 lines
3.4 KiB
Bash
Executable File
96 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
|
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
|
|
|
|
read_env_value() {
|
|
local key="$1"
|
|
[[ -f "$ENV_FILE" ]] || return 0
|
|
local value
|
|
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
|
|
case "$value" in
|
|
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
|
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
|
esac
|
|
printf '%s\n' "$value"
|
|
}
|
|
|
|
configured_value() {
|
|
local key="$1"
|
|
local default_value="$2"
|
|
local value
|
|
value="${!key:-}"
|
|
if [[ -z "$value" ]]; then
|
|
value="$(read_env_value "$key")"
|
|
fi
|
|
printf '%s\n' "${value:-$default_value}"
|
|
}
|
|
|
|
resolve_app_path() {
|
|
local key="$1"
|
|
local raw="$2"
|
|
local clean candidate resolved current part
|
|
local -a parts=()
|
|
case "$raw" in
|
|
""|/*|.|..|../*|*/../*|*/..) echo "unsafe ${key} path" >&2; return 1 ;;
|
|
esac
|
|
if [[ "$raw" =~ [[:cntrl:]] ]]; then
|
|
echo "unsafe ${key} path" >&2
|
|
return 1
|
|
fi
|
|
clean="${raw#./}"
|
|
[[ -n "$clean" ]] || { echo "unsafe ${key} path" >&2; return 1; }
|
|
command -v realpath >/dev/null 2>&1 || { echo "realpath is required" >&2; return 1; }
|
|
candidate="$ROOT_DIR/$clean"
|
|
resolved="$(realpath -m -- "$candidate")" || { echo "unsafe ${key} path" >&2; return 1; }
|
|
case "$resolved" in
|
|
"$ROOT_DIR"/*) ;;
|
|
*) echo "unsafe ${key} path" >&2; return 1 ;;
|
|
esac
|
|
current="$ROOT_DIR"
|
|
IFS='/' read -r -a parts <<< "$clean"
|
|
for part in "${parts[@]}"; do
|
|
[[ -z "$part" || "$part" == "." ]] && continue
|
|
current="$current/$part"
|
|
if [[ -L "$current" ]]; then
|
|
echo "unsafe ${key} path" >&2
|
|
return 1
|
|
fi
|
|
done
|
|
printf '%s\n' "$resolved"
|
|
}
|
|
|
|
ensure_dir() {
|
|
local key="$1"
|
|
local raw
|
|
local path
|
|
raw="$(configured_value "$key" "$2")"
|
|
path="$(resolve_app_path "$key" "$raw")"
|
|
mkdir -p -- "$path"
|
|
[[ "$(resolve_app_path "$key" "$raw")" == "$path" ]] || { echo "unsafe ${key} path" >&2; return 1; }
|
|
}
|
|
|
|
ensure_dir "APP_DATA_DIR_1" "./data/workspace"
|
|
ensure_dir "APP_DATA_DIR_2" "./data/home-config"
|
|
ensure_dir "APP_DATA_DIR_3" "./data/home-share"
|
|
ensure_dir "APP_DATA_DIR_4" "./data/home-agents"
|
|
ensure_dir "APP_DATA_DIR_5" "./data/home-claude"
|
|
ensure_dir "APP_DATA_DIR_6" "./data/home-opencode"
|
|
|
|
CUSTOM_ENV_FILE_RAW="$(configured_value "CUSTOM_ENV_FILE" "./data/custom.env")"
|
|
CUSTOM_ENV_FILE_ABS="$(resolve_app_path "CUSTOM_ENV_FILE" "$CUSTOM_ENV_FILE_RAW")"
|
|
mkdir -p -- "$(dirname -- "$CUSTOM_ENV_FILE_ABS")"
|
|
touch -- "$CUSTOM_ENV_FILE_ABS"
|
|
|
|
echo '[opencode-workstation:init] initialized persistent directories:'
|
|
echo " $(resolve_app_path APP_DATA_DIR_1 "$(configured_value APP_DATA_DIR_1 "./data/workspace")") -> /workspace"
|
|
echo " $(resolve_app_path APP_DATA_DIR_2 "$(configured_value APP_DATA_DIR_2 "./data/home-config")") -> /home/opencode/.config"
|
|
echo " $(resolve_app_path APP_DATA_DIR_3 "$(configured_value APP_DATA_DIR_3 "./data/home-share")") -> /home/opencode/.local/share"
|
|
echo " $(resolve_app_path APP_DATA_DIR_4 "$(configured_value APP_DATA_DIR_4 "./data/home-agents")") -> /home/opencode/.agents"
|
|
echo " $(resolve_app_path APP_DATA_DIR_5 "$(configured_value APP_DATA_DIR_5 "./data/home-claude")") -> /home/opencode/.claude"
|
|
echo " $(resolve_app_path APP_DATA_DIR_6 "$(configured_value APP_DATA_DIR_6 "./data/home-opencode")") -> /home/opencode/.opencode"
|
|
echo " ${CUSTOM_ENV_FILE_ABS} -> custom env_file"
|
|
echo '[opencode-workstation:init] default serve address: http://0.0.0.0:4096'
|
|
echo '[opencode-workstation:init] ACP port: 8765'
|