Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .flake8

This file was deleted.

34 changes: 34 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Build distribution
description: Builds the distribution

runs:
using: composite
steps:
- name: Disable initramfs update
shell: bash
run: sudo sed -i 's/yes/no/g' /etc/initramfs-tools/update-initramfs.conf

- name: Disable man-db update
shell: bash
run: sudo rm -f /var/lib/man-db/auto-update

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"

- name: Install uv
shell: bash
run: python3 -m pip install uv

- name: Build distribution packages
shell: bash
run: uv build
env:
UV_PROJECT_ENVIRONMENT: .venv

- name: Store distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
42 changes: 42 additions & 0 deletions .github/actions/check/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Run linter and tests
description: Runs the format check, linter, type check and tests

runs:
using: composite
steps:
- name: Disable initramfs update
shell: bash
run: sudo sed -i 's/yes/no/g' /etc/initramfs-tools/update-initramfs.conf

- name: Disable man-db update
shell: bash
run: sudo rm -f /var/lib/man-db/auto-update

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"

- name: Install uv
shell: bash
run: python3 -m pip install uv

- name: Setup project
shell: bash
run: uv sync --group dev
env:
UV_PROJECT_ENVIRONMENT: .venv

- name: Run ruff check
uses: astral-sh/ruff-action@v3
with:
args: "check"

- name: Run ruff format check
uses: astral-sh/ruff-action@v3
with:
args: "format --check"

- name: Run tests
shell: bash
run: uv run pytest tests/ --replay -v
28 changes: 28 additions & 0 deletions .github/workflows/check-and-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Check and Build

on:
workflow_call:

jobs:
check:
name: Check
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check
uses: ./.github/actions/check

build:
name: Build
runs-on: ubuntu-latest
needs: [check]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Build
uses: ./.github/actions/build
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: Continuous Integration

on:
pull_request:
branches: [main]

jobs:
check-and-build:
uses: ./.github/workflows/check-and-build.yml
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ __pycache__/
# Distribution / packaging
.Python
build/
!.github/actions/build/
develop-eggs/
dist/
downloads/
Expand Down Expand Up @@ -127,3 +128,13 @@ dmypy.json

# Pyre type checker
.pyre/

# Devenv
.devenv*
devenv.local.nix

# direnv
.direnv

# pre-commit
.pre-commit-config.yaml
16 changes: 7 additions & 9 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
{
"python.analysis.typeCheckingMode": "basic",
"python.linting.flake8Enabled": true,
"python.linting.mypyEnabled": true,
"python.linting.mypyCategorySeverity.note": "Warning",
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "ms-python.black-formatter"
},
}
"python.analysis.typeCheckingMode": "strict",
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff"
}
}

136 changes: 136 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2025-10-17

### Added

- **High-level KVM interface**: New `KVM` class in `kvm.py` providing type-safe, structured interface for library usage
- **Multi-device addressing**: Support for controlling multiple KVM switches on the same serial bus (addresses 0-99)
- **Device discovery**: New `discover` command to find all devices on the serial bus with their firmware versions
- **Comprehensive CLI commands** (replacing simple console.py):
- `status`: Show system status with firmware version and address
- `help`: Display device help information
- `input switch`: Switch inputs with output selection
- `output routing`: Query current input-to-output routing
- `output stream`: Check output stream status
- `edid get/set`: Manage EDID data for inputs
- `discover`: Find all devices on the serial bus
- Multiple output formats: `--format raw|json|pretty`
- **Comprehensive test suite**: Full test coverage with pytest
- Unit tests for `Device`, `KVM`, and CLI commands
- Integration tests for end-to-end workflows
- Hardware replay tests using pytest-reserial (no hardware needed for CI)
- Test coverage reporting with pytest-cov
- **Test scripts** for different testing scenarios:
- `test-record.sh`: Record serial traffic from real hardware
- `test-replay.sh`: Run tests using recorded traffic (CI-friendly)
- `test-with-hardware.sh`: Run tests with actual hardware
- **Enhanced documentation**:
- Extensive README with installation, usage examples, and library usage guide
- Development setup instructions with uv
- Testing documentation
- **Product documentation**: Added official EZCOO KVM switch manual (PDF) in `docs/`
- **CI/CD workflows**: GitHub Actions for automated testing and building on pull requests
- Composite actions for check and build steps
- Reusable workflow for check-and-build
- CI workflow triggered on PRs to main
- **Release documentation**: Complete manual release process guide in `RELEASING.md` including:
- Version bumping and changelog updates
- GitHub release creation
- PyPI publishing
- AUR package updates

