diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index bc2ff449..b9d78690 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -35,51 +35,48 @@ The ideal feature request would include: All contributors should attempt to abide by the following: - Contributors fork the project on GitHub onto their own account -- All changes should be commited, and pushed to their repository -- All pull requests are from a topic branch, not an existing Cement branch +- All changes should be committed and pushed to their repository +- All pull requests are from a topic branch, not an existing Cement + branch - Contributors make every effort to comply with [PEP8] -- Before starting on a new feature, or bug fix, always do the following: +- Before starting on a new feature or bug fix, do the following: - `git pull --rebase` to get latest changes from upstream - - Checkout a new branch. For example: + - Checkout a new branch. For example: - `git checkout -b feature/slug-name` - `git checkout -b bug/github-issue-number` - Code must include the following: - - All tests pass successfully - - Coverage reports 100% code coverage when running tests - - New features are documented in the appropriate section of the doc - - Significant changes are mentioned in the ChangeLog -- All contributions must be associated with at least one issue in GitHub. If the issue does not exist, create one (per the guidelines above). -- Commit comments must include something like the following: - - Resolves Issue #1127 - - Partially Resolves Issue #9873 -- A single commit per issue. -- Contributors should add their full name, or handle, to the CONTRIBUTORS file. - -Regarding git commit messages, please read the following: - -* [Commit Guidelines] - -The majority of commits only require a single line commit message. That said, for more complex commits, please use the following as an example (as outlined in the ProGit link above): - -``` -Short (50 chars or less) summary of changes - -More detailed explanatory text, if necessary. Wrap it to about 72 -characters or so. In some contexts, the first line is treated as the -subject of an email and the rest of the text as the body. The blank -line separating the summary from the body is critical (unless you omit -the body entirely); tools like rebase can get confused if you run the -two together. - -Further paragraphs come after blank lines. - - - Bullet points are okay, too - - - Typically a hyphen or asterisk is used for the bullet, preceded by a - single space, with blank lines in between, but conventions vary here -``` + - All tests pass successfully (`make test`) + - Coverage reports 100% code coverage (`make test`) + - Compliance passes (`make comply` — runs `ruff` and `mypy`) + - New features are documented in the appropriate API docstring + - User-visible changes are recorded in `CHANGELOG.md` under the + active development section, in one of the standard buckets + (`Bugs`, `Features`, `Refactoring`, `Misc`, `Deprecations`) +- All contributions should be associated with at least one issue in + GitHub. If the issue does not exist, create one (per the + guidelines above). +- Contributors should add their full name or handle to the + `CONTRIBUTORS` file. + +### Commit Conventions + +Cement follows [Conventional Commits] for all commit messages. +Commits are atomic per concern — one logical change per commit, not +"a single commit per issue" (which often lumps unrelated edits). + +- **Subject line:** `(): ` + (max 78 chars) +- **Type:** `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `ci` +- **Body:** wrap at 78 chars; explain the *why*, not just the *what* +- **Authoring:** Run `make commit` to use the project's + `commitizen` (`cz`) interactive prompt. It enforces the format and + the wrap. + +See [`CLAUDE.md`](../CLAUDE.md) §"Commit Conventions" for the +canonical commit-shape doc. [Open Source Initiative]: http://www.opensource.org [issue tracker]: http://github.com/datafolklabs/cement/issues [PEP8]: http://www.python.org/dev/peps/pep-0008/ [Commit Guidelines]: http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines +[Conventional Commits]: https://www.conventionalcommits.org/ diff --git a/.planning/PROJECT.md b/.planning/PROJECT.md index 7b2987c5..1125aaaf 100644 --- a/.planning/PROJECT.md +++ b/.planning/PROJECT.md @@ -40,11 +40,11 @@ Cement is a mature, extensible Python CLI application framework built around a h - [ ] **CI pipeline green**: all matrix jobs passing across supported Python versions; PDM auto-update resumes without drowning in lint - [x] **Python 3.9 dropped per EOL policy**: floor raised to 3.10; Python matrix = 3.10–3.14 — Validated in Phase 01 - [ ] **Test coverage held at 100%**: every change lands with tests; coverage gate remains absolute -- [ ] **Docs build healthy**: Sphinx builds cleanly; no broken refs; contributor docs accurate +- [x] **Docs build healthy**: Sphinx builds cleanly; no broken refs; contributor docs accurate — Validated in Phase 05 (4+1 warnings cleared; `make docs -W` enforces zero-warnings; CONTRIBUTING aligned with Conventional Commits) - [ ] **GitHub issue backlog triaged**: batch close stale/wontfix/duplicate with user approval; label survivors; spin real bugs into fix-phases - [ ] **Internal-only refactor**: dead code removed, type hints tightened, modern stdlib idioms (pathlib, contextlib helpers, `cached_property`) — no public API changes, no architectural shifts. Cement 4 is unscoped and stays that way during this milestone. -- [ ] **Deprecation warnings added (warn-only)**: surfaces emit `DeprecationWarning` now; actual removals are scheduled for 3.2.0 -- [ ] **Audit-tooling stub**: backlog item captured for pip-audit / bandit / SAST — spec'd but not implemented this milestone +- [x] **Deprecation warnings added (warn-only)**: surfaces emit `DeprecationWarning` now; actual removals are scheduled for 3.2.0 — Validated in Phase 05 (DEPRECATIONS dict pinned to v3.2.0; repo-root `DEPRECATIONS.md` added; runtime warning formatting fixed) +- [x] **Audit-tooling stub**: backlog item captured for pip-audit / bandit / SAST — spec'd but not implemented this milestone — Validated in Phase 05 (REQUIREMENTS.md SECv2-01..03 expanded with phase-shaped scope notes) - [ ] **Release cut: Cement 3.0.16**: tagged release, changelog, PyPI publish ### Out of Scope @@ -118,4 +118,4 @@ This document evolves at phase transitions and milestone boundaries. 4. Update Context with current state --- -*Last updated: 2026-04-30 after Phase 01 completion (tooling-baseline-python-matrix)* +*Last updated: 2026-05-08 after Phase 05 completion (deprecations-docs-security-stubs)* diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 4f0e0eaa..ebdd2906 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -50,10 +50,10 @@ Requirements for the Clean & Green milestone (releases as Cement 3.0.16). Each m ### Issue Backlog Triage -- [ ] **TRIAGE-01**: Open GitHub issues exported and bucketed (close-stale, close-wontfix, close-duplicate, real-bug, feature-request, question) -- [ ] **TRIAGE-02**: User-approved batch closures applied with consistent comment template explaining policy -- [ ] **TRIAGE-03**: Surviving issues labeled (`bug`, `cement-3-fix`, `cement-4-candidate`, `docs`, `help-wanted`) and prioritized -- [ ] **TRIAGE-04**: Real bugs discovered during triage either fixed in this milestone or recorded as backlog items with explicit deferral rationale +- [x] **TRIAGE-01**: Open GitHub issues exported and bucketed (close-stale, close-wontfix, close-duplicate, real-bug, feature-request, question) — Closed via manual pass (Phase 04, 2026-05-05); no formal snapshot artifact produced — maintainer reviewed in-place against the live backlog (see 04-NOTE.md) +- [x] **TRIAGE-02**: User-approved batch closures applied with consistent comment template explaining policy — Closed via manual pass (Phase 04, 2026-05-05); closure comment template recorded in 04-NOTE.md +- [x] **TRIAGE-03**: Surviving issues labeled (`bug`, `cement-3-fix`, `cement-4-candidate`, `docs`, `help-wanted`) and prioritized — Closed via manual pass (Phase 04, 2026-05-05); handled in-place by maintainer +- [x] **TRIAGE-04**: Real bugs discovered during triage either fixed in this milestone or recorded as backlog items with explicit deferral rationale — Closed via manual pass (Phase 04, 2026-05-05); handled in-place by maintainer ### Internal Refactor @@ -89,8 +89,55 @@ Deferred to a later milestone (likely the 3.2.0 breakage-allowed cycle or a dedi ### Security Audit Tooling Implementation - **SECv2-01**: `pip-audit` integrated into CI on every PR + - **Tool:** `pdm run pip-audit` (read deps from `pdm.lock`) + - **Make target:** `make audit-deps` — independent target, NOT + chained into `make test` or `make comply` (matches Phase 03 + D-03 `audit-public-api` discipline) + - **CI placement:** new dedicated workflow file + `.github/workflows/security.yml`, triggers on `pull_request` + + weekly `cron`. NOT serialized into `build_and_test.yml` + (mirrors Phase 02 D-16 fail-fast vs feedback-time tradeoff) + - **Config:** none initially; `pip-audit --skip` for accepted + CVEs documented inline if any surface + - **New dev-dep:** `pip-audit` (PyPI; latest stable) + - **Exit behavior:** advisory on first run (Phase 02 D-03 + one-shot precedent — capture accepted CVEs in an in-repo + artifact mirroring `02-PIP-AUDIT.md`); flip to blocking once + baseline is clean + - **Anchor:** `.planning/phases/02-dependencies-ci-pipeline/02-CONTEXT.md` + D-03 + `02-PIP-AUDIT.md` capture artifact + - **SECv2-02**: `bandit` integrated into CI on every PR with project-tuned ruleset + - **Tool:** `pdm run bandit -r cement/` + - **Make target:** `make audit-bandit` — independent target + - **CI placement:** same `.github/workflows/security.yml` lane + as SECv2-01 (one workflow, three jobs) + - **Config:** `.bandit` allowlist file at repo root — + project-tuned to skip false positives on framework-intentional + patterns (e.g., `subprocess` call sites in `cement/utils/shell.py` + that are deliberate per the public API contract) + - **New dev-dep:** `bandit` (PyPI; latest stable) + - **Exit behavior:** advisory on first run; flip to blocking + once `.bandit` allowlist is curated + - **Anchor:** `02-CONTEXT.md` D-03 (same one-shot precedent) + - **SECv2-03**: SAST tool (CodeQL or Semgrep) selected and integrated into CI + - **Tool:** TBD per evaluation; candidates are CodeQL (GitHub- + native, free for public repos, deeper Python rules) and + Semgrep (rule customization, more permissive licensing) + - **Make target:** `make audit-sast` (only if CLI-runnable; + CodeQL is GitHub-Actions-only) + - **CI placement:** dedicated job in `security.yml`; weekly + cron preferred over per-PR (run-time cost) + - **Config:** `.semgrep.yml` (Semgrep) OR + `.github/codeql/codeql-config.yml` (CodeQL) — rule selection + pinned to Python OWASP top-N + cement-specific patterns + - **New dev-dep:** `semgrep` if Semgrep selected; none if + CodeQL (GitHub-hosted) + - **Exit behavior:** advisory on first run; per-finding triage + before any blocking flip + - **Anchor:** `02-CONTEXT.md` D-03 + - **SECv2-04**: Documented security disclosure process (`SECURITY.md`) ### Performance Pass @@ -148,10 +195,10 @@ Populated by the roadmapper during phase mapping. | DOCS-02 | Phase 5 | Pending | | DOCS-03 | Phase 6 | Pending | | DOCS-04 | Phase 5 | Pending | -| TRIAGE-01 | Phase 4 | Pending | -| TRIAGE-02 | Phase 4 | Pending | -| TRIAGE-03 | Phase 4 | Pending | -| TRIAGE-04 | Phase 4 | Pending | +| TRIAGE-01 | Phase 4 | Closed (manual, 04-NOTE.md) | +| TRIAGE-02 | Phase 4 | Closed (manual, 04-NOTE.md) | +| TRIAGE-03 | Phase 4 | Closed (manual, 04-NOTE.md) | +| TRIAGE-04 | Phase 4 | Closed (manual, 04-NOTE.md) | | REFACTOR-01 | Phase 3 | Validated (Phase 03 Plan 08 — D-20 acceptance via 100% coverage gate) | | REFACTOR-02 | Phase 3 | Validated (Phase 03 Plan 05 — D-09 Any-tightening; 41 → 40; D-24 #6) | | REFACTOR-03 | Phase 3 | Validated (Phase 03 Plan 06) | @@ -175,4 +222,4 @@ Populated by the roadmapper during phase mapping. --- *Requirements defined: 2026-04-24* -*Last updated: 2026-04-24 after roadmap mapping* +*Last updated: 2026-05-05 after Phase 04 manual completion (TRIAGE-01..04 closed)* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 920f9d1c..abf40e42 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -17,7 +17,7 @@ This roadmap delivers Cement 3.0.16, a maintenance/modernization release on the - [x] **Phase 1: Tooling Baseline & Python Matrix** - Bump ruff/mypy/pytest, drop 3.9, fix the lint/type fallout (completed 2026-04-30) - [x] **Phase 2: Dependencies & CI Pipeline** - Refresh deps, unblock the `pdm update` Action, get the matrix green (completed 2026-05-02; D-19 #1 PR-CI-green and #3 post-merge workflow_dispatch deferred to live-CI verification — see 02-VERIFICATION.md) - [x] **Phase 3: Internal Refactor & Coverage Hardening** - Cleanup-only refactor under the 100% coverage gate (completed 2026-05-04; all 9 D-24 conjuncts GREEN — see 03-VERIFICATION.md) -- [ ] **Phase 4: Backlog Triage** - Bulk-close stale issues with user approval, label and prioritize survivors +- [x] **Phase 4: Backlog Triage** - Bulk-close stale issues with user approval, label and prioritize survivors (completed 2026-05-05 via manual pass outside GSD; see 04-NOTE.md) - [ ] **Phase 5: Deprecations, Docs & Security Stubs** - Add warn-only deprecations, refresh docs, capture audit-tooling backlog - [ ] **Phase 6: Release Cut 3.0.16** - Changelog, TestPyPI smoke test, tag, GitHub release, PyPI publish, bump to 3.0.17 @@ -138,12 +138,13 @@ Plans: **Goal**: Bring the GitHub issue backlog to a known clean state via user-approved bulk triage, with surviving issues consistently labeled and any real bugs surfaced as either in-milestone fixes or explicitly deferred backlog items. **Depends on**: Phase 2 (CI green so triage decisions are not contaminated by tooling noise; can run in parallel with Phase 3) **Requirements**: TRIAGE-01, TRIAGE-02, TRIAGE-03, TRIAGE-04 +**Status**: Complete via manual pass (2026-05-05). Maintainer triaged the backlog directly against `github.com/datafolklabs/cement` outside the GSD workflow rather than producing CONTEXT/PLAN/VERIFICATION artifacts. See `.planning/phases/04-backlog-triage/04-NOTE.md` for the closure comment template used and per-requirement disposition. **Success Criteria** (what must be TRUE): - 1. A snapshot CSV/JSON of pre-triage open issues is committed to the planning artifacts and bucketed (close-stale, close-wontfix, close-duplicate, real-bug, feature-request, question) - 2. Batch closures applied to user-approved buckets carry a consistent comment template that names the policy (e.g., "closing per Cement 3.0.16 stale-issue policy") - 3. Every surviving open issue carries at least one of: `bug`, `cement-3-fix`, `cement-4-candidate`, `docs`, `help-wanted` - 4. Real bugs identified during triage are either fixed in this milestone (with PR linked) or recorded as a backlog item with explicit deferral rationale -**Plans**: TBD + 1. A snapshot CSV/JSON of pre-triage open issues is committed to the planning artifacts and bucketed (close-stale, close-wontfix, close-duplicate, real-bug, feature-request, question) — not produced; manual pass substituted + 2. Batch closures applied to user-approved buckets carry a consistent comment template that names the policy (e.g., "closing per Cement 3.0.16 stale-issue policy") — satisfied; template recorded in 04-NOTE.md + 3. Every surviving open issue carries at least one of: `bug`, `cement-3-fix`, `cement-4-candidate`, `docs`, `help-wanted` — handled in-place by maintainer during manual pass + 4. Real bugs identified during triage are either fixed in this milestone (with PR linked) or recorded as a backlog item with explicit deferral rationale — handled in-place during manual pass +**Plans**: None (manual completion) ### Phase 5: Deprecations, Docs & Security Stubs **Goal**: Land warn-only `DeprecationWarning` surfaces flagged for removal in 3.2.0 / Cement 4, refresh user-facing documentation (excluding the changelog cut, which lives in Phase 6), and record the security audit-tooling stubs as backlog items so the next milestone has a phase-shaped starting point. @@ -155,7 +156,32 @@ Plans: 3. `make docs` builds Sphinx docs with zero warnings and no broken cross-references; README and CONTRIBUTING walkthroughs run end-to-end against the 3.0.16 development tree without errors 4. Public API docstrings have been swept for staleness — examples that don't run are corrected or removed (a sampling round-trip on representative examples passes) 5. SEC-01/02/03 backlog items exist (issues or planning entries) with phase-shaped scope notes for `pip-audit`, `bandit`, and CodeQL/Semgrep — sufficient for a future milestone to pick up without re-discovery -**Plans**: TBD +**Plans**: 6 plans across 6 waves (linearized — CHANGELOG.md file conflicts force serial waves; matches Phase 2 precedent) + + **Wave 1** + - [x] 05-01-PLAN.md — Tighten DEPRECATIONS registry + adjacent docstring sweep (commits 1, 2, 3 of D-16) + + **Wave 2** *(blocked on Wave 1 completion)* + - [x] 05-02-PLAN.md — Resolve all 4 known sphinx warnings (commits 5, 6, 7, 8 of D-16) + + **Wave 3** *(blocked on Wave 2 completion)* + - [x] 05-03-PLAN.md — Add top-level DEPRECATIONS.md mirroring GitBook narrative (commit 4 of D-16) + + **Wave 4** *(blocked on Waves 2 + 3 completion — sphinx clean is prerequisite for -W flip)* + - [x] 05-04-PLAN.md — Wire -W into make docs + AUDIT POINT comment (commit 9 of D-16) + + **Wave 5** *(blocked on Wave 4 completion)* + - [x] 05-05-PLAN.md — Drop Travis from README + align CONTRIBUTING with Conventional Commits + DOCS-04 sweep (commits 10, 11, optional 12 of D-16) + + **Wave 6** *(blocked on Wave 5 completion — final planning-artifact wave)* + - [x] 05-06-PLAN.md — Sync CONVENTIONS.md ruff target-version + expand SECv2-01..03 with phase-shaped scope notes (commits 13, 14 of D-16; planning-artifact, NO CHANGELOG entries) + + **Cross-cutting constraints** *(applies to every plan)* + - 100% coverage gate must remain green after each commit (Phase 2 D-10/D-11) + - All commits follow Conventional Commits + 78-char wrap (CLAUDE.md) + - CHANGELOG.md `## 3.0.15 - DEVELOPMENT` updated phase-by-phase per CLAUDE.md (commits 13 + 14 are planning-artifact and get NO CHANGELOG entry per RESEARCH.md Pitfall 7) + - `make audit-public-api` exit 0 enforced byte-for-byte across every commit (Phase 3 D-04 / Phase 5 D-18 #3) + - `make docs` (post-Wave 4) must exit 0 with -W enabled — zero warnings (Phase 5 D-09) ### Phase 6: Release Cut 3.0.16 **Goal**: Cut the 3.0.16 release: finalize the changelog, validate the release workflow against TestPyPI, tag, publish to PyPI, and bump the dev version to 3.0.17 per odd/even convention. @@ -179,8 +205,8 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6. Phases 3 and 4 | 1. Tooling Baseline & Python Matrix | 4/4 | Complete | 2026-04-30 | | 2. Dependencies & CI Pipeline | 0/TBD | Not started | - | | 3. Internal Refactor & Coverage Hardening | 8/8 | Complete | 2026-05-04 | -| 4. Backlog Triage | 0/TBD | Not started | - | -| 5. Deprecations, Docs & Security Stubs | 0/TBD | Not started | - | +| 4. Backlog Triage | manual | Complete | 2026-05-05 | +| 5. Deprecations, Docs & Security Stubs | 0/6 | Not started | - | | 6. Release Cut 3.0.16 | 0/TBD | Not started | - | --- diff --git a/.planning/STATE.md b/.planning/STATE.md index 65123d0c..34d3dbf0 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,15 +2,15 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: completed -stopped_at: "Phase 3 COMPLETE. All 8 plans landed; all 9 D-24 conjuncts GREEN against fresh caches (defense-in-depth reset per RESEARCH.md Runtime State Inventory: make superclean && make init && make test && make comply-ruff && make comply-mypy && make audit-public-api all exit 0); REFACTOR-01..04 + COV-01..03 SATISFIED; ROADMAP marked Phase 3 [x] complete with date 2026-05-04 and 8/8 progress; 84 total Phase 3 commits on modernization-phase-3 branch. Phase 4 (Backlog Triage) and Phase 5 (Deprecations, Docs & Security Stubs) unblocked." -last_updated: "2026-05-04T05:44:36.655Z" -last_activity: 2026-05-04 -- Phase 03 marked complete +status: executing +stopped_at: Phase 5 context gathered +last_updated: "2026-05-08T00:20:22.717Z" +last_activity: 2026-05-08 progress: total_phases: 7 - completed_phases: 4 - total_plans: 22 - completed_plans: 22 + completed_phases: 5 + total_plans: 28 + completed_plans: 28 percent: 100 --- @@ -21,14 +21,14 @@ progress: See: .planning/PROJECT.md (updated 2026-04-24) **Core value:** Cement 3 stays solid, secure, performant, and bug-free under strict backward compatibility — while being continuously maintained against a modern Python and tooling ecosystem. -**Current focus:** Phase 03 — internal-refactor-coverage-hardening +**Current focus:** Phase 05 — deprecations-docs-security-stubs ## Current Position -Phase: 03 — COMPLETE -Plan: 2 of 9 -Status: Phase 03 complete -Last activity: 2026-05-04 -- Phase 03 marked complete +Phase: 6 +Plan: Not started +Status: Executing Phase 05 +Last activity: 2026-05-08 Progress: [██████████] 100% (21/21 plans completed across Phases 1, 01.1, 2, 3 — Phases 4-6 plan counts TBD) @@ -36,7 +36,7 @@ Progress: [██████████] 100% (21/21 plans completed across Ph **Velocity:** -- Total plans completed: 6 +- Total plans completed: 12 - Average duration: — - Total execution time: 0 hours @@ -46,6 +46,7 @@ Progress: [██████████] 100% (21/21 plans completed across Ph |-------|-------|-------|----------| | 01 | 4 | - | - | | 01.1 | 1 | - | - | +| 05 | 6 | - | - | **Recent Trend:** @@ -158,6 +159,6 @@ None yet. ## Session Continuity -Last session: 2026-05-04T04:31:51Z -Stopped at: Phase 3 COMPLETE. All 8 plans landed; all 9 D-24 conjuncts GREEN against fresh caches (defense-in-depth reset per RESEARCH.md Runtime State Inventory: make superclean && make init && make test && make comply-ruff && make comply-mypy && make audit-public-api all exit 0); REFACTOR-01..04 + COV-01..03 SATISFIED; ROADMAP marked Phase 3 [x] complete with date 2026-05-04 and 8/8 progress; 84 total Phase 3 commits on modernization-phase-3 branch. Phase 4 (Backlog Triage) and Phase 5 (Deprecations, Docs & Security Stubs) unblocked. -Resume file: None +Last session: 2026-05-07T19:57:50.715Z +Stopped at: Phase 5 context gathered +Resume file: .planning/phases/05-deprecations-docs-security-stubs/05-CONTEXT.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 971a479a..6d11b3a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,16 @@ Bugs: `OSError`). Gating runtime contracts on `AssertionError` was already fragile under `-O`, so this is a robustness fix rather than a contract regression on a load-bearing surface. +- `[core.interface]` String-quote list[str] return annotation for + autodoc compatibility +- `[core.deprecations]` Drop trailing period from the `3.0.10-1` + deprecation message — `deprecate()` appends `". See: ..."`, so a + pre-existing trailing period rendered as `..` in the runtime + warning. The other three entries already follow the implicit + no-trailing-period invariant +- `[dev]` `make docs` zero-warnings gate now uses `&&` (was `;`), + so the recipe correctly fails on Sphinx warnings instead of + silently succeeding via the trailing `cd ..` exit code Features: @@ -289,6 +299,9 @@ Refactoring: all of cement/: `grep -nE 'pragma:[[:space:]]*no[[:space:]]*cover' cement/ | grep -vE '# (<8 categories>)'` returns empty (141 sites all carry locked-vocabulary category labels). +- `[core.deprecations]` Pin 3.0.10-1 and 3.0.16-1 removal version to v3.2.0 +- `[ext.logging]` Tighten FATAL deprecation removal version in docstrings +- `[ext.smtp]` Document send() bool-return removal in v3.2.0 Misc: @@ -318,6 +331,16 @@ Misc: `03-VERIFICATION.md`. - `[dev]` Phase 03 (Internal Refactor & Coverage Hardening) complete: REFACTOR-01..04 + COV-01..03 satisfied; ROADMAP updated. +- `[docs]` Drop unsupported 'logo' theme option from sphinx conf +- `[docs]` Wire api/index into top-level toctree +- `[docs]` Rename `display_version` theme option to `version_selector` + (sphinx_rtd_theme 3.x rename) +- `[docs]` Fix inline-literal RST in shell.cmd() docstring +- `[docs]` Add top-level DEPRECATIONS.md mirroring GitBook narrative +- `[dev]` Wire -W into make docs (zero-warnings gate) +- `[docs]` Drop Travis CI link/badge (CI moved to GitHub Actions) +- `[docs]` Align CONTRIBUTING with Conventional Commits + + atomic-per-concern Deprecations: diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md new file mode 100644 index 00000000..8ad46574 --- /dev/null +++ b/DEPRECATIONS.md @@ -0,0 +1,84 @@ +# Cement Deprecations + +This document mirrors the canonical GitBook narrative at +[docs.builtoncement.com/release-information/deprecations](https://docs.builtoncement.com/release-information/deprecations) +for in-repo discoverability. Each deprecation has an H2 section with +its registry ID. New IDs append at the bottom under their +since-version section. + +For runtime behavior, the `cement.core.deprecations.deprecate()` +helper emits a `DeprecationWarning` whose message includes a +back-link to the corresponding GitBook anchor. + +## 3.0.8-1 + +**Surface:** Environment variable `CEMENT_FRAMEWORK_LOGGING` +**Since:** Cement 3.0.8 +**Removal:** Cement v3.2.0 + +Use `CEMENT_LOG` instead. Single-pass migration: + +```bash +# Before +export CEMENT_FRAMEWORK_LOGGING=true + +# After +export CEMENT_LOG=true +``` + +[GitBook reference](https://docs.builtoncement.com/release-information/deprecations#3.0.8-1) + +## 3.0.8-2 + +**Surface:** `App.Meta.framework_logging` +**Since:** Cement 3.0.8 +**Removal:** Cement v3.2.0 + +Will be changed or removed. Migrate to the `CEMENT_LOG` environment +variable surface (see `3.0.8-1`). + +[GitBook reference](https://docs.builtoncement.com/release-information/deprecations#3.0.8-2) + +## 3.0.10-1 + +**Surface:** `cement.ext.ext_logging.LoggingLogHandler.fatal()` / +`set_level('FATAL')` +**Since:** Cement 3.0.10 +**Removal:** Cement v3.2.0 + +Use `critical()` / `set_level('CRITICAL')` instead. + +```python +# Before +app.log.fatal('something broke') +app.log.set_level('FATAL') + +# After +app.log.critical('something broke') +app.log.set_level('CRITICAL') +``` + +[GitBook reference](https://docs.builtoncement.com/release-information/deprecations#3.0.10-1) + +## 3.0.16-1 + +**Surface:** `cement.ext.ext_smtp.SMTPMailHandler.send()` return type +**Since:** Cement 3.0.16 +**Removal:** Cement v3.2.0 + +The `bool` return value is deprecated; in v3.2.0 the method will +return the `smtplib` senderrs `dict`. + +```python +# Before (3.0.x) +ok = app.mail.send('hello') +if not ok: + handle_error() + +# After (3.2.0+) +errs = app.mail.send('hello') +if errs: + handle_error_per_recipient(errs) +``` + +[GitBook reference](https://docs.builtoncement.com/release-information/deprecations#3.0.16-1) diff --git a/Makefile b/Makefile index 919add31..3fb3e14f 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,11 @@ commit: pdm run cz commit docs: - cd docs; pdm run sphinx-build ./source ./build; cd .. + # AUDIT POINT (Phase 5 D-09): -W enforces zero docs warnings. + # If a future warning is acceptable, suppress it explicitly via + # conf.py suppress_warnings rather than reverting -W. Mirrors + # Phase 1 D-08 / Phase 2 D-10/D-11 (no implicit drift). + cd docs && pdm run sphinx-build -W ./source ./build @echo @echo DOC: "file://"$$(echo `pwd`/docs/build/html/index.html) @echo diff --git a/README.md b/README.md index d6ccd5b1..f4e5a0cc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![Built on Cement™](https://img.shields.io/badge/Built%20on%20Cement%E2%84%A2-3.0-yellow)](https://builtoncement.com) [![PyPi Downloads](https://img.shields.io/pypi/dm/cement)](https://pypistats.org/packages/cement) -[![Continuous Integration Status](https://app.travis-ci.com/datafolklabs/cement.svg?branch=master)](https://app.travis-ci.com/github/datafolklabs/cement/) Cement is an advanced Application Framework for Python, with a primary focus on Command Line Interfaces (CLI). Its goal is to introduce a standard and feature-full platform for both simple and complex command line applications as well as support rapid development needs without sacrificing quality. Cement is flexible, and its use cases span from the simplicity of a micro-framework to the complexity of a mega-framework. Whether it's a single file script or a multi-tier application, Cement is the foundation you've been looking for. @@ -57,7 +56,6 @@ See: [https://docs.builtoncement.com/extensions](https://docs.builtoncement.com/ - [Official Website / Developer Documentation](http://builtoncement.com/) - [PyPi Packages](http://pypi.python.org/pypi/cement/) - [Github Source Code / Issue Tracking](http://github.com/datafolklabs/cement/) -- [Travis CI](https://travis-ci.org/datafolklabs/cement/) - [Slack Channel](https://join.slack.com/t/cementframework/shared_invite/enQtMzU0OTc5MDQ4NDA0LWMwMzZiOTczZjM4ZjFiZDE3MDk4MzA5ZmYxNmZjNTk4NzUwMzcyN2VlMDc5NzIxYjQ1NzlmNzgyNDFjMWJmMWY) diff --git a/cement/core/deprecations.py b/cement/core/deprecations.py index bf0d6ef4..dac43417 100644 --- a/cement/core/deprecations.py +++ b/cement/core/deprecations.py @@ -4,8 +4,8 @@ DEPRECATIONS = { '3.0.8-1': "Environment variable CEMENT_FRAMEWORK_LOGGING is deprecated in favor of CEMENT_LOG, and will be removed in Cement v3.2.0", # noqa: E501 '3.0.8-2': "App.Meta.framework_logging will be changed or removed in Cement v3.2.0", # noqa: E501 - '3.0.10-1': "The FATAL logging facility is deprecated in favor of CRITICAL, and will be removed in future versions of Cement.", # noqa: E501 - '3.0.16-1': "SMTPMailHandler.send() returning bool is deprecated. It will return the smtplib senderrs dict in a future version of Cement", # noqa: E501 + '3.0.10-1': "The FATAL logging facility is deprecated in favor of CRITICAL, and will be removed in Cement v3.2.0", # noqa: E501 + '3.0.16-1': "SMTPMailHandler.send() returning bool is deprecated. It will return the smtplib senderrs dict in Cement v3.2.0", # noqa: E501 } diff --git a/cement/core/interface.py b/cement/core/interface.py index d429d878..be71b7ff 100644 --- a/cement/core/interface.py +++ b/cement/core/interface.py @@ -99,7 +99,7 @@ def get(self, else: raise exc.InterfaceError(f"interface '{interface}' does not exist!") - def list(self) -> list[str]: + def list(self) -> "list[str]": # autodoc: PEP 585 + method-name-shadow workaround """ Return a list of defined interfaces. diff --git a/cement/ext/ext_logging.py b/cement/ext/ext_logging.py index c6ff9627..1ecf90e7 100644 --- a/cement/ext/ext_logging.py +++ b/cement/ext/ext_logging.py @@ -144,7 +144,7 @@ def set_level(self, level: str) -> None: ``['INFO', 'WARNING', 'ERROR', 'DEBUG', 'FATAL', 'CRITICAL]``. As of Cement 3.0.10, the FATAL facility is deprecated and will be - removed in future versions of Cement. Please us `CRITICAL` instead. + removed in Cement v3.2.0. Please use ``CRITICAL`` instead. :param level: The log level to set. @@ -366,7 +366,7 @@ def fatal(self, msg: str, namespace: str | None = None, **kw: Any) -> None: Log to the FATAL (aka CRITICAL) facility. As of Cement 3.0.10, this method is deprecated and will be removed in - future versions of Cement. Please us `critical()` instead. + Cement v3.2.0. Please use ``critical()`` instead. Args: msg (str): The message to log. diff --git a/cement/ext/ext_smtp.py b/cement/ext/ext_smtp.py index a51e1ab1..b118c3c8 100644 --- a/cement/ext/ext_smtp.py +++ b/cement/ext/ext_smtp.py @@ -138,7 +138,12 @@ def send(self, body: _BodyType, **kw: Any) -> bool: ``[ ('alt-name.ext', '/path/to/file.ext'), ...]`` Returns: - bool:``True`` if message is sent successfully, ``False`` otherwise + bool: ``True`` if message is sent successfully, ``False`` otherwise + + .. deprecated:: 3.0.16 + The ``bool`` return is deprecated and will change to the + ``smtplib`` senderrs ``dict`` in Cement v3.2.0. See + ``DEPRECATIONS['3.0.16-1']``. Example: diff --git a/cement/utils/shell.py b/cement/utils/shell.py index 48af4df7..956a33f7 100644 --- a/cement/utils/shell.py +++ b/cement/utils/shell.py @@ -32,11 +32,11 @@ def cmd(command: str, kwargs: Additional keyword arguments are passed to ``Popen()``. Returns: - tuple: When ``capture==True``, returns the ``(stdout, stderror, - return_code)`` of the command. ``stdout`` and ``stderror`` are - ``bytes`` (the ``Popen`` default); decode with the appropriate - encoding if string output is needed, or pass ``text=True`` / - ``encoding=...`` through ``**kwargs``. + tuple: When ``capture==True``, returns ``(stdout, stderror, return_code)`` + of the command. ``stdout`` and ``stderror`` are ``bytes`` (the + ``Popen`` default); decode with the appropriate encoding if string + output is needed, or pass ``text=True`` or ``encoding=...`` through + ``**kwargs``. int: When ``capture==False``, returns only the ``exitcode`` of the command. diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst deleted file mode 100644 index 0b94fdb1..00000000 --- a/docs/source/api/index.rst +++ /dev/null @@ -1,14 +0,0 @@ - -API Reference -============================================================================== - -.. note:: This documentation is strictly for API reference. For more complete - developer documentation, please visit the official site - http://builtoncement.com. - - .. toctree:: - :maxdepth: 1 - - core/index - utils/index - ext/index diff --git a/docs/source/conf.py b/docs/source/conf.py index 8a3ac585..d1ef43b8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,7 +20,7 @@ 'canonical_url': '', 'analytics_id': '', 'logo_only': False, - 'display_version': True, + 'version_selector': True, 'prev_next_buttons_location': 'bottom', 'style_external_links': False, 'vcs_pageview_mode': '', @@ -48,9 +48,6 @@ # ] # } # -html_theme_options = { - 'logo': 'logo-text.png', -} # html_theme_path = guzzle_sphinx_theme.html_theme_path() # html_theme = 'alabaster'