EvaluationWorkspace

This commit is contained in:
2026-08-20 12:44:58 +02:00
parent ac4ab782b2
commit 2f1cd00e32
11 changed files with 746 additions and 33 deletions
+3 -5
View File
@@ -2,9 +2,7 @@ from __future__ import annotations
import os
import queue
import re
import tkinter as tk
from datetime import datetime
from pathlib import Path
from tkinter import filedialog, messagebox, ttk
from typing import Any
@@ -565,9 +563,9 @@ class CopienatorApp(tk.Tk):
self.state_store.invalidate_after(ordered_ids, step.id)
self.state_store.update_step(step.id, status="running", command=command_display(command))
self.active_step_id = step.id
timestamp = datetime.now().astimezone().strftime("%Y%m%d-%H%M%S")
safe_step = re.sub(r"[^A-Za-z0-9_.-]+", "_", step.id)
log_path = evaluation / ".copienator" / "logs" / f"{timestamp}-{safe_step}.log"
workspace = self.state_store.workspace
assert workspace is not None
log_path = workspace.log_path(step.id)
environment = os.environ.copy()
environment["PYTHONUNBUFFERED"] = "1"
+8 -11
View File
@@ -5,12 +5,13 @@ from datetime import datetime, timezone
from pathlib import Path
from typing import Any
STATE_FILENAME = ".copienator-gui.json"
from copienator import EvaluationWorkspace, atomic_write_json, read_json
class StateStore:
def __init__(self) -> None:
self.evaluation: Path | None = None
self.workspace: EvaluationWorkspace | None = None
self.data: dict[str, Any] = self._empty_data()
@staticmethod
@@ -18,10 +19,11 @@ class StateStore:
return {"version": 1, "steps": {}, "history": []}
def load(self, evaluation: Path) -> None:
self.evaluation = evaluation
path = evaluation / STATE_FILENAME
self.workspace = EvaluationWorkspace(evaluation)
self.evaluation = self.workspace.root
path = self.workspace.gui_state_file
try:
loaded = json.loads(path.read_text(encoding="utf-8"))
loaded = read_json(path, default=self._empty_data())
self.data = loaded if isinstance(loaded, dict) else self._empty_data()
except (OSError, json.JSONDecodeError):
self.data = self._empty_data()
@@ -30,14 +32,9 @@ class StateStore:
self.data.setdefault("history", [])
def save(self) -> None:
if not self.evaluation:
if not self.workspace:
return
path = self.evaluation / STATE_FILENAME
temporary = path.with_suffix(path.suffix + ".tmp")
temporary.write_text(
json.dumps(self.data, indent=2, ensure_ascii=False), encoding="utf-8"
)
temporary.replace(path)
atomic_write_json(self.workspace.gui_state_file, self.data)
def step(self, step_id: str) -> dict[str, Any]:
return self.data["steps"].setdefault(step_id, {})