Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,51 @@ Two things follow:
repository and the whole Python bridge are instrumented. Rule 12 is about what genuinely needs
a device; this rule is about not sending it things that do not.

### 14. A Python dependency is pinned in four places, and they all move together

There is no single manifest. `opentagviewer_export` is shared code that runs under **both**
interpreters — Chaquopy packages it into the APK, and the desktop exporter runs the same files
from source — so every Python dependency is declared once per consumer:

| Where | What it feeds | How to change it |
| --- | --- | --- |
| `app/build.gradle.kts` — the `install(…)` lines in the Chaquopy block | **what ships in the APK** | by hand |
| `app/src/test/python/requirements.txt` | the Chaquopy bridge tests | by hand |
| `python/pyproject.toml` | the desktop exporter and its tests | by hand |
| `python/uv.lock` | what `uv sync --frozen` actually installs | `cd python && uv lock` — never by hand |

**Miss one and the two halves ship different libraries.** That is not version skew: FindMy.py is
pinned by commit off a fork, and its API moves between commits (rule 3), so one consumer gets
methods the other does not. It has happened — `requirements.txt` said `FindMy==0.9.8` from PyPI
while the app built the fork, and both lines were individually true for months.

Two tests in `app/src/test/python/test_main.py` enforce it, and they are worth knowing by name
because they fail in a place that looks unrelated:

- `test_the_whole_repository_pins_one_findmy`
- `test_pinned_versions_match_the_app_build` — every install, including the `git+…` ones, which
is the shape that was invisible to it before

They run in the **Chaquopy bridge tests** step of `build-debug.yml`, which is *before* the APK is
built. So a missed pin presents as **"the APK build failed"** with the APK steps merely skipped,
and the actual assertion is several steps up the log. Read the step list before believing the
build broke:

```bash
gh api repos/parawanderer/OpenTagViewer/actions/jobs/<job-id> \
--jq '.steps[] | "\(.conclusion // .status)\t\(.name)"'
```

Run them before pushing — they need no device and take under a second:

```bash
python -m venv .venv && .venv/bin/pip install -r app/src/test/python/requirements.txt
.venv/bin/python -m pytest app/src/test/python -q
```

The same applies to every other shared dependency, not just FindMy.py: `PyYAML` is pinned in
`app/build.gradle.kts` and `python/pyproject.toml` for exactly this reason.

---

## Building and testing
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ chaquopy {
// wheel for desktop platforms and a pure-Python `py3-none-any` one as well.
// There is no Android wheel, so pip falls back to the pure-Python build - which
// is correct but markedly slower. The messages here are small enough not to care.
install("git+https://github.com/parawanderer/FindMy.py@337381dedf4662d730752e727d896f964feae1f8")
install("git+https://github.com/parawanderer/FindMy.py@4f940158c437b17ae61a8e90af084d658750629c")

install("NSKeyedUnArchiver==1.5")

Expand Down
2 changes: 1 addition & 1 deletion app/src/test/python/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# `FindMy==0.9.8` here for as long as the app built the fork, so every bridge test
# ran against a library the app does not ship - which is not a small difference:
# the fork's Anisette providers take `serial=` and PyPI's do not.
git+https://github.com/parawanderer/FindMy.py@337381dedf4662d730752e727d896f964feae1f8
git+https://github.com/parawanderer/FindMy.py@4f940158c437b17ae61a8e90af084d658750629c
NSKeyedUnArchiver==1.5
PyYAML==6.0.2

Expand Down
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ constraint-dependencies = [
]

[tool.uv.sources]
FindMy = { git = "https://github.com/parawanderer/FindMy.py", rev = "337381dedf4662d730752e727d896f964feae1f8" }
FindMy = { git = "https://github.com/parawanderer/FindMy.py", rev = "4f940158c437b17ae61a8e90af084d658750629c" }

[dependency-groups]
# Only the release build installs this, with `uv sync --no-default-groups --group build`. It is
Expand Down
32 changes: 16 additions & 16 deletions python/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading