lintle 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lintle-0.1.1/.github/workflows/publish.yml +50 -0
- lintle-0.1.1/.gitignore +29 -0
- lintle-0.1.1/.python-version +1 -0
- lintle-0.1.1/CHANGELOG.md +63 -0
- lintle-0.1.1/CLAUDE.md +129 -0
- lintle-0.1.1/CONTRIBUTING.md +144 -0
- lintle-0.1.1/LICENSE +21 -0
- lintle-0.1.1/PKG-INFO +251 -0
- lintle-0.1.1/README.md +226 -0
- lintle-0.1.1/docs/superpowers/plans/2026-05-21-tle-corpus-cleaner.md +2077 -0
- lintle-0.1.1/docs/superpowers/plans/2026-05-22-conventions-alignment.md +968 -0
- lintle-0.1.1/docs/superpowers/runs/2026-05-22-corpus-run-report.md +65 -0
- lintle-0.1.1/docs/superpowers/runs/2026-05-22-corpus-run-summary.json +391 -0
- lintle-0.1.1/docs/superpowers/specs/2026-05-21-tle-corpus-cleaner-design.md +549 -0
- lintle-0.1.1/docs/superpowers/specs/2026-05-22-conventions-alignment-design.md +140 -0
- lintle-0.1.1/pyproject.toml +69 -0
- lintle-0.1.1/src/lintle/__init__.py +17 -0
- lintle-0.1.1/src/lintle/__main__.py +8 -0
- lintle-0.1.1/src/lintle/cli.py +441 -0
- lintle-0.1.1/src/lintle/pipeline.py +205 -0
- lintle-0.1.1/src/lintle/repair.py +140 -0
- lintle-0.1.1/src/lintle/report.py +197 -0
- lintle-0.1.1/src/lintle/tle.py +217 -0
- lintle-0.1.1/tests/__init__.py +0 -0
- lintle-0.1.1/tests/conftest.py +26 -0
- lintle-0.1.1/tests/test_cli.py +384 -0
- lintle-0.1.1/tests/test_integration.py +86 -0
- lintle-0.1.1/tests/test_oracle.py +16 -0
- lintle-0.1.1/tests/test_pipeline.py +178 -0
- lintle-0.1.1/tests/test_repair.py +111 -0
- lintle-0.1.1/tests/test_report.py +153 -0
- lintle-0.1.1/tests/test_tle.py +101 -0
- lintle-0.1.1/uv.lock +314 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
# Manually triggered. Pick the target from the input dropdown (defaults to
|
|
4
|
+
# the TestPyPI sandbox), and click Run workflow. Trusted Publishing (OIDC)
|
|
5
|
+
# handles authentication for both PyPI and TestPyPI — no API tokens stored.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
target:
|
|
11
|
+
description: "Where to publish"
|
|
12
|
+
type: choice
|
|
13
|
+
options:
|
|
14
|
+
- testpypi
|
|
15
|
+
- pypi
|
|
16
|
+
default: testpypi
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
publish:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
environment:
|
|
22
|
+
name: pypi
|
|
23
|
+
url: ${{ inputs.target == 'pypi' && 'https://pypi.org/project/lintle/' || 'https://test.pypi.org/project/lintle/' }}
|
|
24
|
+
permissions:
|
|
25
|
+
id-token: write # required for Trusted Publishing (OIDC)
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.11"
|
|
33
|
+
|
|
34
|
+
- name: Verify before publishing
|
|
35
|
+
run: |
|
|
36
|
+
uv sync
|
|
37
|
+
uv run pytest
|
|
38
|
+
uv run ruff check .
|
|
39
|
+
uv run ruff format --check .
|
|
40
|
+
|
|
41
|
+
- name: Build sdist and wheel
|
|
42
|
+
run: uv build
|
|
43
|
+
|
|
44
|
+
- name: Publish to TestPyPI
|
|
45
|
+
if: inputs.target == 'testpypi'
|
|
46
|
+
run: uv publish --index testpypi --trusted-publishing always
|
|
47
|
+
|
|
48
|
+
- name: Publish to PyPI
|
|
49
|
+
if: inputs.target == 'pypi'
|
|
50
|
+
run: uv publish --trusted-publishing always
|
lintle-0.1.1/.gitignore
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# TLE corpus data — multi-gigabyte inputs and cleaner output, not version-controlled.
|
|
2
|
+
# data/source/ holds the raw tle*.txt files and TLEs.zip; data/output/ is where
|
|
3
|
+
# the cleaner writes <name>.cleaned.txt / <name>.broken.txt.
|
|
4
|
+
/data/
|
|
5
|
+
|
|
6
|
+
# Legacy / alternate locations (in case files are placed at the repo root)
|
|
7
|
+
/tle*.txt
|
|
8
|
+
/*.zip
|
|
9
|
+
/cleaned/
|
|
10
|
+
/output/
|
|
11
|
+
|
|
12
|
+
# Claude Code session state
|
|
13
|
+
/.claude/
|
|
14
|
+
|
|
15
|
+
# macOS
|
|
16
|
+
.DS_Store
|
|
17
|
+
|
|
18
|
+
# Python
|
|
19
|
+
__pycache__/
|
|
20
|
+
*.py[cod]
|
|
21
|
+
.venv/
|
|
22
|
+
venv/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.ruff_cache/
|
|
26
|
+
.coverage
|
|
27
|
+
htmlcov/
|
|
28
|
+
build/
|
|
29
|
+
dist/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.1] - 2026-05-22
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `lintle clean` (and `validate`) no longer crash with a `FileNotFoundError`
|
|
12
|
+
traceback when the default input directory `data/source` does not exist on the
|
|
13
|
+
host. A new input-validation step in `cli.main()` catches the situation
|
|
14
|
+
upfront and prints a friendly hint that points the user at `--help` and
|
|
15
|
+
explains how to pass paths or create the directory.
|
|
16
|
+
- `discover_paths` no longer silently treats a nonexistent path as a file;
|
|
17
|
+
missing entries are dropped (and the new `check_paths` helper rejects them at
|
|
18
|
+
the boundary with a clear `no such file or directory` message instead of a
|
|
19
|
+
crash deeper in the pipeline).
|
|
20
|
+
- `--jobs 0` is rejected upfront instead of silently spinning up a zero-worker
|
|
21
|
+
pool that hangs.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- `--version` / `-V` on the top-level `lintle` command.
|
|
26
|
+
- Top-level and per-subcommand help now include an `Examples:` block and an
|
|
27
|
+
`Exit codes:` reference. Subcommands carry richer descriptions and metavars
|
|
28
|
+
(`PATH`, `DIR`, `N`) so `lintle --help` and `lintle clean --help` are
|
|
29
|
+
self-explanatory.
|
|
30
|
+
- `check_paths(paths, using_default)` — a small public helper in `cli.py` that
|
|
31
|
+
returns a user-facing error string for missing or unreadable inputs, or
|
|
32
|
+
`None` if everything is fine.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- The `paths` positional argument's argparse default is now `None` (resolved to
|
|
37
|
+
`data/source` inside `main()`) so the CLI can tell "user passed nothing" apart
|
|
38
|
+
from "user explicitly passed `data/source`" and tailor the error wording.
|
|
39
|
+
- The version string is now tracked in **one place**: `pyproject.toml`. The
|
|
40
|
+
`__version__` attribute in `src/lintle/__init__.py` is resolved at runtime via
|
|
41
|
+
`importlib.metadata.version("lintle")` (falling back to `0.0.0+local` for
|
|
42
|
+
uninstalled source checkouts). Future releases need only a single bump in
|
|
43
|
+
`pyproject.toml` — see `CONTRIBUTING.md` for the release flow.
|
|
44
|
+
|
|
45
|
+
## [0.1.0] - 2026-05-22
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- `lintle` console script with two modes: `validate` (read-only audit) and `clean`
|
|
50
|
+
(writes corrected files plus quarantine sidecars).
|
|
51
|
+
- `tle.py` — the single TLE validator: column layout, mod-10 checksum, semantic range
|
|
52
|
+
checks, and paired-record validation.
|
|
53
|
+
- `repair.py` — speculative, validated repairs: trailing-`\` stripping, CRLF
|
|
54
|
+
normalisation, whitespace trimming, and deterministic checksum reconstruction.
|
|
55
|
+
- `pipeline.py` — constant-memory streaming with prefix-driven `1 `/`2 ` line pairing.
|
|
56
|
+
- `report.py` — per-file statistics, the byte-faithful `.broken.txt` quarantine sidecar,
|
|
57
|
+
and the Markdown run report.
|
|
58
|
+
- `cli.py` — argument parsing, path globbing, per-file `ProcessPoolExecutor` parallelism,
|
|
59
|
+
a live single-line progress display, and graceful Ctrl-C shutdown (exit code `130`).
|
|
60
|
+
- Test suite: 92 tests across 7 files, including an `sgp4` oracle cross-check and
|
|
61
|
+
golden-output / idempotence integration tests; `cli.py` is fully covered.
|
|
62
|
+
- Project tooling: `ruff` for linting and formatting, `pytest-cov` for coverage.
|
|
63
|
+
- Documentation: `README.md`, `CONTRIBUTING.md`, and this changelog.
|
lintle-0.1.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this
|
|
4
|
+
repository.
|
|
5
|
+
|
|
6
|
+
`lintle` validates and cleans a ~30 GB corpus of Two-Line Element (TLE)
|
|
7
|
+
satellite-tracking files exported from space-track.org.
|
|
8
|
+
|
|
9
|
+
## Authoritative spec
|
|
10
|
+
|
|
11
|
+
The design doc at `docs/superpowers/specs/2026-05-21-tle-corpus-cleaner-design.md` is the
|
|
12
|
+
authoritative specification — read it before changing validation, repair, or pipeline
|
|
13
|
+
behaviour. It carries a revision log in its header; keep that current when the design
|
|
14
|
+
changes.
|
|
15
|
+
|
|
16
|
+
## Tech Stack
|
|
17
|
+
|
|
18
|
+
Python 3.11 · uv · standard library only at runtime · `sgp4` (dev-only test oracle) ·
|
|
19
|
+
`pytest` · `pytest-cov` · `ruff`
|
|
20
|
+
|
|
21
|
+
The runtime is **pure standard library**. `sgp4` and `pytest` are dev-only dependencies;
|
|
22
|
+
`sgp4` is a test oracle and must never be imported at runtime.
|
|
23
|
+
|
|
24
|
+
## Critical Rules — principles that must not be violated
|
|
25
|
+
|
|
26
|
+
These are the reason the design exists; an implementation that breaks them is wrong.
|
|
27
|
+
|
|
28
|
+
1. **Validated transformation.** Never apply a fix and trust it. Apply a candidate fix,
|
|
29
|
+
re-run *full* validation, and commit the result only if it now passes — otherwise
|
|
30
|
+
quarantine.
|
|
31
|
+
2. **Correctness over recovery.** Never emit a wrong-but-valid-looking record; when in
|
|
32
|
+
doubt, quarantine. No reconstruction of missing *data* characters. The one sanctioned
|
|
33
|
+
reconstruction is a missing *checksum* digit, which is deterministically recomputable —
|
|
34
|
+
and even that is a distinct, weaker repair tier with its own reporting.
|
|
35
|
+
3. **Constant memory.** Files stream; the pairing state machine holds at most two lines.
|
|
36
|
+
A 3.2 GB file must never be loaded whole.
|
|
37
|
+
4. **One validator definition.** "Perfect" is defined once, in `tle.py`. Never add a
|
|
38
|
+
second, divergent validation path.
|
|
39
|
+
|
|
40
|
+
**Report outcomes faithfully.** If tests fail, say so with the output. If a verification
|
|
41
|
+
step was skipped, say that rather than implying it ran. Never claim "all tests pass" when
|
|
42
|
+
output shows failures.
|
|
43
|
+
|
|
44
|
+
## The corpus (`data/`, git-ignored)
|
|
45
|
+
|
|
46
|
+
- `data/source/` — 29 raw `tle*.txt` files (~30 GB) plus `TLEs.zip` (~12 GB). Inputs.
|
|
47
|
+
- `data/output/` — where `clean` writes `cleaned/`, `broken/`, and `report.md`. Outputs.
|
|
48
|
+
- The whole `data/` tree is git-ignored — ~42 GB — and must never be staged or committed.
|
|
49
|
+
- **Never read a corpus file whole** — the largest is 3.2 GB. Sample with `head`, `awk`,
|
|
50
|
+
or `sed -n`.
|
|
51
|
+
|
|
52
|
+
## Code Style
|
|
53
|
+
|
|
54
|
+
- Python 3.11. Concise one-paragraph docstrings on every public module, function, and
|
|
55
|
+
class — match that established style; do not expand to Args/Returns/Raises blocks.
|
|
56
|
+
- `ruff` for linting and formatting, configured in `pyproject.toml` (rule sets `E`, `F`,
|
|
57
|
+
`I`, `UP`, `B`, `SIM`; 88-column lines).
|
|
58
|
+
- `src/` layout — all package code lives under `src/lintle/`.
|
|
59
|
+
- Run `uv run ruff check .` and `uv run ruff format --check .` before committing.
|
|
60
|
+
|
|
61
|
+
## Project Layout
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
src/lintle/
|
|
65
|
+
├── __main__.py # python -m lintle entry point
|
|
66
|
+
├── __init__.py # __version__, stem() filename helper
|
|
67
|
+
├── cli.py # argparse, globbing, parallel workers, live progress, Ctrl-C handling
|
|
68
|
+
├── pipeline.py # streams a file in binary, pairs 1/2 lines into records, routes them
|
|
69
|
+
├── repair.py # speculative fixes, each confirmed by tle.py before commit
|
|
70
|
+
├── report.py # FileStats, the .broken.txt sidecar writer, the run report
|
|
71
|
+
└── tle.py # the validator — column layout, checksum, semantic ranges, pairing
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Module dependencies point one way only: `cli.py → pipeline.py → repair.py → tle.py`.
|
|
75
|
+
|
|
76
|
+
→ See [`README.md`](README.md) for the architecture, usage, and data flow.
|
|
77
|
+
→ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for setup, testing, and the git workflow.
|
|
78
|
+
|
|
79
|
+
## Commands
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv sync # Install, including dev deps (sgp4, pytest, ruff)
|
|
83
|
+
uv run pytest # Full test suite
|
|
84
|
+
uv run pytest tests/test_tle.py::TestComputeChecksum # A single test class
|
|
85
|
+
uv run pytest --cov=lintle --cov-report=term-missing --cov-branch # Tests + coverage
|
|
86
|
+
uv run ruff check . # Lint
|
|
87
|
+
uv run ruff format --check . # Format check
|
|
88
|
+
uv run lintle validate # Audit data/source/ (read-only)
|
|
89
|
+
uv run lintle clean # Clean data/source/ -> data/output/
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Working Style
|
|
93
|
+
|
|
94
|
+
- **Use agents** for codebase exploration and multi-step research tasks.
|
|
95
|
+
- **Always verify** after a change: run `uv run pytest`, `uv run ruff check .`, and
|
|
96
|
+
`uv run ruff format --check .`, and report the actual output.
|
|
97
|
+
- Build order, if rebuilding from the spec (§12): `pyproject.toml` → `tle.py` (test-first,
|
|
98
|
+
it is the correctness oracle) → `repair.py` → `pipeline.py` → `report.py` / `cli.py`.
|
|
99
|
+
|
|
100
|
+
## Verification
|
|
101
|
+
|
|
102
|
+
After completing edits, run these before reporting success:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
uv run pytest # Must pass
|
|
106
|
+
uv run ruff check . # Must pass
|
|
107
|
+
uv run ruff format --check . # Must pass
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If any fail, report the actual output — do not suppress or simplify failures.
|
|
111
|
+
|
|
112
|
+
## File Guidelines
|
|
113
|
+
|
|
114
|
+
- Never read a corpus file whole — sample with `head`, `awk`, or `sed -n`.
|
|
115
|
+
- When renaming a function or variable, search for direct calls, string literals
|
|
116
|
+
containing the name, re-exports, and test references.
|
|
117
|
+
- Prefer files with one clear responsibility; keep functions focused and readable.
|
|
118
|
+
|
|
119
|
+
## Conventions
|
|
120
|
+
|
|
121
|
+
- Design docs live in `docs/superpowers/specs/`, named `YYYY-MM-DD-topic.md`. The design
|
|
122
|
+
doc carries a revision log in its header — keep it current when the design changes.
|
|
123
|
+
- Tests are grouped into `Test*` classes, one per unit or behaviour under test.
|
|
124
|
+
- Git: never commit to `main` directly; branch (`feature/`, `bugfix/`, `chore/`); use
|
|
125
|
+
conventional commits (`feat:`, `fix:`, `docs:`, `test:`, `style:`, `chore:`).
|
|
126
|
+
- Versioning: `pyproject.toml`'s `[project] version` is the single source of truth;
|
|
127
|
+
`src/lintle/__init__.py` resolves `__version__` from it at runtime via
|
|
128
|
+
`importlib.metadata`. Bump it once, add a `CHANGELOG.md` entry — see CONTRIBUTING.md
|
|
129
|
+
for the release flow.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Contributing to lintle
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- **Python 3.11+**
|
|
6
|
+
- **[uv](https://docs.astral.sh/uv/)** — Python package and project manager
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
git clone <repo-url>
|
|
12
|
+
cd TLEs
|
|
13
|
+
uv sync
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`uv sync` installs Python 3.11 if needed, creates a `.venv/`, and installs the project
|
|
17
|
+
plus all dev dependencies (`pytest`, `pytest-cov`, `sgp4`, `ruff`) from `uv.lock`.
|
|
18
|
+
|
|
19
|
+
### Managing dependencies
|
|
20
|
+
|
|
21
|
+
Dependencies are declared in `pyproject.toml` and pinned in `uv.lock` (committed to git).
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv add --group dev <pkg> # Add a dev-only dependency
|
|
25
|
+
uv sync # Reinstall from the lock file (after a pull)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The **runtime has no third-party dependencies** — `lintle` is pure standard library.
|
|
29
|
+
`sgp4` is a dev-only test oracle and must never be imported at runtime.
|
|
30
|
+
|
|
31
|
+
## Running
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv run lintle validate # Read-only audit of data/source/
|
|
35
|
+
uv run lintle clean # Write cleaned output to data/output/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`uv run` executes a command inside the project virtual environment — no manual
|
|
39
|
+
activation needed.
|
|
40
|
+
|
|
41
|
+
## Testing
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uv run pytest # Run all tests
|
|
45
|
+
uv run pytest -x # Stop on first failure
|
|
46
|
+
uv run pytest -k "checksum" # Run tests matching an expression
|
|
47
|
+
uv run pytest tests/test_tle.py # Run one file
|
|
48
|
+
uv run pytest tests/test_tle.py::TestComputeChecksum # Run one class
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Coverage
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
uv run pytest --cov=lintle --cov-report=term-missing --cov-branch
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This reports line and branch coverage, listing uncovered lines in the `Missing` column.
|
|
58
|
+
|
|
59
|
+
### Test layout
|
|
60
|
+
|
|
61
|
+
Tests are grouped into `Test*` classes, one per unit or behaviour under test.
|
|
62
|
+
|
|
63
|
+
| File | What it covers |
|
|
64
|
+
|------|----------------|
|
|
65
|
+
| `test_tle.py` | The validator: checksum, column layout, semantic ranges, record pairing |
|
|
66
|
+
| `test_repair.py` | Speculative line/record repair and the rejection categories |
|
|
67
|
+
| `test_pipeline.py` | Streaming I/O, line pairing, per-file processing, progress, temp-file safety |
|
|
68
|
+
| `test_report.py` | `FileStats`, the `.broken.txt` sidecar, summaries, the run report |
|
|
69
|
+
| `test_cli.py` | Argument parsing, path discovery, exit codes, elapsed-time formatting |
|
|
70
|
+
| `test_integration.py` | End-to-end: golden output, idempotence, re-validation |
|
|
71
|
+
| `test_oracle.py` | Cross-checks a known-good TLE against the trusted `sgp4` parser |
|
|
72
|
+
|
|
73
|
+
`conftest.py` holds the shared `line1` / `line2` fixtures — a canonical, known-good TLE.
|
|
74
|
+
|
|
75
|
+
## Linting & Formatting
|
|
76
|
+
|
|
77
|
+
[Ruff](https://docs.astral.sh/ruff/) handles both linting and formatting. Its
|
|
78
|
+
configuration lives in `pyproject.toml` under `[tool.ruff]` (rule sets `E`, `F`, `I`,
|
|
79
|
+
`UP`, `B`, `SIM`; 88-column lines).
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv run ruff check . # Lint
|
|
83
|
+
uv run ruff check . --fix # Lint with auto-fix
|
|
84
|
+
uv run ruff format . # Format
|
|
85
|
+
uv run ruff format --check . # Check formatting (no writes)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Run both before committing:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
uv run ruff check . && uv run ruff format --check .
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Verification
|
|
95
|
+
|
|
96
|
+
Before reporting any change as done, run — and report the actual output of:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv run pytest
|
|
100
|
+
uv run ruff check .
|
|
101
|
+
uv run ruff format --check .
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Never claim success without the output. If a check fails, report the failure.
|
|
105
|
+
|
|
106
|
+
## Git Workflow
|
|
107
|
+
|
|
108
|
+
- **Never commit directly to `main`.** Branch for every change.
|
|
109
|
+
- Branch names: `feature/<desc>`, `bugfix/<desc>`, `chore/<desc>` — lowercase, hyphens.
|
|
110
|
+
- Use [Conventional Commits](https://www.conventionalcommits.org/): `feat:`, `fix:`,
|
|
111
|
+
`docs:`, `test:`, `refactor:`, `style:`, `chore:`.
|
|
112
|
+
- Open a pull request to `main`; run the verification commands above before merging.
|
|
113
|
+
|
|
114
|
+
## Versioning
|
|
115
|
+
|
|
116
|
+
Semantic versioning (`MAJOR.MINOR.PATCH`). The version lives in **one place** —
|
|
117
|
+
`pyproject.toml`'s `[project] version` field — and is resolved at runtime from the
|
|
118
|
+
installed distribution metadata by `src/lintle/__init__.py`:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from importlib.metadata import PackageNotFoundError, version as _dist_version
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
__version__ = _dist_version("lintle")
|
|
125
|
+
except PackageNotFoundError: # source checkout that was never installed
|
|
126
|
+
__version__ = "0.0.0+local"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Because the lookup needs the project to be installed (even editable), keep `uv sync`
|
|
130
|
+
current — every dev workflow in this repo already does.
|
|
131
|
+
|
|
132
|
+
Release flow:
|
|
133
|
+
|
|
134
|
+
1. Bump `version` in `pyproject.toml`.
|
|
135
|
+
2. Add a new `## [X.Y.Z] - YYYY-MM-DD` section at the top of `CHANGELOG.md` with
|
|
136
|
+
`### Added` / `### Changed` / `### Fixed` subsections (see Keep a Changelog).
|
|
137
|
+
3. Run the verification commands (`uv run pytest`, `uv run ruff check .`,
|
|
138
|
+
`uv run ruff format --check .`) and report the actual output.
|
|
139
|
+
4. Commit on a `chore/release-X.Y.Z` branch and open a PR to `main`. Tag and publish
|
|
140
|
+
after merge.
|
|
141
|
+
|
|
142
|
+
Nothing else needs to change — `lintle --version`, the `report.py` headers, and any
|
|
143
|
+
downstream `from lintle import __version__` import all pick the new value up from
|
|
144
|
+
`pyproject.toml` automatically.
|
lintle-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrei Lavrenov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|