diff --git a/.idea/modules.xml b/.idea/modules.xml index 46b271a..6ea9d61 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 8a2e8df..f837adc 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -8,6 +8,6 @@ - + \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index c799ec9..c126380 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ The Medoc TCP client is a **subpackage** at `src/heat_task/medoc/` (console scri - `models.py` — protocol enums/dataclasses (`Command`, `ReturnCode`, `MedocResponse`, …) - `cli/` — the `medoc` command line (`parser.py`, `commands.py`, `formatting.py`, `__init__.py` wires `main`) -Task-agnostic experiment plumbing — screen/VSYNC setup, run manifest, CSV writers, setup-wizard primitives, instruction pager, keyboard abstraction — comes from the separate **`psyexp-core`** package. `pyproject.toml` pins it to a git tag (`[tool.uv.sources]`) so clones reproduce exactly. For local co-development, set `UV_NO_SYNC=1` (export it in your shell, or use `uv run --no-sync`) and overlay `uv pip install -e ../psyexp-core` — that stops `uv run`'s auto-sync from reverting the editable install (and from removing the manually-installed Apple Silicon psychtoolbox). See README "Co-developing `psyexp-core` locally". +Task-agnostic experiment plumbing — screen/VSYNC setup, run manifest, CSV writers, setup-wizard primitives, instruction pager, keyboard abstraction — comes from the separate **`psyexp-core`** package, declared as a published PyPI dependency (`psyexp-core>=X.Y`) and pinned exactly in `uv.lock` so clones reproduce. For local co-development overlay an editable sibling checkout (`uv pip install -e ../psyexp-core`) and run with `uv run --no-sync` (or `UV_NO_SYNC=1`, or the `just core-*` recipes). The two overlays behave differently under sync: `uv sync --inexact` keeps the manually-installed Apple Silicon psychtoolbox (it is *not* in the lock), but it does **not** keep the editable `psyexp-core` (it *is* in the lock, so a sync reverts it) — only skipping the sync preserves that. See README "Co-developing `psyexp-core` locally". ## Terminology diff --git a/CHANGELOG.md b/CHANGELOG.md index ae04096..d95e30a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v1.0.0-rc.2 + +### Changed + +- Bumped `psyexp-core` to `v0.8.0` + ## v1.0.0-rc.1 First release candidate for 1.0.0. diff --git a/docs/development.md b/docs/development.md index 3cb8fa8..ef12b42 100644 --- a/docs/development.md +++ b/docs/development.md @@ -29,10 +29,11 @@ Silicon, install it manually from the lab build, e.g. uv pip install ../Psychtoolbox-3/dist/psychtoolbox-3.0.22.2-cp311-cp311-macosx_10_9_universal2.whl ``` -Because `uv sync`/`uv run` are exact by default and will remove the manual install, run them as -`uv sync --inexact` and `uv run --no-sync …` (or set `UV_NO_SYNC=1`) to keep it. On Windows the lab -build is needed similarly; otherwise PsychoPy's own transitive `psychtoolbox` (`<3.0.20`, -non-arm64) applies. +Because `uv sync` is exact by default it removes the manual install — run it as `uv sync --inexact` +to keep psychtoolbox. (`uv run`'s implicit sync is *inexact*, so it leaves the manual install alone; +pass `--no-sync` only when you are also overlaying an editable `psyexp-core`, which *is* in the lock +and would otherwise be reverted.) On Windows the lab build is needed similarly; otherwise PsychoPy's +own transitive `psychtoolbox` (`<3.0.20`, non-arm64) applies. ## Quick Start @@ -71,11 +72,11 @@ are ignored by pip/conda, so the conda install resolves dependencies fresh from from the lockfile. `psychtoolbox` is still not pulled in automatically (see below) — install the lab build manually after creating the environment. -> **Heads up — `uv run` auto-syncs the venv from `uv.lock` on every launch.** That sync will -> (a) revert a local editable `psyexp-core` back to the pinned git tag and (b) remove the manually -> installed Apple Silicon psychtoolbox wheel. Disable it by setting `UV_NO_SYNC=1` — either -> `export UV_NO_SYNC=1` in your shell session or prefix individual commands with -> `uv run --no-sync …`. +> **Heads up — `uv run` auto-syncs the venv from `uv.lock` on every launch** (inexactly: it won't +> remove your manually-installed psychtoolbox, but it *will* revert a local editable `psyexp-core` +> back to the locked PyPI version, since the core is in the lock). While co-developing the core, +> skip that sync with `UV_NO_SYNC=1` — `export` it in your shell, prefix commands with +> `uv run --no-sync …`, or use the `just core-*` recipes. ## Co-developing `psyexp-core` locally @@ -93,8 +94,16 @@ uv pip install -e ../psyexp-core # one time uv run heat-task # uses your local core, edits are live ``` -After changing *other* dependencies you'll need a manual `uv sync` (auto-sync is off) — that -re-clobbers psyexp-core, so re-run the editable install above. +The `just core-dev` / `just core-run` / `just core-test` recipes wrap this — they overlay the +editable checkout and run with `--no-sync`. Note `uv sync --inexact` does **not** preserve the +editable core: `--inexact` only spares packages absent from the lock (that's what keeps +psychtoolbox), and the core *is* in the lock, so only skipping the sync keeps it. After changing +*other* dependencies you'll need a manual `uv sync --inexact` — that reverts psyexp-core, so re-run +the editable install (or `just core-dev`) afterward. + +For a setup that survives sync, declare the path source in `pyproject.toml` +(`[tool.uv.sources] psyexp-core = { path = "../psyexp-core", editable = true }`) and keep that edit +local with `git update-index --skip-worktree pyproject.toml uv.lock`. ## Updating `psyexp-core` @@ -107,7 +116,7 @@ uv lock --upgrade-package psyexp-core # rewrite uv.lock to the newest version uv sync --inexact # apply it; --inexact keeps the manual psychtoolbox install ``` -Then commit the updated `uv.lock`. Raise the `>=` floor in `pyproject.toml` first if you want to +(`just core-upgrade` runs both commands.) Then commit the updated `uv.lock`. Raise the `>=` floor in `pyproject.toml` first if you want to require a new minimum. CI (`.github/workflows/tests.yml`) reads the pinned version straight from `uv.lock` via `uv export --frozen`, so it tracks the upgrade automatically once the lock is committed. diff --git a/justfile b/justfile new file mode 100644 index 0000000..0cbb59d --- /dev/null +++ b/justfile @@ -0,0 +1,51 @@ +# heat-task dev tasks. Run `just` to list recipes. +# Requires `just` (https://github.com/casey/just): `brew install just`. + +# Show available recipes +default: + @just --list + +# Install/refresh the venv (--inexact keeps the manual psychtoolbox install) +sync: + uv sync --inexact + +# Run the task (locked PyPI core) +run *args: + uv run heat-task {{args}} + +# Talk to the thermode via the vendored medoc CLI +medoc *args: + uv run medoc {{args}} + +# Run the test suite +test *args: + uv run pytest {{args}} + +# --- Co-developing psyexp-core from ../psyexp-core --------------------------- +# Two overlays, two rules: +# * psychtoolbox (NOT in the lock) -> kept by `uv sync --inexact` +# * editable psyexp-core (IN the lock) -> only kept by skipping the sync; +# `--inexact` does NOT save it. +# Co-development runs with --no-sync, which preserves both at once. + +# Overlay an editable sibling checkout of ../psyexp-core +core-dev: + uv pip install -e ../psyexp-core + @echo "Editable psyexp-core overlaid. Use 'just core-run' / 'just core-test' so it isn't reverted." + +# Run the task against the editable overlay (no sync; keeps core + psychtoolbox) +core-run *args: + uv run --no-sync heat-task {{args}} + +# Run the tests against the editable overlay +core-test *args: + uv run --no-sync pytest {{args}} + +# Drop the editable core, restore the locked PyPI version (keeps psychtoolbox) +core-release: + uv sync --inexact + +# Upgrade to the newest published psyexp-core and update the lock +core-upgrade: + uv lock --upgrade-package psyexp-core + uv sync --inexact diff --git a/pyproject.toml b/pyproject.toml index 89c7cfa..d56b571 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,10 +17,10 @@ dependencies = [ # Note: psychtoolbox is NOT declared here. PyPI has no arm64 wheel for it, so on # Apple Silicon install it manually from the lab build, e.g. # uv pip install ../Psychtoolbox-3/dist/psychtoolbox-3.0.22.2-cp311-cp311-macosx_10_9_universal2.whl -# Because `uv sync`/`uv run` are exact by default and will remove it, run them as -# `uv sync --inexact` and `uv run --no-sync ...` (or set UV_NO_SYNC=1) to keep the -# manual install. On Windows the lab build is needed similarly; PsychoPy's own -# transitive psychtoolbox (<3.0.20, non-arm64) otherwise applies. +# Because `uv sync` is exact by default it removes the manual install — run it as +# `uv sync --inexact` to keep psychtoolbox. (`uv run`'s implicit sync is inexact, +# so it leaves the manual install alone.) On Windows the lab build is needed +# similarly; PsychoPy's own transitive psychtoolbox (<3.0.20, non-arm64) otherwise applies. [project.scripts] heat-task = "heat_task.__main__:run"