conan-1.6-utilities/CLAUDE.md
Ole-Morten Duesund 215925b480 Add MIT license, full README and CLAUDE.md
- 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
2026-08-25 14:56:00 +02:00

78 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.ConanAPIV1` API 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.83.11.** Conan 1.x imports the `imp` module, which is gone in
3.12. `requires-python` in `pyproject.toml` and the PEP 723 header in
`conandeps.py` both 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 run `conan` against the
host's `~/.conan`; never `pip install` on the host. Rebuild the image with
`./dev.sh build` after touching `Containerfile`.
- **Never depend on the private remote.** The real remote is called `knor`
and only exists on the machine where the tool is used. Tests must use the
local `conan_server` fixture in `tests/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 through `ConanAPIV1.info()` and each
node's `binary` status is read. This honours `package_id()` overrides,
options and `default_package_id_mode` exactly like `conan install`. Do not
replace this with settings-dict matching against `conan search` output.
- **"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()` mutates `req.ref` in place
and only emits `"<pkg>: requirement <old> overridden by <who> to <new>"`.
`conandeps` captures the output stream with a non-coloured `ConanOutput`
and matches `_OVERRIDE_RE`. `test_overrides` pins this format if a Conan
patch release changes the wording, that test is the alarm.
- **Both explicit and implicit overrides are reported.** `override=True`
requirements are collected from `conanfile.requires` to label an override
as explicit; everything else parsed from the WARN lines is implicit.
- **`range_ref` is not a version range after an override.** Conan reuses
`Requirement.range_ref` to hold the pre-override reference, so only treat
it as a range when `req.version_range` is 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 via `uv run conandeps.py` without a checkout.
- **Exit codes:** `0` fine, `1` missing binaries, `2` Conan error. CI relies
on this.
## Workflow
- Lint/format: `./dev.sh ruff check .` and `./dev.sh ruff format .`
(config in `pyproject.toml`, target py38, line length 100). Run
`shellcheck dev.sh` after editing the wrapper.
- Tests: `./dev.sh python -m pytest`. The fixture spins up `conan_server`
on a free port with a pre-written `server.conf` (the port cannot be given
on the command line), creates fake packages whose `build()` does nothing,
uploads them, then wipes the cache so binaries can only come from the
remote. Fake recipes need `--build=missing` at create time because
dependencies' binaries are deliberately incomplete.
- Dependencies: `uv.lock` is committed; regenerate with `./dev.sh uv lock`
after changing `pyproject.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`.