- LICENSE: MIT, referenced from pyproject.toml metadata. - README: explains what the project is, how to install conandeps with uv, every option, exit codes, a worked example with a conflict/override walkthrough, how it works internally, and the container dev workflow. - CLAUDE.md: hard constraints (Conan 1.66 only, Python <3.12, all work in the container, private remote "knor" never available in tests) and the design decisions behind conandeps so future sessions do not revisit them. - Ignore uv build output (dist/). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYNdaGDrpaqDyT8QtrTQbM
4.1 KiB
4.1 KiB
CLAUDE.md
Guidance for working on this repository. It records decisions made when the project was started (August 2026) that are not obvious from the code.
What this is
Small single-file Python utilities for Conan 1.x, targeting 1.66. Not
Conan 2. The first (and so far only) tool is conandeps.py; see README.md
for what it does and how it is used.
Hard constraints
- Conan 1.66 only. Use the
conans.client.conan_api.ConanAPIV1API and Conan 1 graph internals (Node.binary,Node.dependencies,conanfile.requires). Do not introduce Conan 2 APIs or a Conan 2 code path. - Python 3.8–3.11. Conan 1.x imports the
impmodule, which is gone in 3.12.requires-pythoninpyproject.tomland the PEP 723 header inconandeps.pyboth say<3.12; keep them in sync. - All development runs inside the container. Use
./dev.sh <cmd>for every python/pytest/ruff/uv invocation. Never runconanagainst the host's~/.conan; neverpip installon the host. Rebuild the image with./dev.sh buildafter touchingContainerfile. - Never depend on the private remote. The real remote is called
knorand only exists on the machine where the tool is used. Tests must use the localconan_serverfixture intests/test_conandeps.py.
Design decisions (and why)
- Binary availability is computed via Conan's graph, not
conan search. The graph is built once per build type throughConanAPIV1.info()and each node'sbinarystatus is read. This honourspackage_id()overrides, options anddefault_package_id_modeexactly likeconan install. Do not replace this with settings-dict matching againstconan searchoutput. - "Missing" means missing for the exact profile. Not "no binary with that build_type at all".
- Overrides are parsed from Conan's WARN output. Conan 1 does not record
overrides on the graph;
Requirements.update()mutatesreq.refin place and only emits"<pkg>: requirement <old> overridden by <who> to <new>".conandepscaptures the output stream with a non-colouredConanOutputand matches_OVERRIDE_RE.test_overridespins this format – if a Conan patch release changes the wording, that test is the alarm. - Both explicit and implicit overrides are reported.
override=Truerequirements are collected fromconanfile.requiresto label an override as explicit; everything else parsed from the WARN lines is implicit. range_refis not a version range after an override. Conan reusesRequirement.range_refto hold the pre-override reference, so only treat it as a range whenreq.version_rangeis truthy.- Single file, stdlib + Conan only. No third-party deps beyond Conan.
Packaging is hatchling with
only-include = ["conandeps.py"]; the PEP 723 header makes the file usable viauv run conandeps.pywithout a checkout. - Exit codes:
0fine,1missing binaries,2Conan error. CI relies on this.
Workflow
- Lint/format:
./dev.sh ruff check .and./dev.sh ruff format .(config inpyproject.toml, target py38, line length 100). Runshellcheck dev.shafter editing the wrapper. - Tests:
./dev.sh python -m pytest. The fixture spins upconan_serveron a free port with a pre-writtenserver.conf(the port cannot be given on the command line), creates fake packages whosebuild()does nothing, uploads them, then wipes the cache so binaries can only come from the remote. Fake recipes need--build=missingat create time because dependencies' binaries are deliberately incomplete. - Dependencies:
uv.lockis committed; regenerate with./dev.sh uv lockafter changingpyproject.toml. - Commits: atomic, no
--amend; run ruff + pytest + shellcheck before committing. Add a memory of anything a future session could not derive from the repository.
Adding another tool
Follow the conandeps.py pattern: one executable file with a module
docstring explaining how and why, a PEP 723 header, a main(argv) that
returns an exit code, a [project.scripts] entry, an only-include entry in
pyproject.toml, tests under tests/ using the shared conan_env fixture,
and a section in README.md.