v0.12.2 - CLI Refactoring & Code Quality (2026-04-06)¶
What Changed?¶
This release improves fnb's maintainability through CLI option consolidation. A new options.py module centralizes all Typer option definitions, eliminating code duplication across commands and improving consistency. This refactoring reduces cli.py by 83 lines while maintaining 100% backward compatibility.
What's New¶
Main Feature: Centralized CLI Options Module¶
What it does:
Consolidates scattered CLI option definitions (--log-level, --verbose, --quiet, --config, etc.) into a single, reusable Options class. All commands now reference these centralized definitions instead of duplicating option specifications.
How to use it:
No changes required for end users. The CLI behavior remains identical, but internally:
- All commands use Options.log_level(), Options.verbose(), etc.
- Help text consistency is guaranteed
- Option modifications now require changes in only one place
Code example:
# Before: Scattered definitions in each command
@app.command()
def fetch(
label: str,
dry_run: bool = typer.Option(False, "--dry-run", "-n", help="..."),
log_level: str = typer.Option("INFO", "--log-level", help="..."),
...
) -> None:
pass
# After: Centralized in options.py
from fnb.options import Options
@app.command()
def fetch(
label: str,
dry_run: bool = Options.dry_run(),
log_level: str = Options.log_level(),
...
) -> None:
pass
Installation¶
Quick Start¶
# Get the release
git checkout v0.12.2
# Install dependencies
uv pip install -e .
# Verify installation
fnb --help
fnb fetch --help
What's Different from the Last Version?¶
✅ Added¶
- New
options.pymodule - Centralized CLI option definitions with 8 reusable methods - Type-safe log levels -
LogLeveltype hint for compile-time validation
🔧 Changed¶
- CLI signature simplification - All commands now use
Options.*()methods instead of inlinetyper.Option()definitions - Code reduction - cli.py reduced from 597 lines to 514 lines (-83 lines)
🐛 Fixed¶
- CI/CD improvements - Resolved pytest execution failure by installing dev dependencies
Is It Safe to Upgrade?¶
Backward Compatible: Yes ✅
- Help text unchanged - All CLI help output remains identical
- Command behavior unchanged - All commands work exactly as before
- Default values preserved - All option defaults remain the same
- No breaking changes - Existing scripts and workflows continue to work without modification
Tests Passed¶
- ✅ 124 unit tests pass (83% coverage)
- ✅ 23 integration tests pass (100% success rate)
- ✅ Total: 141 tests pass with 87% code coverage
- ✅ options.py achieves 100% test coverage
- ✅ CLI help output verified unchanged
- ✅ All commands functional (fetch, backup, sync, status, init, version)
Code Quality Improvements¶
Maintainability¶
- DRY Principle: Eliminated duplicate option definitions across 4 commands
- Single Source of Truth: Option changes now require modifications in only one module
- Consistency: All help texts and default values guaranteed to match across commands
Type Safety¶
- Literal Types:
LogLevel = Literal["DEBUG", "INFO", "WARNING", "ERROR"]enables compile-time validation - Static Analysis: mypy and ruff properly validate option usage
Test Coverage¶
| Module | Coverage |
|---|---|
| options.py | 100% ✅ |
| cli.py | 97% |
| Overall | 87% |
Release Details¶
- Date: 2026-04-06
- Version: v0.12.2
- Files Changed: 2
src/fnb/options.py(new, 125 lines)src/fnb/cli.py(modified, -83 lines)- Commits:
826a3d3- refactor: consolidate CLI options into options.py moduleac15d92- fix(ci): install dev dependencies to resolve pytest execution failure
Design Pattern Reference¶
This refactoring follows the established pattern from the kazunoko project:
- Static method factory for option generation
- Centralized class (Options) for grouping related definitions
- Type hints for validation (LogLevel type alias)
- Full documentation in each method docstring
Next Steps¶
Future improvements in the pipeline:
- fetch/backup Code Deduplication - Extract common operation logic into
RsyncOperationbase class - CLI Command Integration - Consolidate similar command implementations
- Operation Result Objects - Replace boolean returns with structured result objects for better error reporting
See GitHub Issue #46 for implementation details and discussion.
Upgrading from v0.12.1¶
No special steps required. Simply checkout the new tag and reinstall:
All existing configurations and workflows continue to work without modification.