Compare commits
10 Commits
59061a9c03
...
990bc46477
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
990bc46477 | ||
| e1050cb70a | |||
| caf1e9cdcd | |||
| 73f9c03e18 | |||
|
|
b2f2df7b06 | ||
|
|
2060c4ffbe | ||
|
|
c0d4314933 | ||
|
|
0f66de2929 | ||
|
|
74468af7c8 | ||
|
|
e184b1e5b0 |
@@ -47,6 +47,7 @@ A default config file is created during `kugetsu init` with commented examples:
|
|||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
|----------|---------|-------------|
|
|----------|---------|-------------|
|
||||||
| `MAX_CONCURRENT_AGENTS` | 3 | Maximum number of concurrent dev agents |
|
| `MAX_CONCURRENT_AGENTS` | 3 | Maximum number of concurrent dev agents |
|
||||||
|
| `KUGETSU_TEMP_DIR` | `~/.local/share/opencode/tool-output` | Temp directory for subagent tool output (useful in headless environments where /tmp is restricted) |
|
||||||
|
|
||||||
### Environment Variables for Agents
|
### Environment Variables for Agents
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ INDEX_FILE="$KUGETSU_DIR/index.json"
|
|||||||
NOTIFICATIONS_FILE="$KUGETSU_DIR/notifications.json"
|
NOTIFICATIONS_FILE="$KUGETSU_DIR/notifications.json"
|
||||||
LOGS_DIR="$KUGETSU_DIR/logs"
|
LOGS_DIR="$KUGETSU_DIR/logs"
|
||||||
ENV_DIR="${ENV_DIR:-$KUGETSU_DIR/env}"
|
ENV_DIR="${ENV_DIR:-$KUGETSU_DIR/env}"
|
||||||
|
QUEUE_FILE="$KUGETSU_DIR/queue.json"
|
||||||
|
LOCKS_DIR="$KUGETSU_DIR/locks"
|
||||||
MAX_CONCURRENT_AGENTS="${MAX_CONCURRENT_AGENTS:-3}"
|
MAX_CONCURRENT_AGENTS="${MAX_CONCURRENT_AGENTS:-3}"
|
||||||
|
POLL_INTERVAL="${POLL_INTERVAL:-600}"
|
||||||
|
|
||||||
# Load user config overrides (~/.kugetsu/config)
|
# Load user config overrides (~/.kugetsu/config)
|
||||||
if [ -f "$KUGETSU_DIR/config" ]; then
|
if [ -f "$KUGETSU_DIR/config" ]; then
|
||||||
@@ -56,6 +59,87 @@ count_active_dev_sessions() {
|
|||||||
echo "$count"
|
echo "$count"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acquire_lock() {
|
||||||
|
local issue_ref="$1"
|
||||||
|
local session_id="$2"
|
||||||
|
local lock_file="$LOCKS_DIR/${issue_ref//[^a-zA-Z0-9._-]/_}.lock"
|
||||||
|
|
||||||
|
mkdir -p "$LOCKS_DIR"
|
||||||
|
|
||||||
|
if [ -f "$lock_file" ]; then
|
||||||
|
local lock_pid=$(cat "$lock_file" 2>/dev/null | cut -d: -f1)
|
||||||
|
local lock_session=$(cat "$lock_file" 2>/dev/null | cut -d: -f2)
|
||||||
|
|
||||||
|
if [ -n "$lock_pid" ] && ! kill -0 "$lock_pid" 2>/dev/null; then
|
||||||
|
echo "Stale lock detected, removing..."
|
||||||
|
rm -f "$lock_file"
|
||||||
|
elif [ "$lock_session" = "$session_id" ]; then
|
||||||
|
echo "Already holding lock for $issue_ref"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "Error: $issue_ref is locked by session $lock_session (PID $lock_pid)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${BASHPID}:${session_id}:$(date +%s)" > "$lock_file"
|
||||||
|
echo "Lock acquired for $issue_ref: $lock_file"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
release_lock() {
|
||||||
|
local issue_ref="$1"
|
||||||
|
local lock_file="$LOCKS_DIR/${issue_ref//[^a-zA-Z0-9._-]/_}.lock"
|
||||||
|
|
||||||
|
if [ ! -f "$lock_file" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local lock_pid=$(cat "$lock_file" 2>/dev/null | cut -d: -f1)
|
||||||
|
|
||||||
|
if [ "$lock_pid" = "$BASHPID" ]; then
|
||||||
|
rm -f "$lock_file"
|
||||||
|
echo "Lock released for $issue_ref"
|
||||||
|
else
|
||||||
|
echo "Error: Cannot release lock held by PID $lock_pid (current: $BASHPID)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
release_all_locks() {
|
||||||
|
local session_id="$1"
|
||||||
|
if [ ! -d "$LOCKS_DIR" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
for lock_file in "$LOCKS_DIR"/*.lock; do
|
||||||
|
[ -f "$lock_file" ] || continue
|
||||||
|
local lock_session=$(cat "$lock_file" 2>/dev/null | cut -d: -f2)
|
||||||
|
if [ "$lock_session" = "$session_id" ]; then
|
||||||
|
rm -f "$lock_file"
|
||||||
|
echo "Released stale lock: $(basename "$lock_file")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
check_lock() {
|
||||||
|
local issue_ref="$1"
|
||||||
|
local lock_file="$LOCKS_DIR/${issue_ref//[^a-zA-Z0-9._-]/_}.lock"
|
||||||
|
|
||||||
|
if [ -f "$lock_file" ]; then
|
||||||
|
local lock_pid=$(cat "$lock_file" 2>/dev/null | cut -d: -f1)
|
||||||
|
local lock_session=$(cat "$lock_file" 2>/dev/null | cut -d: -f2)
|
||||||
|
|
||||||
|
if [ -n "$lock_pid" ] && ! kill -0 "$lock_pid" 2>/dev/null; then
|
||||||
|
echo "Stale lock detected, removing..."
|
||||||
|
rm -f "$lock_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "Locked by session $lock_session (PID $lock_pid)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat << 'EOF'
|
cat << 'EOF'
|
||||||
kugetsu - OpenCode Session Manager (Issue-Driven)
|
kugetsu - OpenCode Session Manager (Issue-Driven)
|
||||||
@@ -563,8 +647,10 @@ cmd_delegate() {
|
|||||||
mkdir -p "$LOGS_DIR"
|
mkdir -p "$LOGS_DIR"
|
||||||
local log_file="$LOGS_DIR/delegate-$(date +%s).log"
|
local log_file="$LOGS_DIR/delegate-$(date +%s).log"
|
||||||
|
|
||||||
|
local temp_dir="${KUGETSU_TEMP_DIR:-$HOME/.local/share/opencode/tool-output}"
|
||||||
|
|
||||||
mkdir -p "$ENV_DIR"
|
mkdir -p "$ENV_DIR"
|
||||||
local env_sh="set -a; "
|
local env_sh="set -a; export KUGETSU_TEMP_DIR='$temp_dir'; "
|
||||||
if [ -f "$ENV_DIR/pm-agent.env" ]; then
|
if [ -f "$ENV_DIR/pm-agent.env" ]; then
|
||||||
env_sh="${env_sh}source '$ENV_DIR/pm-agent.env'; "
|
env_sh="${env_sh}source '$ENV_DIR/pm-agent.env'; "
|
||||||
elif [ -f "$ENV_DIR/default.env" ]; then
|
elif [ -f "$ENV_DIR/default.env" ]; then
|
||||||
@@ -593,6 +679,116 @@ cmd_logs() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_queue() {
|
||||||
|
if [ ! -f "$QUEUE_FILE" ]; then
|
||||||
|
cat > "$QUEUE_FILE" << 'EOF'
|
||||||
|
{
|
||||||
|
"dev_followups": [],
|
||||||
|
"user_interrupts": [],
|
||||||
|
"background": []
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_queue() {
|
||||||
|
local action="${1:-}"
|
||||||
|
|
||||||
|
init_queue
|
||||||
|
|
||||||
|
case "$action" in
|
||||||
|
""|"list")
|
||||||
|
local total=0
|
||||||
|
echo "Queue status:"
|
||||||
|
for tier in dev_followups user_interrupts background; do
|
||||||
|
local count=$(python3 -c "import json; d=json.load(open('$QUEUE_FILE')); print(len(d.get('$tier', [])))" 2>/dev/null || echo 0)
|
||||||
|
total=$((total + count))
|
||||||
|
if [ "$count" -eq 0 ]; then
|
||||||
|
echo " $tier (0): (empty)"
|
||||||
|
else
|
||||||
|
echo " $tier ($count):"
|
||||||
|
python3 -c "import json, sys; d=json.load(open('$QUEUE_FILE')); [print(f' [{t[\"id\"]}] {t[\"message\"][:60]}') for t in d.get('$tier', [])]" 2>/dev/null || echo " (error reading)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "Total queued: $total"
|
||||||
|
;;
|
||||||
|
"enqueue")
|
||||||
|
local tier="${2:-}"
|
||||||
|
local message="${3:-}"
|
||||||
|
if [ -z "$tier" ] || [ -z "$message" ]; then
|
||||||
|
echo "Usage: kugetsu queue enqueue <tier> <message>" >&2
|
||||||
|
echo " tier: dev_followups, user_interrupts, or background" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! "$tier" =~ ^(dev_followups|user_interrupts|background)$ ]]; then
|
||||||
|
echo "Error: Invalid tier '$tier'" >&2
|
||||||
|
echo " Valid tiers: dev_followups, user_interrupts, background" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
local id="qe-$(date +%s)-$$"
|
||||||
|
python3 << EOF
|
||||||
|
import json
|
||||||
|
with open('$QUEUE_FILE', 'r') as f:
|
||||||
|
d = json.load(f)
|
||||||
|
d.setdefault('$tier', []).append({
|
||||||
|
'id': '$id',
|
||||||
|
'message': '$message',
|
||||||
|
'created': '$(date -Iseconds)'
|
||||||
|
})
|
||||||
|
with open('$QUEUE_FILE', 'w') as f:
|
||||||
|
json.dump(d, f, indent=2)
|
||||||
|
print('Enqueued to $tier: [$id] $message')
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
"dequeue")
|
||||||
|
local tier="${2:-}"
|
||||||
|
local result=$(python3 << EOF
|
||||||
|
import json
|
||||||
|
with open('$QUEUE_FILE', 'r') as f:
|
||||||
|
d = json.load(f)
|
||||||
|
tiers = ['dev_followups', 'user_interrupts', 'background'] if not '$tier' else ['$tier']
|
||||||
|
for t in tiers:
|
||||||
|
if d.get(t) and len(d[t]) > 0:
|
||||||
|
task = d[t].pop(0)
|
||||||
|
with open('$QUEUE_FILE', 'w') as f:
|
||||||
|
json.dump(d, f, indent=2)
|
||||||
|
print(f'{t}|{task["id"]}|{task["message"]}')
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print('Queue empty')
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
if [ "$result" = "Queue empty" ]; then
|
||||||
|
echo "$result"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$result"
|
||||||
|
;;
|
||||||
|
"clear")
|
||||||
|
cat > "$QUEUE_FILE" << 'EOF'
|
||||||
|
{
|
||||||
|
"dev_followups": [],
|
||||||
|
"user_interrupts": [],
|
||||||
|
"background": []
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo "Queue cleared"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: kugetsu queue <list|enqueue|dequeue|clear>" >&2
|
||||||
|
echo "" >&2
|
||||||
|
echo "Commands:" >&2
|
||||||
|
echo " list Show queue status" >&2
|
||||||
|
echo " enqueue <tier> <msg> Add task to queue" >&2
|
||||||
|
echo " dequeue [tier] Remove and return next task" >&2
|
||||||
|
echo " clear Clear all queued tasks" >&2
|
||||||
|
echo "" >&2
|
||||||
|
echo "Tiers: dev_followups, user_interrupts, background" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
cmd_env() {
|
cmd_env() {
|
||||||
local action="${1:-}"
|
local action="${1:-}"
|
||||||
local agent_type="${2:-}"
|
local agent_type="${2:-}"
|
||||||
@@ -695,12 +891,16 @@ cmd_env() {
|
|||||||
|
|
||||||
cmd_doctor() {
|
cmd_doctor() {
|
||||||
local fix=false
|
local fix=false
|
||||||
|
local fix_permissions=false
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--fix)
|
--fix)
|
||||||
fix=true
|
fix=true
|
||||||
;;
|
;;
|
||||||
|
--fix-permissions)
|
||||||
|
fix_permissions=true
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -798,6 +998,52 @@ cmd_doctor() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$fix_permissions" = true ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Fixing session permissions..."
|
||||||
|
fix_session_permissions
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fix_session_permissions() {
|
||||||
|
local opencode_db="${OPENCODE_DB:-$HOME/.opencode/opencode.db}"
|
||||||
|
|
||||||
|
if [ ! -f "$opencode_db" ]; then
|
||||||
|
echo "[ERROR] opencode database not found: $opencode_db"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local base_session_id=$(get_base_session_id)
|
||||||
|
local pm_agent_session_id=$(get_pm_agent_session_id)
|
||||||
|
|
||||||
|
local PERMISSION_JSON='[{"permission":"question","pattern":"*","action":"deny"},{"permission":"plan_enter","pattern":"*","action":"deny"},{"permission":"plan_exit","pattern":"*","action":"deny"},{"permission":"external_directory","pattern":"*","action":"allow"}]'
|
||||||
|
|
||||||
|
if [ -n "$base_session_id" ] && [ "$base_session_id" != "null" ]; then
|
||||||
|
echo "Updating base session permissions: $base_session_id"
|
||||||
|
python3 -c "
|
||||||
|
import sqlite3
|
||||||
|
conn = sqlite3.connect('$opencode_db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(\"UPDATE session SET permission = ? WHERE id = ?\", ('$PERMISSION_JSON', '$base_session_id'))
|
||||||
|
conn.commit()
|
||||||
|
print('[OK] Base session permissions updated')
|
||||||
|
"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$pm_agent_session_id" ] && [ "$pm_agent_session_id" != "null" ] && [ "$pm_agent_session_id" != "None" ]; then
|
||||||
|
echo "Updating PM agent session permissions: $pm_agent_session_id"
|
||||||
|
python3 -c "
|
||||||
|
import sqlite3
|
||||||
|
conn = sqlite3.connect('$opencode_db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(\"UPDATE session SET permission = ? WHERE id = ?\", ('$PERMISSION_JSON', '$pm_agent_session_id'))
|
||||||
|
conn.commit()
|
||||||
|
print('[OK] PM agent session permissions updated')
|
||||||
|
"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Session permissions fix complete"
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_MODE=false
|
DEBUG_MODE=false
|
||||||
@@ -1052,6 +1298,8 @@ EOF
|
|||||||
echo "Initialization complete!"
|
echo "Initialization complete!"
|
||||||
echo "- Base session: $new_session_id"
|
echo "- Base session: $new_session_id"
|
||||||
echo "- PM agent: ${new_pm_session_id:-created by hermes}"
|
echo "- PM agent: ${new_pm_session_id:-created by hermes}"
|
||||||
|
|
||||||
|
fix_session_permissions
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_start() {
|
cmd_start() {
|
||||||
@@ -1097,6 +1345,14 @@ cmd_start() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local worktree_path=$(issue_ref_to_worktree_path "$issue_ref")
|
local worktree_path=$(issue_ref_to_worktree_path "$issue_ref")
|
||||||
|
|
||||||
|
trap 'release_lock "$issue_ref" 2>/dev/null; exit' EXIT INT TERM
|
||||||
|
|
||||||
|
if ! acquire_lock "$issue_ref" "$base_session_id"; then
|
||||||
|
echo "Error: Could not acquire lock for '$issue_ref'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
create_worktree "$issue_ref"
|
create_worktree "$issue_ref"
|
||||||
|
|
||||||
local session_file="$(issue_ref_to_filename "$issue_ref").json"
|
local session_file="$(issue_ref_to_filename "$issue_ref").json"
|
||||||
@@ -1163,6 +1419,8 @@ cmd_start() {
|
|||||||
|
|
||||||
echo "Session started for '$issue_ref': $new_session_id"
|
echo "Session started for '$issue_ref': $new_session_id"
|
||||||
echo "Worktree: $worktree_path"
|
echo "Worktree: $worktree_path"
|
||||||
|
|
||||||
|
release_lock "$issue_ref"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_continue() {
|
cmd_continue() {
|
||||||
@@ -1416,6 +1674,7 @@ cmd_destroy() {
|
|||||||
|
|
||||||
if [ "$force" = true ]; then
|
if [ "$force" = true ]; then
|
||||||
remove_worktree_for_issue "$target"
|
remove_worktree_for_issue "$target"
|
||||||
|
release_lock "$target" 2>/dev/null || true
|
||||||
rm -f "$session_path"
|
rm -f "$session_path"
|
||||||
remove_issue_from_index "$target"
|
remove_issue_from_index "$target"
|
||||||
echo "Session for '$target' destroyed"
|
echo "Session for '$target' destroyed"
|
||||||
@@ -1425,6 +1684,7 @@ cmd_destroy() {
|
|||||||
read reply
|
read reply
|
||||||
if [ "$reply" = "y" ] || [ "$reply" = "Y" ]; then
|
if [ "$reply" = "y" ] || [ "$reply" = "Y" ]; then
|
||||||
remove_worktree_for_issue "$target"
|
remove_worktree_for_issue "$target"
|
||||||
|
release_lock "$target" 2>/dev/null || true
|
||||||
rm -f "$session_path"
|
rm -f "$session_path"
|
||||||
remove_issue_from_index "$target"
|
remove_issue_from_index "$target"
|
||||||
echo "Session for '$target' destroyed"
|
echo "Session for '$target' destroyed"
|
||||||
@@ -1469,6 +1729,9 @@ main() {
|
|||||||
server)
|
server)
|
||||||
cmd_server "$@"
|
cmd_server "$@"
|
||||||
;;
|
;;
|
||||||
|
queue)
|
||||||
|
cmd_queue "$@"
|
||||||
|
;;
|
||||||
env)
|
env)
|
||||||
cmd_env "$@"
|
cmd_env "$@"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -634,9 +634,70 @@ else
|
|||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Test E7: KUGETSU_TEMP_DIR is exported in cmd_delegate
|
||||||
|
echo "--- Test: KUGETSU_TEMP_DIR export in cmd_delegate ---"
|
||||||
|
if grep -q "KUGETSU_TEMP_DIR" "$KUGETSU" && grep -q "export KUGETSU_TEMP_DIR" "$KUGETSU"; then
|
||||||
|
pass "KUGETSU_TEMP_DIR is exported to delegated agents"
|
||||||
|
else
|
||||||
|
fail "KUGETSU_TEMP_DIR not found in cmd_delegate export"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Cleanup env files
|
# Cleanup env files
|
||||||
rm -rf ~/.kugetsu/env 2>/dev/null || true
|
rm -rf ~/.kugetsu/env 2>/dev/null || true
|
||||||
|
|
||||||
|
# Test E7: fix_session_permissions function exists
|
||||||
|
echo "--- Test: fix_session_permissions function exists ---"
|
||||||
|
if grep -q "fix_session_permissions()" "$KUGETSU"; then
|
||||||
|
pass "fix_session_permissions function exists"
|
||||||
|
else
|
||||||
|
fail "fix_session_permissions function not found"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test E8: cmd_doctor --fix-permissions flag is recognized
|
||||||
|
echo "--- Test: cmd_doctor --fix-permissions flag ---"
|
||||||
|
OUTPUT=$($KUGETSU doctor --fix-permissions 2>&1 || true)
|
||||||
|
if echo "$OUTPUT" | grep -q -E "(Fixing session permissions|Session permissions fix complete|opencode database not found)"; then
|
||||||
|
pass "cmd_doctor --fix-permissions flag is recognized"
|
||||||
|
else
|
||||||
|
fail "cmd_doctor --fix-permissions not recognized: $OUTPUT"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test E9: fix_session_permissions has valid permission JSON
|
||||||
|
echo "--- Test: fix_session_permissions has valid permission JSON ---"
|
||||||
|
PERMISSION_JSON='[{"permission":"question","pattern":"*","action":"deny"},{"permission":"plan_enter","pattern":"*","action":"deny"},{"permission":"plan_exit","pattern":"*","action":"deny"},{"permission":"external_directory","pattern":"*","action":"allow"}]'
|
||||||
|
if python3 -c "import json; json.loads('$PERMISSION_JSON')" 2>/dev/null; then
|
||||||
|
pass "fix_session_permissions has valid permission JSON"
|
||||||
|
else
|
||||||
|
fail "fix_session_permissions permission JSON is invalid"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test E10: fix_session_permissions SQL UPDATE syntax is valid
|
||||||
|
echo "--- Test: fix_session_permissions SQL UPDATE syntax ---"
|
||||||
|
if python3 -c "
|
||||||
|
import sqlite3
|
||||||
|
conn = sqlite3.connect(':memory:')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('CREATE TABLE session (id TEXT, permission TEXT)')
|
||||||
|
cursor.execute('INSERT INTO session (id, permission) VALUES (?, ?)', ('test_id', 'original'))
|
||||||
|
cursor.execute('UPDATE session SET permission = ? WHERE id = ?', ('$PERMISSION_JSON', 'test_id'))
|
||||||
|
conn.commit()
|
||||||
|
cursor.execute('SELECT permission FROM session WHERE id = ?', ('test_id',))
|
||||||
|
result = cursor.fetchone()
|
||||||
|
if result and 'external_directory' in result[0]:
|
||||||
|
print('OK')
|
||||||
|
else:
|
||||||
|
print('FAIL')
|
||||||
|
" 2>/dev/null | grep -q OK; then
|
||||||
|
pass "fix_session_permissions SQL UPDATE syntax is valid"
|
||||||
|
else
|
||||||
|
fail "fix_session_permissions SQL UPDATE syntax failed"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
cleanup
|
cleanup
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user