fix(ci): uv lock 생성 + setup-uv 옵션 정리 + UI 진행률 인디케이터 (#6, #4 부분)
All checks were successful
CI / Ruff + Test (Py3.11 + Py3.13) (3.11) (push) Successful in 23s
CI / Ruff + Test (Py3.11 + Py3.13) (3.13) (push) Successful in 23s

CI uv setup 실패 (#6 후속):
- 원인: astral-sh/setup-uv@v3 의 enable-cache:true 가 **/uv.lock 미발견 시 fail.
  7개 push 모두 ::error::No file ... matched to [**/uv.lock] → 10-20초 만에 abort.
- 해결: uv.lock 생성 (438KB, 89 packages 해결) + cache-dependency-glob 명시.

연쇄 수정 (uv.lock 생성 과정에서 노출):
- pyproject.toml: scipy/pyproj/numpy 핀을 hard-pin == 에서 range > = 로 완화
  (base vs [py313] extras 충돌 해소). requires-python ">=3.9" → ">=3.11"
  (pyproj>=3.7 wheel 가용 환경과 일치). [tool.uv] no-progress = false 제거 (deprecated).
- .gitea/workflows/ci.yml: 별도 Setup Python step 제거 (uv venv가 자동 fetch),
  install step 단순화 (matrix 분기 EXTRAS 변수), 모든 run: 에 shell: bash 명시.

UI 진행률 인디케이터 (#4 부분):
- self.progress_bar (CTkProgressBar mode=indeterminate, MC overlap orange #FF5F00)
  status_bar 우측에 hidden 배치. start_progress(label)/stop_progress() 메서드 추가.
- self.textbox height 120 → 80 (인라인 로그 비중 축소, 백엔드 파일이 주 기록처).

ruff cleanup (harness/perf.py):
- Optional[Callable[...]] → Callable[...] | None (UP045).
- try/except/pass → contextlib.suppress (SIM105).
- 미사용 # noqa: BLE001 제거 (RUF100).

검증: uv lock 성공, ruff check All checks passed, py_compile + AST OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 17:13:33 +09:00
parent 5a44c90ea6
commit fc963007b7
6 changed files with 2333 additions and 21 deletions

View File

@@ -620,8 +620,10 @@ class SCanvasApp(ctk.CTk):
self.map_view.set_zoom(6)
self.map_view.set_position(36.5, 127.5)
# 2. 로그 (하단 — 스크롤 가능, 높이 줄임)
self.textbox = ctk.CTkTextbox(self.main_frame, height=120, font=ctk.CTkFont(family="Consolas", size=12), border_width=1)
# 2. 로그 (하단 — 스크롤 가능. 피드백 #4: 인라인 로그 비중 축소, 백엔드 파일이
# 주 기록처. height 120 → 80 으로 캔버스 영역 확보.
# 파일 로그: %LOCALAPPDATA%\\S-CANVAS\\scanvas_harness.log + logs/scanvas.log)
self.textbox = ctk.CTkTextbox(self.main_frame, height=80, font=ctk.CTkFont(family="Consolas", size=12), border_width=1)
self.textbox.grid(row=1, column=0, padx=0, pady=0, sticky="nsew")
# 3. 하단 상태 바
@@ -634,6 +636,16 @@ class SCanvasApp(ctk.CTk):
self.status_text = ctk.CTkLabel(self.status_bar, text="지형 데이터를 로드해 주세요.", font=ctk.CTkFont(size=12))
self.status_text.pack(side="left")
# 진행률 인디케이터 (피드백 #4 — "느리게 느껴짐" 일부 해결).
# 기본 hidden. start_progress/stop_progress 로 토글. indeterminate animation
# 으로 "시스템이 살아있다" 시그널 — 실 진행률 측정은 future work (#11 perf 와 연계).
# MC accent 색상 (#FF5F00 overlap orange) 적용.
self.progress_bar = ctk.CTkProgressBar(
self.status_bar, mode="indeterminate", width=180, height=10,
progress_color="#FF5F00", fg_color=("#E0E0E0", "#333333"),
)
# 초기엔 hidden (pack 안 함). start_progress 시 등장.
self.log("S-CANVAS Generative Design Engine 구동 완료.")
# Perf 측정 라인을 GUI 로그에도 함께 표시 (#11). harness/perf.py 폴백 import 시
@@ -741,6 +753,33 @@ class SCanvasApp(ctk.CTk):
self.textbox.see("end")
self.after(0, _update)
def start_progress(self, label: str | None = None) -> None:
"""진행률 인디케이터 표시 + indeterminate animation 시작.
피드백 #4 — 긴 작업 시 "시스템 살아있음" 시그널. label 주면 status_text 도
함께 갱신. 메인 thread 블로킹 작업이라도 호출 직전/직후에 표시 가능 (실
애니메이션은 idle time 에 의존).
"""
def _start():
with contextlib.suppress(Exception):
self.progress_bar.pack(side="right", padx=(8, 12), pady=4)
self.progress_bar.start()
if label is not None:
self.status_text.configure(text=label)
self.update_idletasks()
self.after(0, _start)
def stop_progress(self, final_label: str | None = None) -> None:
"""진행률 인디케이터 숨김 + animation 정지."""
def _stop():
with contextlib.suppress(Exception):
self.progress_bar.stop()
self.progress_bar.pack_forget()
if final_label is not None:
self.status_text.configure(text=final_label)
self.update_idletasks()
self.after(0, _stop)
def _diag(self, message, *, reset=False):
"""구조물 분류/추출 진단 로그 (scanvas_diagnostic.log).