File size: 6,557 Bytes
96d97a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env bash
# setup_e2e_env.sh — E2E environment builder for GOAL #60 (T1, spec §2).
#
# Builds the DISPOSABLE test ComfyUI root used by
# tests/e2e/test_e2e_install_flags.py. ENV BUILD ONLY: donor steps 4-5
# (editable pip install of the Manager + custom_nodes symlink) are
# deliberately DROPPED — the Manager is mounted via `git worktree add`
# by the `mount_worktree` session fixture in the test module, which is
# the SOLE owner of mount create/reuse/teardown (spec §2 T1
# single-ownership rule). This script never touches the Manager repo.
#
# Idempotent: re-run is a no-op when the marker + key artifacts exist
# (E2E-SC-01).
#
# Input env vars:
#   E2E_COMFYUI_ROOT — target directory (default: mktemp -d)
#   COMFYUI_BRANCH   — ComfyUI clone ref (default: master; Q-2)
#   PYTHON           — python executable for version probe (default: python3)
#
# Output (last line of stdout):
#   E2E_COMFYUI_ROOT=/path/to/environment
#
# Exit: 0=success, 1=failure

set -euo pipefail

COMFYUI_REPO="https://github.com/comfyanonymous/ComfyUI.git"
PYTORCH_CPU_INDEX="https://download.pytorch.org/whl/cpu"
# Minimal seed config. use_uv=false: the venv is seeded with pip
# (`uv venv --seed`), so the Manager's make_pip_cmd resolves to
# `<venv-python> -m pip` and the suite's pip-uninstall hygiene helpers
# work without uv on PATH at server runtime. The install flags are NOT
# seeded here — stage_flags.sh stages them per launch identity (SC-06).
CONFIG_INI_CONTENT="[default]

file_logging = false

use_uv = false"

log()  { echo "[setup_e2e] $*"; }
err()  { echo "[setup_e2e] ERROR: $*" >&2; }
die()  { err "$@"; exit 1; }