### Changed

- **BREAKING**: License changed from Apache-2.0 to GPL-3.0-or-later
- **BREAKING**: Migrated from Poetry to uv for dependency management
- Removed `poetry.lock` and `poetry.toml`
- Added `uv.lock` and updated `pyproject.toml` to use PEP 621 format
- Changed build backend from poetry-core to hatchling
- **BREAKING**: Migrated from flake8 to ruff for linting and formatting
- Removed flake8, flake8-black, flake8-import-order
- Added ruff with comprehensive rule configuration
- Removed `.flake8` configuration file
- **BREAKING**: Complete CLI rewrite (`cli.py` replaces `console.py`)
- New command structure with subcommands and groups
- Added `--address` option for multi-device support
- Added `--format` option for output formatting (raw/json/pretty)
- Default output format changed from raw device response to human-readable pretty format
- Removed direct device command exposure
- All commands now use high-level KVM interface
- **BREAKING**: Enhanced `Device` class with improved error handling
- Added `DeviceError` and `DeviceConnectionError` exceptions
- Added command validation to prevent injection attacks
- Better error messages for connection and communication failures
- Configurable baudrate and timeout parameters
- Type hints updated to use modern Python 3.10+ syntax (`Self`, `type[]`)
- **BREAKING**: Response parsing now returns structured `KVMResponse[T]` objects
- Generic type parameter ensures type safety
- Includes raw command, raw response lines, and parsed response
- Enables both programmatic access and raw output
- **Type safety improvements**:
- Added `StreamState` enum for on/off states
- Generic `KVMResponse[T]` wrapper for all responses
- Proper type hints throughout codebase
- Dataclasses for all structured data
- **Dependencies**:
- Removed: `attrs`, `mypy`, `flake8` family
- Added: `pytest`, `pytest-cov`, `pytest-reserial`, `ruff`
- Updated: `click` to 8.1.3+, `pyserial` to 3.5+
- Minimum Python version: 3.10

### Removed

- **console.py**: Replaced by comprehensive `cli.py` with structured commands
- **Poetry configuration**: Migrated to uv
- **flake8 configuration**: Migrated to ruff
- **attrs dependency**: Replaced with standard library dataclasses

### Fixed

- Improved error handling in device communication with specific exception types
- Better validation of command responses with structured parsing
- More reliable serial port handling with proper connection error handling
- Command injection prevention through input validation

### Development

- Added `.vscode/settings.json` with Python and testing configurations
- Updated `.gitignore` with uv-specific patterns and test artifacts
- Enhanced `pyproject.toml` with:
- Ruff configuration (line length, linting rules)
- Pytest configuration (test paths, coverage options)
- Coverage configuration (source paths, exclusions)
- Dependency groups for dev dependencies

## [0.1.1] - 2024-XX-XX

### Changed

- Bump dependencies

## [0.1.0] - 2024-XX-XX

### Fixed

- Fix wrong baudrate

### Changed

- Move things around and refactoring

## [0.0.1] - 2024-XX-XX

### Added

- Initial PoC implementation

[0.2.0]: https://github.com/Luminger/ezcoo-cli/compare/0.1.1...0.2.0
[0.1.1]: https://github.com/Luminger/ezcoo-cli/compare/0.1.0...0.1.1
[0.1.0]: https://github.com/Luminger/ezcoo-cli/compare/0.0.1...0.1.0
[0.0.1]: https://github.com/Luminger/ezcoo-cli/releases/tag/0.0.1
Loading