refactor: use JSON file exchange instead of stdout parsing #234

Merged
shoko merged 1 commits from fix/issue-119 into main 2026-04-08 05:35:11 +02:00
4 changed files with 102 additions and 16 deletions

View File

@@ -139,6 +139,77 @@ validate_issue_ref() {
fi fi
} }
read_json_file() {
local file_path="$1"
if [ -f "$file_path" ]; then
cat "$file_path"
else
echo "{}"
fi
}
write_json_file() {
local file_path="$1"
local json_content="$2"
local temp_file="$file_path.tmp.$$"
printf '%s' "$json_content" > "$temp_file"
if ! python3 -c "import json; json.load(open('$temp_file'))" 2>/dev/null; then
echo "Error: write_json_file would create malformed JSON: $file_path" >&2
rm -f "$temp_file"
return 1
fi
mv "$temp_file" "$file_path"
}
get_json_value() {
local file_path="$1"
local key="$2"
local default="${3:-}"
if [ ! -f "$file_path" ]; then
echo "$default"
return
fi
python3 -c "import json; print(json.load(open('$file_path')).get('$key', '$default'))" 2>/dev/null || echo "$default"
}
set_json_value() {
local file_path="$1"
local key="$2"
local value="$3"
if [ ! -f "$file_path" ]; then
printf '{"%s": "%s"}\n' "$key" "$value" > "$file_path"
return
fi
python3 << PYEOF
import json
import sys
file_path = "$file_path"
key = "$key"
value = "$value"
try:
with open(file_path, 'r') as f:
data = json.load(f)
except:
data = {}
data[key] = value
with open(file_path, 'w') as f:
json.dump(data, f, indent=2)
print(f"Set $key = $value in $file_path")
PYEOF
}
update_session_pr_url() { update_session_pr_url() {
local issue_ref="$1" local issue_ref="$1"
local pr_url="$2" local pr_url="$2"

View File

@@ -34,6 +34,8 @@ release_lock() {
check_task_completion() { check_task_completion() {
local item="$1" local item="$1"
local queue_id=$(basename "$item" .json) local queue_id=$(basename "$item" .json)
local item_data=$(read_json_file "$item")
local state=$(python3 -c "import json; print(json.load(open('$item')).get('state', ''))" 2>/dev/null) local state=$(python3 -c "import json; print(json.load(open('$item')).get('state', ''))" 2>/dev/null)
[ "$state" = "notified" ] || return 0 [ "$state" = "notified" ] || return 0

View File

@@ -239,23 +239,34 @@ create_session() {
return 1 return 1
fi fi
local before_json=$(opencode session list --format=json 2>/dev/null) local before_file="$KUGETSU_DIR/sessions/before$$.json"
local before_set=$(echo "$before_json" | python3 -c "import sys,json; sessions=json.load(sys.stdin); print('|'.join(s['id'] for s in sessions))" 2>/dev/null || echo "|") local after_file="$KUGETSU_DIR/sessions/after$$.json"
opencode session list --format=json > "$before_file" 2>/dev/null || printf '{}' > "$before_file"
opencode run --fork --session "$base_session" "new session" >/dev/null 2>&1 opencode run --fork --session "$base_session" "new session" >/dev/null 2>&1
sleep 1 sleep 1
local after_json=$(opencode session list --format=json 2>/dev/null) opencode session list --format=json > "$after_file" 2>/dev/null || printf '{}' > "$after_file"
local after_sessions=$(echo "$after_json" | python3 -c "import sys,json; sessions=json.load(sys.stdin); [print(s['id']) for s in sessions]" 2>/dev/null || true)
local new_session_id="" local new_session_id=$(python3 << PYEOF
while IFS= read -r sess; do import json
if [[ -n "$sess" ]] && [[ ! "$before_set" =~ \|${sess}\| ]]; then
new_session_id="$sess" with open("$before_file", 'r') as f:
before = json.load(f)
with open("$after_file", 'r') as f:
after = json.load(f)
before_ids = set(s['id'] for s in before)
for s in after:
if s['id'] not in before_ids:
print(s['id'])
break break
fi PYEOF
done <<< "$after_sessions" )
rm -f "$before_file" "$after_file"
echo "$new_session_id" echo "$new_session_id"
} }

View File

@@ -145,15 +145,17 @@ check_pr_status() {
token="${GITEA_TOKEN:-}" token="${GITEA_TOKEN:-}"
fi fi
local response local response_file="$KUGETSU_DIR/.pr_status_response_$$.json"
if [ -n "$token" ]; then if [ -n "$token" ]; then
response=$(curl -s -H "Authorization: token $token" "$api_url" 2>/dev/null || echo "{}") curl -s -H "Authorization: token $token" "$api_url" > "$response_file" 2>/dev/null || printf '{}' > "$response_file"
else else
response=$(curl -s "$api_url" 2>/dev/null || echo "{}") curl -s "$api_url" > "$response_file" 2>/dev/null || printf '{}' > "$response_file"
fi fi
local state=$(echo "$response" | python3 -c "import json, sys; d=json.load(sys.stdin); print(d.get('state', 'unknown'))" 2>/dev/null || echo "unknown") local state=$(python3 -c "import json; print(json.load(open('$response_file')).get('state', 'unknown'))" 2>/dev/null || echo "unknown")
local merged=$(echo "$response" | python3 -c "import json, sys; d=json.load(sys.stdin); print('true' if d.get('merged', False) else 'false')" 2>/dev/null || echo "false") local merged=$(python3 -c "import json; print('true' if json.load(open('$response_file')).get('merged', False) else 'false')" 2>/dev/null || echo "false")
rm -f "$response_file"
if [ "$merged" = "true" ]; then if [ "$merged" = "true" ]; then
echo "merged" echo "merged"