validate_prerequisites() {
    local py="${PYTHON:-python3}"
    local missing=()
    command -v git   >/dev/null 2>&1 || missing+=("git")
    command -v uv    >/dev/null 2>&1 || missing+=("uv")
    command -v "$py" >/dev/null 2>&1 || missing+=("$py")
    if [[ ${#missing[@]} -gt 0 ]]; then
        die "Missing prerequisites: ${missing[*]}"
    fi
    local py_version major minor
    py_version=$("$py" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
    major="${py_version%%.*}"
    minor="${py_version##*.}"
    if [[ "$major" -lt 3 ]] || { [[ "$major" -eq 3 ]] && [[ "$minor" -lt 9 ]]; }; then
        die "Python 3.9+ required, found $py_version"
    fi
    log "Prerequisites OK (python=$py_version)"
}

check_already_setup() {
    local root="$1"
    if [[ -f "$root/.e2e_setup_complete" ]] \
        && [[ -d "$root/comfyui" ]] \
        && [[ -d "$root/venv" ]] \
        && [[ -f "$root/comfyui/user/__manager/config.ini" ]]; then
        log "Environment already set up at $root (marker exists). Skipping. (E2E-SC-01 idempotence)"
        echo "E2E_COMFYUI_ROOT=$root"
        exit 0
    fi
}

verify_setup() {
    local root="$1"
    local venv_py="$root/venv/bin/python"
    local errors=0
    log "Running verification checks..."
    [[ -f "$root/comfyui/main.py" ]] || { err "Verification FAIL: comfyui/main.py not found"; ((errors+=1)); }
    [[ -x "$venv_py" ]] || { err "Verification FAIL: venv python not executable"; ((errors+=1)); }
    [[ -f "$root/comfyui/user/__manager/config.ini" ]] || { err "Verification FAIL: config.ini not found"; ((errors+=1)); }
    # venv must carry pip (uv venv --seed) — the suite's hygiene helpers
    # and the Manager's reservation-consuming boot both call `-m pip`.
    if ! "$venv_py" -m pip --version >/dev/null 2>&1; then
        err "Verification FAIL: venv pip not available"
        ((errors+=1))
    fi
    # comfy is a local package inside the ComfyUI checkout
    if ! PYTHONPATH="$root/comfyui" "$venv_py" -c "import comfy" 2>/dev/null; then
        err "Verification FAIL: 'import comfy' failed"
        ((errors+=1))
    fi
    # [D2] half-check at setup time: the Manager must NOT be pip-installed
    # into this venv (the worktree mount is the only delivery mechanism).
    if "$venv_py" -m pip show comfyui-manager >/dev/null 2>&1 \
        || "$venv_py" -m pip show ComfyUI-Manager >/dev/null 2>&1; then
        err "Verification FAIL: a pip-installed Manager exists in the venv (wrong layout for [D2])"
        ((errors+=1))
    fi
    if [[ "$errors" -gt 0 ]]; then
        die "Verification failed with $errors error(s)"
    fi
    log "Verification OK: all checks passed"
}

# ===== Main =====
validate_prerequisites

PYTHON="${PYTHON:-python3}"
COMFYUI_BRANCH="${COMFYUI_BRANCH:-master}"

CREATED_BY_US=false
if [[ -z "${E2E_COMFYUI_ROOT:-}" ]]; then
    E2E_COMFYUI_ROOT="$(mktemp -d -t e2e_comfyui_XXXXXX)"
    CREATED_BY_US=true
    log "Created E2E_COMFYUI_ROOT=$E2E_COMFYUI_ROOT"
else
    mkdir -p "$E2E_COMFYUI_ROOT"
    log "Using E2E_COMFYUI_ROOT=$E2E_COMFYUI_ROOT"
fi

check_already_setup "$E2E_COMFYUI_ROOT"

cleanup_on_failure() {
    local exit_code=$?
    if [[ "$exit_code" -ne 0 ]] && [[ "$CREATED_BY_US" == "true" ]]; then
        err "Setup failed. Cleaning up $E2E_COMFYUI_ROOT"
        rm -rf "$E2E_COMFYUI_ROOT"
    fi
}
trap cleanup_on_failure EXIT

log "Step 1/5: Cloning ComfyUI (branch=$COMFYUI_BRANCH)..."
if [[ -d "$E2E_COMFYUI_ROOT/comfyui/.git" ]]; then
    log "  ComfyUI already cloned, skipping"
else
    git clone --depth=1 --branch "$COMFYUI_BRANCH" "$COMFYUI_REPO" "$E2E_COMFYUI_ROOT/comfyui"
fi

log "Step 2/5: Creating virtual environment (seeded with pip)..."
if [[ -d "$E2E_COMFYUI_ROOT/venv" ]]; then
    log "  venv already exists, skipping"
else
    uv venv --seed "$E2E_COMFYUI_ROOT/venv"
fi
VENV_PY="$E2E_COMFYUI_ROOT/venv/bin/python"

log "Step 3/5: Installing ComfyUI dependencies (CPU-only torch index)..."
uv pip install \
    --python "$VENV_PY" \
    -r "$E2E_COMFYUI_ROOT/comfyui/requirements.txt" \
    --extra-index-url "$PYTORCH_CPU_INDEX"

log "Step 4/5: Writing seed config.ini + HOME isolation dirs..."
mkdir -p "$E2E_COMFYUI_ROOT/comfyui/user/__manager"
echo "$CONFIG_INI_CONTENT" > "$E2E_COMFYUI_ROOT/comfyui/user/__manager/config.ini"
mkdir -p "$E2E_COMFYUI_ROOT/home/.config"
mkdir -p "$E2E_COMFYUI_ROOT/home/.local/share"
mkdir -p "$E2E_COMFYUI_ROOT/logs"
mkdir -p "$E2E_COMFYUI_ROOT/comfyui/custom_nodes"

log "Step 5/5: Verifying setup..."
verify_setup "$E2E_COMFYUI_ROOT"

# Marker written ONLY after verification passes (E2E-SC-01)
date -Iseconds > "$E2E_COMFYUI_ROOT/.e2e_setup_complete"

trap - EXIT
log "Setup complete."
echo "E2E_COMFYUI_ROOT=$E2E_COMFYUI_ROOT"