v1.9.6 - CLI Options Module Refactoring (2025-12-29)#
What Changed?#
This release refactors the monolithic cli/options.py (770 lines) into a modular directory structure with individual option classes in separate files.
All functionality is preserved through re-exports, ensuring zero breaking changes.
This improves code maintainability and follows the Single Responsibility Principle.
What’s New#
CLI Options Modularization#
What it does:
The large src/haniwers/v1/cli/options.py file (770 lines, 9 option classes) has been decomposed into a modular package structure:
src/haniwers/v1/cli/options/
├── __init__.py # Re-exports all option classes for backward compatibility
├── config.py # ConfigOptions (1 option: config)
├── device.py # DeviceOptions (4 options: port, baudrate, timeout, device_label)
├── logger.py # LoggerOptions (2 options: verbose, logfile)
├── output.py # OutputOptions (3 options: workspace, filename_prefix, filename_suffix)
├── preprocess.py # PreprocessOptions (2 options: interval, offset)
├── sampler.py # SamplerOptions (6 options: label, events_per_file, number_of_files, stream_mode, mode, duration)
├── scan.py # ScanOptions (2 options: nsteps, step)
├── testing.py # TestingOptions (10 options: mock, label, load_from, random, events, speed, shuffle, jitter, loop, seed)
└── threshold.py # ThresholdOptions (4 options: thresholds, suppress_threshold, max_retry, history)
How to use it: No changes needed! All imports continue to work exactly as before:
# Old way (still works):
from haniwers.v1.cli.options import DeviceOptions, OutputOptions, SamplerOptions
# CLI commands can use options the same way:
def my_command(
port: Optional[str] = DeviceOptions.port,
workspace: Optional[Path] = OutputOptions.workspace,
label: Optional[str] = SamplerOptions.label,
) -> None:
"""My CLI command using common options."""
pass
Benefits:
Improved Maintainability: Each option class in its own file (max 190 lines) instead of 770 lines total
Single Responsibility: Each module has one clear purpose
Better Organization: Related options are grouped logically
Easier Navigation: IDE can quickly locate option definitions
Future-Proof: Easy to extend with new option classes without bloating a single file
Backward Compatible: Existing imports continue to work without modification
Installation#
Quick Start#
# Get the release
git checkout v1.9.6
# Setup
task env:setup
# Run CLI
haniwers-v1 --help
What’s Different from the Last Version?#
✅ Added#
Modular
cli/options/directory structure with 9 individual option class modulesComprehensive
__init__.pythat re-exports all option classes for backward compatibility
🔧 Changed#
Moved
ConfigOptionstocli/options/config.pyMoved
DeviceOptionstocli/options/device.pyMoved
LoggerOptionstocli/options/logger.pyMoved
OutputOptionstocli/options/output.pyMoved
PreprocessOptionstocli/options/preprocess.pyMoved
SamplerOptionstocli/options/sampler.pyMoved
ScanOptionstocli/options/scan.pyMoved
TestingOptionstocli/options/testing.pyMoved
ThresholdOptionstocli/options/threshold.py
🐛 Fixed#
No bug fixes in this release
Is It Safe to Upgrade?#
Backward Compatible: ✅ Yes
All existing imports continue to work without modification
No CLI interface changes—purely internal code organization
All option definitions and behaviors unchanged
Re-exports from
__init__.pyensure drop-in compatibility
Tests Passed#
✅ Builds without errors
✅ All unit tests passing (379 selected)
✅ Module structure validated
✅ Import re-exports verified
✅ Pre-commit hooks passing (ruff format, YAML, etc.)
Release Details#
Date: 2025-12-29
Version: v1.9.6
Files Changed: 11 (9 new modules +
__init__.py+ deleted original options.py)Commits:
715631c: refactor(cli/options): extract ConfigOptions to separate module
5599148: refactor(cli/options): extract DeviceOptions to separate module
83e41a8: refactor(cli/options): extract OutputOptions to separate module
0b6c8da: refactor(cli/options): extract SamplerOptions to separate module
73541ee: refactor(cli/options): extract ThresholdOptions to separate module
81b6543: refactor(cli/options): extract PreprocessOptions to separate module
1d7907f: refactor(cli/options): extract ScanOptions to separate module
56bd858: refactor(cli/options): extract TestingOptions to separate module
82ada3f: refactor(cli/options): extract LoggerOptions to separate module
cb8702a: refactor(cli/options): create
__init__.pyto re-export all option classesd5bce12: refactor(cli/options): remove original monolithic options.py file
bfafd91: bump: version 1.9.5 → 1.9.6
Next Steps#
Phase 2.1 (v1.9.7 planned): Decompose
sampler.py(1,591 lines) into modular structureSimilar modular pattern as cli/options.py
Split into:
_base.py,_reader.py,_writer.py,_iterators.py,_progress.pyMaintain backward compatibility through re-exports
Phase 2.2 (v1.9.8 planned): Decompose
config/model.py(1,184 lines)Split into:
device.py,acquisition.py,threshold.py,haniwers.pyUnified export structure
Phase 3 (v1.10.0): Technical debt resolution
Fix failing integration tests
Resolve TODO comments with implementations
v1.11.0: Complete removal of deprecated
DaqConfigandScanConfigmodelsRemoval timeline: Deprecation warnings added in v1.9.5, removal in v1.11.0
Users have v1.9.6 - v1.10.x to migrate configurations