-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshared
More file actions
160 lines (134 loc) · 4.66 KB
/
shared
File metadata and controls
160 lines (134 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env bash
# Shared configuration, utilities, and guards for sandbox scripts
# shellcheck disable=SC2034 # Variables are used by sourcing scripts
# Resolve directories
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
SANDBOX_HOME="${SCRIPT_DIR}"
ROOT_DIR="$(pwd)"
refresh_root_paths() {
ROOT_DIR="${1:?root directory is required}"
CONFIG_FILE="${ROOT_DIR}/opencode-sandbox-config.yaml"
MISE_CONFIG_ROOT_FILE="${ROOT_DIR}/mise.toml"
# Read sandbox-name from opencode-sandbox-config.yaml
local sandbox_name=""
if [[ -f "${CONFIG_FILE}" ]]; then
while IFS= read -r line || [[ -n "${line}" ]]; do
# Match top-level key: no leading whitespace, key is "sandbox-name", space optional
if [[ "${line}" =~ ^sandbox-name:[[:space:]]*([^#[:space:]][^#]*) ]]; then
# Trim trailing whitespace and inline comments from captured value
sandbox_name="${BASH_REMATCH[1]}"
sandbox_name="${sandbox_name%%#*}"
sandbox_name="${sandbox_name%"${sandbox_name##*[! ]}"}"
break
fi
done < "${CONFIG_FILE}"
fi
if [[ -z "${sandbox_name}" ]]; then
if [[ -f "${CONFIG_FILE}" ]]; then
echo "ERROR: 'sandbox-name' is not set in ${CONFIG_FILE}" >&2
echo " Add a top-level entry to the file, e.g.:" >&2
echo " sandbox-name: my-project" >&2
echo " Run ocs-init to regenerate the config with a sandbox name if needed." >&2
return 1
fi
# Config file absent (e.g. during ocs-init before config is created) — leave paths unset
SANDBOX_ID=""
CONTAINER_NAME=""
OPENCODE_SANDBOX_DIR=""
OPENCODE_PASSWORD_FILE=""
MISE_CONFIG_SANDBOX_FILE=""
OPENCODE_STATE_DIR=""
return 0
fi
# Validate sandbox-name for Docker naming rules: lowercase letters, digits, hyphens only.
if [[ ! "${sandbox_name}" =~ ^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$ ]]; then
echo "ERROR: 'sandbox-name' value '${sandbox_name}' in ${CONFIG_FILE} is not valid." >&2
echo " Docker requires names to contain only lowercase letters, digits, and hyphens," >&2
echo " and must start and end with a letter or digit." >&2
echo " Example: sandbox-name: my-project" >&2
return 1
fi
# Compute SANDBOX_ID: combine sandbox-name with a short hash of the physical project root
# path. Using realpath ensures symlinks don't produce different IDs for the same checkout.
local config_dir
if command -v realpath >/dev/null 2>&1; then
config_dir="$(realpath "$(dirname "${CONFIG_FILE}")")"
else
config_dir="$(cd "$(dirname "${CONFIG_FILE}")" && pwd -P)"
fi
local dir_hash dir_hash_hex
dir_hash="$(printf '%s' "${config_dir}" | cksum | cut -d' ' -f1)"
dir_hash_hex="$(printf '%x' "${dir_hash}")"
SANDBOX_ID="${sandbox_name}-${dir_hash_hex:0:6}"
CONTAINER_NAME="opencode-sandbox-${SANDBOX_ID}"
OPENCODE_SANDBOX_DIR="${HOME}/.opencode-sandbox/${SANDBOX_ID}"
# File paths
OPENCODE_PASSWORD_FILE="${OPENCODE_SANDBOX_DIR}/opencode-password"
MISE_CONFIG_SANDBOX_FILE="${OPENCODE_SANDBOX_DIR}/mise.toml"
OPENCODE_STATE_DIR="${OPENCODE_SANDBOX_DIR}/opencode-state"
}
find_sandbox_root() {
local dir
dir="$(pwd)"
while [[ "${dir}" != "/" ]]; do
if [[ -f "${dir}/opencode-sandbox-config.yaml" ]]; then
printf '%s\n' "${dir}"
return 0
fi
dir="$(dirname "${dir}")"
done
if [[ -f "/opencode-sandbox-config.yaml" ]]; then
printf '/\n'
return 0
fi
return 1
}
use_sandbox_root() {
local detected_root
detected_root="$(find_sandbox_root)" || {
echo "No opencode-sandbox-config.yaml found in the current directory or any parent directory of $(pwd)." >&2
echo "Run ocs-init from your project root to initialize the sandbox first." >&2
return 1
}
refresh_root_paths "${detected_root}"
}
print_sandbox_dir() {
echo ">> using sandbox directory: ${OPENCODE_SANDBOX_DIR}"
}
refresh_root_paths "${ROOT_DIR}"
# Container runtime: prefer docker, fall back to podman
if command -v docker >/dev/null 2>&1; then
CONTAINER_RUNTIME=docker
elif command -v podman >/dev/null 2>&1; then
CONTAINER_RUNTIME=podman
else
echo "Neither docker nor podman found in PATH." >&2
exit 1
fi
# Network configuration
PORT=4096
LOCALHOST=127.0.0.1
open_url() {
local url="${1:?URL is required}"
local opener
local -a openers
case "$(uname -s)" in
Darwin)
openers=(open)
;;
Linux)
openers=(xdg-open open)
;;
*)
openers=(open xdg-open)
;;
esac
for opener in "${openers[@]}"; do
if command -v "${opener}" >/dev/null 2>&1; then
"${opener}" "${url}"
return 0
fi
done
echo "Could not find a supported browser opener. Install xdg-open or open the URL manually: ${url}" >&2
return 1
}