Skip to content

Commit 77aba4f

Browse files
committed
Improve CLAUDE.md
1 parent 2bdf45a commit 77aba4f

File tree

1 file changed

+31
-94
lines changed

1 file changed

+31
-94
lines changed

CLAUDE.md

Lines changed: 31 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,52 @@
11
# CLAUDE.md
22

3-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
3+
The role of this file is to describe common mistakes and confusion points that agents might encounter as they work in this project.
4+
If you ever encounter something in the project that surprises you, please alert the developer working with you and indicate that this is the case in the CLAUDE.md file to help prevent future agents from having the same issue.
45

5-
## What This Project Is
6+
## Interacting with the developer environment
67

7-
`pulp_python` is a Pulp plugin that enables self-hosted, PyPI-compatible Python package repositories. It is a Django application that integrates with [pulpcore](https://github.com/pulp/pulpcore) via the Pulp plugin API. Key capabilities: sync from PyPI, upload packages, serve via pip, pull-through caching, versioned repos, PEP 740 attestations.
8+
Use the `pulp-cli` to interact with the Pulp API. Fallback on `httpie/curl` when the CLI doesn't support the endpoint/options needed.
89

9-
## Development Commands
10-
11-
### Linting
1210
```bash
13-
# Code formatting check
14-
black --check --diff .
15-
16-
# Style/docstring linting
17-
flake8
18-
19-
# Run both via CI scripts
20-
.ci/scripts/extra_linting.sh
21-
.ci/scripts/check_pulpcore_imports.sh
11+
pulp --help
12+
pulp --refresh-api status
13+
pulp file content list --limit 5
14+
pulp file repository create --name foo
15+
pulp -v file repository sync --name foo --remote foo
16+
pulp task show --wait --href prn:core.task:019c8cae-cc5f-7148-a3de-456d0a9f39a1
17+
pulp show --href /pulp/api/v3/tasks/019c8cae-cc5f-7148-a3de-456d0a9f39a1/
2218
```
2319

24-
**Style rules** (`.flake8`): max line length 100, black-compatible, docstrings required on public methods (with several D-codes ignored — see `.flake8`).
25-
26-
### Testing
27-
28-
Tests require a running Pulp instance. Functional tests use pytest fixtures from `pulp_python/pytest_plugin.py` and connect to a live API.
29-
30-
```bash
31-
# Run all tests
32-
pytest pulp_python/tests/
33-
34-
# Run only unit tests (no Pulp instance needed)
35-
pytest pulp_python/tests/unit/
36-
37-
# Run a single functional test file
38-
pytest pulp_python/tests/functional/api/test_sync.py
39-
40-
# Run a single test by name
41-
pytest pulp_python/tests/functional/api/test_sync.py::test_name
42-
```
20+
Use the `oci-env` cli to interact with the developer's Pulp instance. It has commands for managing state, running tests, and executing commands against a running Pulp.
4321

44-
### Building
4522
```bash
46-
# Build the Python distribution wheel
47-
python -m build
48-
49-
# Install in development mode
50-
pip install -e .
23+
oci-env --help
24+
oci-env compose ps # check status of the Pulp dev container
25+
oci-env compose up/down/restart # start/stop/restart the Pulp dev container
26+
oci-env poll --attempts 10 --wait 10 # wait till Pulp container finishes booting up
27+
oci-env pstart/pstop/prestart # start/stop/restart the services inside the Pulp container
28+
oci-env generate-client --help # create the client bindings needed for the functional tests!
29+
oci-env test --help # run the functional/unit tests
30+
oci-env pulpcore-manager # run any pulpcore or Django commands
5131
```
5232

53-
### Changelog Entries
54-
55-
New changelog fragments go in `CHANGES/` using towncrier format. See `pyproject.toml` `[tool.towncrier]` for configuration.
56-
57-
## Architecture
33+
## Running/Writing tests
5834

59-
### Plugin Structure
35+
Prefer writing functional tests for new changes/bugfixes and only fallback on unit tests when the change is not easily testable through the API.
6036

61-
This follows the standard Pulp plugin pattern. The plugin registers itself via the entry point `pulpcore.plugin``pulp_python.app.PulpPythonPluginAppConfig`.
37+
pulp-python functional tests require pulp-python, pulpcore & pulp-file client bindings to be installed. The bindings must be regenerated for any changes to the API spec.
6238

63-
All application code lives in `pulp_python/app/`:
39+
**Always** use the `oci-env` to run the functional and unit tests.
6440

65-
| File/Dir | Purpose |
66-
|---|---|
67-
| `models.py` | Django models for all content types and repository objects |
68-
| `serializers.py` | DRF serializers with validation and metadata extraction |
69-
| `viewsets.py` | DRF viewsets implementing the REST API |
70-
| `urls.py` | URL routing — PyPI API endpoints |
71-
| `utils.py` | Metadata extraction, PyPI template rendering, canonicalization |
72-
| `provenance.py` | PEP 740 attestation/provenance validation logic |
73-
| `tasks/` | Celery async tasks (sync, publish, upload, repair, vulnerability) |
74-
| `pypi/` | PyPI-specific views (Simple API, Legacy upload, Metadata, Provenance) |
75-
| `settings.py` | Django settings additions |
76-
| `migrations/` | Database migrations |
41+
## Modifying template_config.yml
7742

78-
### Core Models
43+
Use the `plugin-template` tool after any changes made to `template_config.yml`.
7944

80-
- **`PythonPackageContent`** — the main content type; stores all Python package metadata (PEP 440/core-metadata fields) plus release info (filename, sha256, size). Unique per `(sha256, _pulp_domain)`.
81-
- **`PackageProvenance`** — PEP 740 provenance objects linked to a `PythonPackageContent`.
82-
- **`PythonRepository`** — Repository; supports `autopublish`, `PULL_THROUGH_SUPPORTED = True`. Calls `tasks.publish()` on new versions if `autopublish` is set.
83-
- **`PythonRemote`** — Remote with package filtering (`includes`, `excludes`, `package_types`, `keep_latest_packages`, `exclude_platforms`, `prereleases`, `provenance`).
84-
- **`PythonPublication`** — Publication for generated PyPI Simple API index files.
85-
- **`PythonDistribution`** — Distribution serving content via `content_handler()` which generates JSON API responses and handles Simple API serving from remote storage.
86-
- **`NormalizeName`** — A custom Django `Transform` that normalizes package names per PEP 426 (regex replace `., _, -``-`, lowercased). Used as `name__normalize=value` in queries.
87-
88-
### PyPI API Endpoints (`urls.py`)
89-
90-
```
91-
pypi/<domain>/<path>/legacy/ → UploadView (twine/pip upload)
92-
pypi/<domain>/<path>/integrity/... → ProvenanceView (PEP 740)
93-
pypi/<domain>/<path>/pypi/<meta>/ → MetadataView (JSON API)
94-
pypi/<domain>/<path>/simple/... → SimpleView (pip simple index)
45+
```bash
46+
# typically located in the parent directory of pulpcore/plugin
47+
../plugin_template/plugin-template --github
9548
```
9649

97-
### Async Tasks (`tasks/`)
98-
99-
- **`sync.py`** — Syncs packages from a remote (PyPI or compatible). Uses `bandersnatch` and `pypi-simple`.
100-
- **`publish.py`** — Creates a `PythonPublication` with Simple API index files.
101-
- **`upload.py`** — Handles package uploads (`upload` for single, `upload_group` for multi-upload).
102-
- **`repair.py`** — Re-downloads missing artifacts.
103-
- **`vulnerability_report.py`** — Fetches vulnerability data for repository content.
104-
105-
### Test Fixtures (`pytest_plugin.py`)
106-
107-
The pytest plugin defines session-scoped and function-scoped fixtures for all major objects: `python_repo_factory`, `python_remote_factory`, `python_distribution_factory`, `python_publication_factory`, `python_content_factory`, `python_repo_with_sync`. Functional tests depend on a running Pulp instance configured via environment.
108-
109-
### Key Conventions
50+
## Contributing
11051

111-
- The plugin is domain-compatible (`domain_compatible = True`). All content models have a `_pulp_domain` FK.
112-
- Package name lookups always use the `NormalizeName` transform: `name__normalize=canonicalize_name(name)`.
113-
- Content deduplication is enforced in `PythonRepository.finalize_new_version()` via pulpcore's `remove_duplicates()`.
114-
- Access policies use `AutoAddObjPermsMixin` and role-based permissions defined in each model's `Meta.permissions`.
115-
- Changelog entries use towncrier; fragment files belong in `CHANGES/`.
52+
When preparing to commit and create a PR you **must** follow our [PR checklist](https://pulpproject.org/pulpcore/docs/dev/guides/pull-request-walkthrough/)

0 commit comments

Comments
 (0)