Add an ai-code-review context file
Signed-off-by: Adam Williamson <awilliam@redhat.com> Assisted-by: Cursor 2.6.11 | claude-4.6-opus-high
This commit is contained in:
parent
37347077a7
commit
7c6bc5825f
1 changed files with 109 additions and 0 deletions
109
.ai_review/project.md
Normal file
109
.ai_review/project.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
## Project Overview
|
||||
|
||||
**Purpose:** Python library for interacting with Fedora's wiki-based test case management system (Wikitcms) — manages release validation events, test result pages, and test day pages on the Fedora MediaWiki instance.
|
||||
**Type:** Library (packaged as `wikitcms` on PyPI, `python-wikitcms` in Fedora repos)
|
||||
**Domain:** Fedora QA / Release Validation
|
||||
**Key Dependencies:** `mwclient` (MediaWiki API), `fedfind` (Fedora compose/release lookup), `cached-property`
|
||||
|
||||
## Technology Stack
|
||||
|
||||
### Versions (current as of 2026-03-06)
|
||||
- **Python** 3.6–3.14 (tested via tox across all these versions)
|
||||
- **mwclient** >=0.8.2 — MediaWiki API client; wikitcms subclasses `Site`, `Page`, `GeneratorList`, `PageList`
|
||||
- **fedfind** >=3.3.0 — Fedora-specific library for finding/describing composes and releases (see Internal section)
|
||||
- **cached-property** — Used for `cached_property` decorator on `Event` and `Page` classes
|
||||
- **setuptools** >=40.6.0 — Build system (with `setuptools-git`)
|
||||
- **productmd** — `composeinfo.get_date_type_respin()` used for Pungi 4 compose ID parsing
|
||||
|
||||
### Dev Tools
|
||||
- **Testing:** pytest + coverage (90% diff-coverage enforced) | **Linting:** pylint, black (100-char lines)
|
||||
- **CI:** Forgejo Actions (tox in `quay.io/fedora/fedora:latest` container) | **Package:** setuptools
|
||||
|
||||
## Architecture & Code Organization
|
||||
|
||||
### Structure
|
||||
```
|
||||
src/wikitcms/
|
||||
├── wiki.py # Wiki(mwclient.Site) — main entry point, high-level methods
|
||||
├── event.py # ValidationEvent (ABC) → ComposeEvent, NightlyEvent
|
||||
├── page.py # Page(mwclient.Page) → ResultPage → ValidationPage → ComposePage, NightlyPage
|
||||
│ # Also: SummaryPage, DownloadPage, AMIPage, TestDayPage
|
||||
├── result.py # Result, ResultRow classes + find_results/find_resultrows parsers
|
||||
├── release.py # Release class — Fedora release representation
|
||||
├── listing.py # TcmsPageList, TcmsGeneratorList, ValidationCategory, TestDayCategory
|
||||
│ # Overrides mwclient generators to return wikitcms types
|
||||
├── helpers.py # Sorting, normalization, compose ID conversion, dist validation
|
||||
└── exceptions.py # NoPageError, NotFoundError, TooManyError, FedfindNotFoundError
|
||||
```
|
||||
|
||||
### Key Patterns
|
||||
- **Subclassing mwclient extensively**: `Wiki` extends `mwclient.Site`, `Page` extends `mwclient.page.Page`, listing classes extend `mwclient.listing.GeneratorList`/`PageList`. Don't suggest replacing inheritance with composition — this design is fundamental to the library's operation.
|
||||
- **Wiki page naming conventions encode semantics**: Page names like `Test Results:Fedora 42 Beta 1.1 Installation` are parsed via regex in `listing.py` to instantiate the correct wikitcms page type. Changes to naming patterns require coordinated regex updates.
|
||||
- **(release, milestone, compose) triplet versioning**: All events and pages are identified by this triplet. The `get_validation_event()`/`get_validation_page()` methods in `wiki.py` accept sloppy input and do best-effort guessing with wiki roundtrips.
|
||||
- **"dist" parameter for multi-stream support**: `dist` defaults to `"Fedora"` but supports `"Fedora-Modular"`, `"Fedora-IoT"`, etc. It's threaded through events, pages, categories, and wiki template names. Must always match the `^Fedora(-\w+)?$` pattern.
|
||||
- **Seedtext and template substitution**: Pages are created using `{{subst:...}}` wiki template calls stored as `seedtext` attributes. The wiki's template system generates the actual page content.
|
||||
|
||||
### Critical Files
|
||||
- **`wiki.py`** — `get_validation_event()` and `get_validation_page()` contain complex guessing logic with multiple code paths for compose types (date vs TC/RC vs Pungi 4). The `report_validation_results()` method is the high-level entry point for result reporting.
|
||||
- **`listing.py`** — `_get_tcms_testresults()` contains fragile regex patterns that must match all historical and current wiki page naming conventions. A regex change here can break page discovery across the entire library.
|
||||
- **`page.py`** — `add_results()` edits wiki page text in-place by byte offset, processing sections in reverse order to preserve offsets. The slicing logic is subtle and order-dependent.
|
||||
- **`helpers.py`** — `cid_to_event()` converts Pungi 4 compose IDs to the (release, milestone, compose) triplet. Contains Fedora-version-specific logic (e.g., the Pungi 4 transition at Fedora 24).
|
||||
- **`result.py`** — `Result.from_result_template()` parses the `{{result|...}}` MediaWiki template syntax. Named parameters (`bot=true`) are extracted before positional ones.
|
||||
|
||||
## Review Guidance
|
||||
|
||||
### What Reviewers Must Know
|
||||
- **Compose versioning changed at Fedora 24** (Pungi 4 transition). Code paths often branch on `int(release) > 23`. Don't suggest removing these branches — they handle real historical data.
|
||||
- **Rawhide nightly events have artificial release numbers**: Rawhide composes don't inherently have a release number; wikitcms assigns one (next expected release). This differs from fedfind's versioning where Rawhide has release "Rawhide" with no milestone.
|
||||
- **`save()` retries once on failure** with a 15-second sleep (in `page.py`). This is intentional — the Fedora wiki is sometimes flaky. Don't suggest removing the retry or the sleep.
|
||||
- **`pylint: disable` comments are deliberate**: Many classes legitimately have many arguments/attributes because they model wiki pages with many properties. Don't suggest refactoring to reduce parameter counts.
|
||||
- **Python 3.6 compatibility is still required**: The library is packaged for all supported Fedora releases, some of which ship Python 3.6. Don't suggest f-string walrus operators, `typing.get_type_hints`, or other 3.7+ features.
|
||||
- **openidc_client is optional**: Imported with try/except in `wiki.py`. Only needed for Fedora wiki authentication. Don't flag the `except ImportError: X = None` pattern.
|
||||
|
||||
### Do NOT Flag (Known False Positives)
|
||||
- `pylint: disable=too-many-arguments` throughout — these classes model complex wiki structures with many inherent attributes.
|
||||
- `pylint: disable=signature-differs` on `login()` and `save()` — intentional signature changes when overriding mwclient methods.
|
||||
- `time.sleep(15)` in `Page.save()` — intentional retry delay for wiki API flakiness.
|
||||
- `super(ClassName, self).__init__()` style — required for Python 3.6 compatibility (no `super()` without args in some edge cases with multiple inheritance).
|
||||
- Bare `except (NoPageWarning, PageCheckWarning)` in listing generators — intentional fallthrough to mwclient types.
|
||||
- `# pylint: disable=protected-access` for `nxt._info` in `TcmsGeneratorList.__next__()` — necessary to avoid expensive API roundtrips; mwclient doesn't expose page info any other way.
|
||||
|
||||
### Common Pitfalls
|
||||
- **Regex patterns in listing.py must handle all historical naming conventions**: New page name formats require new regex patterns, but old ones must be preserved. Test against real wiki data files in `tests/data/`.
|
||||
- **Byte offset manipulation in `add_results()`**: Results must be processed in reverse section order (`sorted(..., reverse=True)`) or byte offsets get corrupted by earlier edits. Don't reorder.
|
||||
- **`_check_compose()` is called twice in `get_validation_event()`/`get_validation_page()`**: The two `if _check_compose(compose) ==` calls are sequential checks, not redundant — compose can be "date" or "compose" type.
|
||||
|
||||
## Internal & Proprietary
|
||||
|
||||
- **fedfind** (`fedfind` package): Fedora-specific library for finding and describing Fedora composes and releases. Provides `fedfind.release.get_release()`, `fedfind.helpers.parse_cid()`, `fedfind.helpers.date_check()`, and `fedfind.const.PUNGI_SUCCESS`. It is another Fedora QA project, not a general-purpose library. Don't suggest alternatives.
|
||||
- **productmd** (`productmd` package): Fedora/Red Hat library for parsing product metadata. Used only for `get_date_type_respin()`. Another internal ecosystem library.
|
||||
- **openidc_client**: Fedora's OpenID Connect client library. Used for authenticating to the Fedora wiki. The `client_secret="notsecret"` in `Wiki.login()` is intentional — this is a public client in the OIDC sense.
|
||||
- **relval**: The primary consumer of this library — a CLI tool for managing Fedora release validation. Edit summaries reference "relval" because that's the tool that calls wikitcms.
|
||||
|
||||
---
|
||||
<!-- MANUAL SECTIONS - DO NOT MODIFY THIS LINE -->
|
||||
|
||||
## Architecture & Design Decisions
|
||||
|
||||
- **Why subclass mwclient rather than wrap it**: The library needs to seamlessly integrate with mwclient's generator/page system so that iterating over wiki categories automatically returns wikitcms-typed objects. Composition would require re-implementing all of mwclient's iterator protocol.
|
||||
- **Why (release, milestone, compose) triplet**: This versioning scheme predates the library and mirrors how Fedora QA organizes validation testing on the wiki. It maps to wiki page names, categories, and template parameters.
|
||||
- **Why support Python 3.6**: The library is packaged in Fedora repos. Older Fedora releases that are still supported may ship Python 3.6. Dropping 3.6 support requires coordinating with Fedora packaging policy.
|
||||
- **Why `cached_property` from the external package**: At the time the library was written, `functools.cached_property` did not exist (added in Python 3.8). The external `cached-property` package provides Python 3.6 compatibility.
|
||||
|
||||
## Domain-Specific Context
|
||||
|
||||
- **Validation Event**: A testing event for a specific Fedora compose (nightly or milestone candidate). One event has multiple result pages (one per test type: Installation, Desktop, Server, etc.).
|
||||
- **Compose vs Nightly**: "Compose" events are for milestone release candidates (Alpha, Beta, Final/RC). "Nightly" events are for daily automated builds (Rawhide or Branched).
|
||||
- **Test type / testtype**: A category of tests (e.g., "Installation", "Desktop", "Server", "Cloud"). Each test type has its own result page within an event.
|
||||
- **ResultRow**: A row in a wiki result table — represents a single test case with columns for different environments (e.g., x86_64, aarch64). Contains Result objects.
|
||||
- **Seedtext**: Wiki template substitution text (e.g., `{{subst:Validation results|...}}`) that, when saved to a page, causes the wiki's template engine to generate the full result page structure.
|
||||
- **CurrentFedoraCompose**: A wiki template page that acts as a pointer to the current validation event. Updated by `ValidationEvent.update_current()`.
|
||||
|
||||
## Special Cases
|
||||
|
||||
- **Pungi 4 transition at Fedora 24**: Before F24, composes used TC/RC naming (TC1, RC3). After F23, Pungi 4 introduced date-based nightly IDs (20160308.n.0) and numeric milestone composes (1.1, 1.2). Both schemes must be supported simultaneously.
|
||||
- **IoT composes as nightlies**: IoT composes are technically "production" type in Pungi but are treated as nightlies in wikitcms. Special regex handling in `listing.py` (`iot_nightly_patt`).
|
||||
- **"Final" to "RC" milestone conversion**: Post-F23, the "Final" milestone became "RC" in Pungi 4 naming. `get_validation_event()` and `get_validation_page()` silently convert "Final" to "RC" for releases > 23.
|
||||
|
||||
---
|
||||
*Generated by [context-generator](https://github.com/juanje/context-generator) v1.0.0 | Cursor with claude-4.6-opus-high-thinking*
|
||||
Loading…
Add table
Add a link
Reference in a new issue