diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 043ba6d..9c30fa0 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -1,9 +1,13 @@ name: CI on: workflow_dispatch: + push: + branches: + - master pull_request: paths-ignore: - 'docs/**' + - '**/*.md' jobs: Ruff: diff --git a/CHANGELOG.md b/CHANGELOG.md index 12ffc54..9ce7a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ 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.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.2] - 2024-07-11 + +### Changed + +- dropped 'verbose' argument from list_boards() +- dropped 'full' argument from version() + ## [0.1.1] - 2024-07-11 ### Added @@ -16,5 +23,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 _First release._ +[0.1.2]: https://github.com/int-brain-lab/tycmd-wrapper/releases/tag/v0.1.2 [0.1.1]: https://github.com/int-brain-lab/tycmd-wrapper/releases/tag/v0.1.1 [0.1.0]: https://github.com/int-brain-lab/tycmd-wrapper/releases/tag/v0.1.0 diff --git a/README.md b/README.md index fff256e..b041fce 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ Martignène](https://github.com/Koromix/). Documentation: https://int-brain-lab.github.io/tycmd-wrapper ![License](https://img.shields.io/github/license/int-brain-lab/tycmd-wrapper) -![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json) [![Coverage](https://img.shields.io/coverallsCoverage/github/int-brain-lab/tycmd-wrapper)](https://coveralls.io/github/int-brain-lab/tycmd-wrapper) [![CI](https://github.com/int-brain-lab/tycmd-wrapper/actions/workflows/testing.yaml/badge.svg)](https://github.com/int-brain-lab/tycmd-wrapper/actions) -[![Documentation](https://img.shields.io/badge/Sphinx-doc-green)](https://int-brain-lab.github.io/tycmd-wrapper) +[![PyPI](https://img.shields.io/pypi/v/tycmd-wrapper)](https://pypi.org/project/tycmd-wrapper/) diff --git a/docs/source/dev_guide.rst b/docs/source/dev_guide.rst index ea0d7d2..7e37e87 100644 --- a/docs/source/dev_guide.rst +++ b/docs/source/dev_guide.rst @@ -55,4 +55,4 @@ Building the package .. code-block:: bash - pdm build --config-setting="--python-tag=py3" --config-setting="--py-limited-api=none" \ No newline at end of file + pdm build \ No newline at end of file diff --git a/tests/test_tycmd.py b/tests/test_tycmd.py index 8f384e6..03662fe 100644 --- a/tests/test_tycmd.py +++ b/tests/test_tycmd.py @@ -1,15 +1,21 @@ from pathlib import Path from tempfile import TemporaryDirectory +from unittest.mock import patch import pytest import tycmd -import re BLINK_HEX = Path(__file__).parent.joinpath("blink.hex").resolve() +@pytest.fixture +def mock_check_output(): + with patch("tycmd.check_output") as mock_check_output: + yield mock_check_output + + def test_identify(): with TemporaryDirectory() as temp_directory: firmware_file = Path(temp_directory).joinpath("firmware.hex") @@ -19,13 +25,34 @@ def test_identify(): assert "Teensy 4.0" in tycmd.identify(BLINK_HEX) +def test_list_boards(mock_check_output): + mock_check_output.return_value = ( + '[\n {"action": "add", "tag": "12345678-Teensy", "serial": "12345678", ' + '"description": "USB Serial", "model": "Teensy 4.1", "location": "usb-3-3", ' + '"capabilities": ["unique", "run", "rtc", "reboot", "serial"], ' + '"interfaces": [["Serial", "/dev/ttyACM0"]]}\n]\n' + ) + output = tycmd.list_boards() + mock_check_output.assert_called_once_with( + ["tycmd", "list", "-O", "json", "-v"], text=True + ) + assert isinstance(output, list) + assert isinstance(output[0], dict) + assert output[0]["serial"] == "12345678" + + mock_check_output.return_value = "[\n]\n" + output = tycmd.list_boards() + assert isinstance(output, list) + assert len(output) == 0 + + def test_version(): - output = tycmd.version(full=True) - assert isinstance(output, str) - match = re.search(r"^.+(\d+\.\d+\.\d+)", output) - assert match is not None - assert match.groups()[0] == tycmd._TYCMD_VERSION - assert tycmd.version(full=False) == tycmd._TYCMD_VERSION + assert tycmd.version() == tycmd._TYCMD_VERSION + with ( + patch("tycmd.check_output", return_value="invalid") as _, + pytest.raises(RuntimeError), + ): + tycmd.version() def test__parse_firmware_file(): diff --git a/tycmd.py b/tycmd.py index 0daf15c..53c89bd 100644 --- a/tycmd.py +++ b/tycmd.py @@ -6,7 +6,7 @@ import re from logging import getLogger -__version__ = "0.1.1" +__version__ = "0.1.2" _TYCMD_VERSION = "0.9.9" log = getLogger(__name__) @@ -35,45 +35,39 @@ def identify(filename: Path | str) -> list[str]: return output.get("models", []) -def list_boards(verbose: bool = True) -> list[dict]: +def list_boards() -> list[dict]: """ List available boards. - Parameters - ---------- - verbose : bool, optional - If True, include detailed information about devices. Default is True. - Returns ------- list[dict] List of available devices. """ - args = ["tycmd", "list", "-O", "json"] + (["-v"] if verbose else []) - return json.loads(check_output(args, text=True)) + args = ["tycmd", "list", "-O", "json", "-v"] + return_string = check_output(args, text=True) + return json.loads(return_string) -def version(full: bool = False) -> str: +def version() -> str: """ - Return version information from tycmd. - - Parameters - ---------- - full : bool, optional - If True, return the full version string as returned by the tycmd binary. If - False, return only the version number. Default is False. + Return version information from tycmd binary. Returns ------- str The version of tycmd. + + Raises + ------ + RuntimeError + If the version string could not be determined. """ output = _call_tycmd(["--version"]) - if full: - return output.strip() + match = re.search(r"\d+\.\d+\.\d+", output) + if match is None: + raise RuntimeError("Could not determine tycmd version") else: - if (match := re.search(r"\d+\.\d+\.\d+", output)) is None: - return "" return match.group()