feat!: Build the CLI with cli-components and chain apply targets #8

Merged
martinjose merged 5 commits from refactor/cli-components into main 2026-10-22 00:41:39 +00:00
Owner

Summary

This moves modify-csv onto cli-components (>=2026.10.3) and adds target chaining to apply.

refactor: Build the CLI with cli-components

  • Replaces the hand-built argparse parser with a declarative cli-components Parser: required subcommands, the script-source exclusive group, typed row/column values, and per-command help pages.
  • Requires Python 3.11 or newer, the minimum for cli-components. CI now tests on 3.11 and 3.13.
  • Adds tests that pin down help pages, usage errors and exit codes.

feat!: Chain apply targets and require the apply command

  • --row, --column and --cell can be repeated and mixed. The script runs over them in the order given:
    modify-csv apply in.csv out.csv --script-file fix.py --column email --row 2 --cell 0 name
    
    • A cell covered by several targets is transformed once per target, each time receiving the previous result.
    • Every target is checked before any cell changes, so one bad target writes nothing.
    • At least one target is required.
  • transform_csv also accepts a sequence of targets. Single-target calls are unchanged, including target= passed by keyword.
  • Each help page now documents only its own command's options. modify-csv --help lists the commands, and the script contract appears on apply --help and template --help.
  • Adds BREAKING_CHANGES.md, linked from the README, to track releases that aren't backward compatible.

Breaking changes

All of these are listed in BREAKING_CHANGES.md under Unreleased:

  • Python 3.11 minimum.
  • apply is required. The original form without a command (modify-csv IN OUT --script-file F --row 2) is gone. Every single-target apply command still works unchanged.
  • Help and errors: the root help page no longer shows the script contract. --cell errors now use the apply usage line, like every other argument error.

At release time, rename the Unreleased heading to the release version.

Verification

  • All 39 product tests and the release-tooling tests pass on Python 3.11 and 3.13.
  • Every README example, including the Python API snippet, runs as documented against a built wheel.
  • twine check passes on the wheel and sdist.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XazST7Ly1bCbjWnhjrHXJk

## Summary This moves modify-csv onto [cli-components](https://pypi.org/project/cli-components/) (>=2026.10.3) and adds target chaining to `apply`. **`refactor: Build the CLI with cli-components`** - Replaces the hand-built argparse parser with a declarative cli-components `Parser`: required subcommands, the script-source exclusive group, typed row/column values, and per-command help pages. - Requires Python 3.11 or newer, the minimum for cli-components. CI now tests on 3.11 and 3.13. - Adds tests that pin down help pages, usage errors and exit codes. **`feat!: Chain apply targets and require the apply command`** - `--row`, `--column` and `--cell` can be repeated and mixed. The script runs over them in the order given: ```sh modify-csv apply in.csv out.csv --script-file fix.py --column email --row 2 --cell 0 name ``` - A cell covered by several targets is transformed once per target, each time receiving the previous result. - Every target is checked before any cell changes, so one bad target writes nothing. - At least one target is required. - `transform_csv` also accepts a sequence of targets. Single-target calls are unchanged, including `target=` passed by keyword. - Each help page now documents only its own command's options. `modify-csv --help` lists the commands, and the script contract appears on `apply --help` and `template --help`. - Adds `BREAKING_CHANGES.md`, linked from the README, to track releases that aren't backward compatible. ## Breaking changes All of these are listed in `BREAKING_CHANGES.md` under **Unreleased**: - **Python 3.11 minimum.** - **`apply` is required.** The original form without a command (`modify-csv IN OUT --script-file F --row 2`) is gone. Every single-target `apply` command still works unchanged. - **Help and errors:** the root help page no longer shows the script contract. `--cell` errors now use the `apply` usage line, like every other argument error. At release time, rename the **Unreleased** heading to the release version. ## Verification - All 39 product tests and the release-tooling tests pass on Python 3.11 and 3.13. - Every README example, including the Python API snippet, runs as documented against a built wheel. - `twine check` passes on the wheel and sdist. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01XazST7Ly1bCbjWnhjrHXJk
Replace the hand-built argparse parser with a declarative cli-components
(>=2026.10.3) Parser. The apply and template subcommands, the two
exactly-one-of option groups, the row/column value checks and the eval
signature on every help page now come from the framework, and the
original form without the apply subcommand still works.

Command-line behaviour is unchanged except for --cell value errors,
which now use the apply subcommand's usage line and name the argument
(e.g. "modify-csv apply: error: argument --cell: row must be a zero-based
integer"), like every other argument error.

- Add tests that pin down help pages, usage errors and exit codes.
- Require Python 3.11 or newer (cli-components' minimum); test CI on
  3.11 and 3.13 instead of 3.10 and 3.13.
- Note the Python requirement in the README.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XazST7Ly1bCbjWnhjrHXJk
feat!: Chain apply targets and require the apply command
All checks were successful
CI / Python 3.11 on Linux (pull_request) Successful in 30s
CI / Python 3.13 on Linux (pull_request) Successful in 17s
CI / CI passed (pull_request) Successful in 17s
b99b660a63
Let apply take any number of --row, --column and --cell targets, in any
mix. They append to one ordered list, and the script runs over them in
the order given; a cell covered by several targets is transformed once
per target, each time receiving the previous result. Every target is
checked against the CSV before any cell changes, so a bad target
anywhere in the chain writes nothing. At least one target is required.

transform_csv accepts a sequence of targets as well as a single target,
with the same ordering and validate-first behaviour.

Scope the help pages: modify-csv --help is an overview of the apply and
template commands, and each command's page documents only its own
options. The script contract moves from the root page to apply and
template.

Remove the form without a command, and track incompatible releases in
BREAKING_CHANGES.md, linked from the README.

BREAKING CHANGE: the apply command is required; the original form
without it (modify-csv IN OUT --script-file F --row 2) is no longer
accepted. Every single-target apply command keeps working unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XazST7Ly1bCbjWnhjrHXJk
release.py prepare now renames the "## Unreleased" heading in
BREAKING_CHANGES.md to "## Released in v<version>" and includes it in the
release commit. A release without that heading is left untouched, and
more than one Unreleased heading is an error.

A new "release.py notes <version>" action prints that version's
breaking-changes section, or a backward-compatible note, and the staging
workflow uses it as the draft Forgejo Release body.

RELEASING.md documents both and lists the Python versions CI actually
tests (3.11 and 3.13).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkT5ZcGgGrktq26E71bJdt
README: absolute links so they work on PyPI, pipx/uv install, a quick
start, fuller script contract (return values, script lifetime, errors,
the eval name), inline vs file scripts, a runnable Python API example,
and a Behaviour and limits section covering encoding, CSV format, row
shape, header lookup, output safety, memory and exit statuses.

Export Target from modify_csv, add project URLs to pyproject.toml, scope
BREAKING_CHANGES.md and explain the Unreleased heading, and add
CONTRIBUTING.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkT5ZcGgGrktq26E71bJdt
style: Format with black and check it in CI
All checks were successful
CI / Python 3.11 on Linux (pull_request) Successful in 15s
CI / Python 3.13 on Linux (pull_request) Successful in 14s
CI / Black formatting (pull_request) Successful in 16s
CI / CI passed (pull_request) Successful in 13s
8c63af2507
Run black 26 over src, tests and scripts, configure it in pyproject.toml,
and add a Black formatting job that the CI passed check requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XkT5ZcGgGrktq26E71bJdt
martinjose deleted branch refactor/cli-components 2026-10-22 00:41:39 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
martinjose/modify-csv!8
No description provided.