juc500 정상동작
This commit is contained in:
+155
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env bash
|
||||
# JUC500 GUI 실행 (인자 없으면 GUI, 있으면 CLI로 전달)
|
||||
# macOS / Windows (Git Bash) 공통
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
is_windows() {
|
||||
case "$(uname -s 2>/dev/null || echo unknown)" in
|
||||
MINGW*|MSYS*|CYGWIN*) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_hint() {
|
||||
if is_windows; then
|
||||
echo " scripts\\setup_windows.bat (또는 ./start_win.sh 재실행 — 자동 설정)" >&2
|
||||
else
|
||||
echo " ./scripts/setup_macos.sh" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
# Windows zip 복사 후: Mac .venv 제거 + vendor 로 .venv 자동 생성
|
||||
if is_windows; then
|
||||
if [[ -f "$ROOT/scripts/bootstrap_windows.sh" ]]; then
|
||||
bash "$ROOT/scripts/bootstrap_windows.sh" || exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# venv Python 선택 (Windows: Scripts\python.exe, Unix: bin/python)
|
||||
# 크로스 OS로 복사된 .venv 대비 — 현재 플랫폼에 맞는 인터프리터만 고른다.
|
||||
PY=""
|
||||
if is_windows && [[ -f "$ROOT/.venv/Scripts/python.exe" ]]; then
|
||||
PY="$ROOT/.venv/Scripts/python.exe"
|
||||
elif [[ -x "$ROOT/.venv/bin/python" ]] && "$ROOT/.venv/bin/python" -c "import sys" 2>/dev/null; then
|
||||
PY="$ROOT/.venv/bin/python"
|
||||
elif command -v python3 >/dev/null 2>&1; then
|
||||
PY="$(command -v python3)"
|
||||
elif command -v python >/dev/null 2>&1; then
|
||||
PY="$(command -v python)"
|
||||
else
|
||||
echo "Python 이 없습니다. 먼저 설치하세요:" >&2
|
||||
setup_hint
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if is_windows; then
|
||||
if [[ ! -f "$ROOT/.venv/Scripts/python.exe" ]]; then
|
||||
echo "경고: .venv 없음 — 시스템 Python 사용. 문제가 있으면:" >&2
|
||||
setup_hint
|
||||
fi
|
||||
elif [[ ! -x "$ROOT/.venv/bin/python" ]]; then
|
||||
echo "경고: .venv 없음 — 시스템 Python 사용. 문제가 있으면:" >&2
|
||||
setup_hint
|
||||
fi
|
||||
|
||||
# Windows 네이티브 Python 은 PYTHONPATH 에 Win 경로·세미콜론을 기대
|
||||
if is_windows; then
|
||||
WINROOT=""
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
WINROOT="$(cygpath -w "$ROOT")"
|
||||
elif WINROOT="$(cd "$ROOT" && pwd -W 2>/dev/null)" && [[ -n "$WINROOT" ]]; then
|
||||
:
|
||||
else
|
||||
# MSYS /c/dev/juc500 → C:/dev/juc500 (Windows python 호환)
|
||||
WINROOT="$ROOT"
|
||||
if [[ "$WINROOT" =~ ^/([a-zA-Z])/(.*)$ ]]; then
|
||||
WINROOT="${BASH_REMATCH[1]}:/${BASH_REMATCH[2]}"
|
||||
fi
|
||||
fi
|
||||
export PYTHONPATH="${WINROOT}${PYTHONPATH:+;$PYTHONPATH}"
|
||||
export JUC500_ROOT="${WINROOT}"
|
||||
else
|
||||
export PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}"
|
||||
export JUC500_ROOT="$ROOT"
|
||||
fi
|
||||
|
||||
# Windows: libusb DLL 은 python.exe 옆에 있어야 pyusb 가 로드함
|
||||
if is_windows; then
|
||||
libusb_src="$ROOT/vendor/libusb-1.0.dll"
|
||||
py_dir="$(dirname "$PY")"
|
||||
libusb_dst="$py_dir/libusb-1.0.dll"
|
||||
if [[ -f "$libusb_src" ]]; then
|
||||
cp -f "$libusb_src" "$libusb_dst" 2>/dev/null || true
|
||||
echo "libusb-1.0.dll → $py_dir/"
|
||||
elif [[ ! -f "$libusb_dst" ]]; then
|
||||
echo "경고: vendor/libusb-1.0.dll 없음 — vendor/ 포함 zip 인지 확인하세요" >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
# editable install 가 예전 경로(C:\dev\juc500\juc500)를 가리키면 구버전이 로드됨 — 매 기동 시 현재 ROOT 로 고정
|
||||
if [[ -f "$ROOT/pyproject.toml" ]]; then
|
||||
pip_args=(-m pip install -e "$ROOT" --no-deps -q)
|
||||
if [[ -d "$ROOT/vendor/wheels" ]]; then
|
||||
pip_args+=(--no-index --find-links="$ROOT/vendor/wheels")
|
||||
fi
|
||||
"$PY" "${pip_args[@]}" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 의존성 빠른 확인
|
||||
if ! "$PY" -c "import usb" 2>/dev/null; then
|
||||
echo "pyusb 가 없습니다. 먼저 설치하세요:" >&2
|
||||
setup_hint
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if is_windows; then
|
||||
libusb_ok="$(
|
||||
"$PY" -c "
|
||||
from juc500_xfer.usb_link import libusb_path
|
||||
p = libusb_path()
|
||||
print(p or '')
|
||||
import sys
|
||||
sys.exit(0 if p else 1)
|
||||
" 2>/dev/null || true
|
||||
)"
|
||||
if [[ -z "$libusb_ok" ]]; then
|
||||
echo "libusb-1.0 를 로드하지 못했습니다. Windows에서:" >&2
|
||||
echo " scripts\\ensure_libusb_windows.bat" >&2
|
||||
echo " 또는 scripts\\setup_windows.bat" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "libusb: $libusb_ok"
|
||||
fi
|
||||
|
||||
# 기존 juc500 인스턴스가 IF5를 점유하면 Access denied 가 난다 — 먼저 종료
|
||||
kill_msg="$(
|
||||
"$PY" -c "
|
||||
from juc500_xfer.wormhole_kill import kill_other_juc500_processes
|
||||
r = kill_other_juc500_processes(force=True)
|
||||
print(r.get('message') or '')
|
||||
" 2>/dev/null || true
|
||||
)"
|
||||
if [[ -n "${kill_msg}" ]]; then
|
||||
echo "$kill_msg"
|
||||
fi
|
||||
|
||||
build_info="$(
|
||||
"$PY" -c "
|
||||
import juc500_xfer.usb_link as u
|
||||
print(getattr(u, 'XFER_BUILD', '?'), '|', u.__file__)
|
||||
" 2>/dev/null || echo "? | import failed"
|
||||
)"
|
||||
echo "JUC500 build: ${build_info}"
|
||||
|
||||
# 개발 중: Python GUI 직접 실행. Tauri 케이블 감시는 JUC500_USE_TAURI=1 일 때만.
|
||||
if [[ "${JUC500_USE_TAURI:-0}" == "1" && -f "$ROOT/scripts/launch_tauri.sh" ]]; then
|
||||
TAURI_RELEASE="$ROOT/juc500-app/src-tauri/target/release/juc500-app"
|
||||
TAURI_DEBUG="$ROOT/juc500-app/src-tauri/target/debug/juc500-app"
|
||||
if [[ -x "$TAURI_RELEASE" || -x "$TAURI_DEBUG" ]]; then
|
||||
exec "$ROOT/scripts/launch_tauri.sh"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$PY" "$ROOT/juc500_app.py" "$@"
|
||||
Reference in New Issue
Block a user