diff --git a/src/fastcs/launch.py b/src/fastcs/launch.py index d3d3fcf7..521fd27f 100644 --- a/src/fastcs/launch.py +++ b/src/fastcs/launch.py @@ -7,6 +7,8 @@ from pydantic import BaseModel, create_model from ruamel.yaml import YAML +from fastcs.__main__ import __version__ + from .backend import Backend from .controller import Controller from .exceptions import LaunchError @@ -62,7 +64,10 @@ def run(self) -> None: self._transport.run() -def launch(controller_class: type[Controller]) -> None: +def launch( + controller_class: type[Controller], + version: str | None = None, +) -> None: """ Serves as an entry point for starting FastCS applications. @@ -72,7 +77,9 @@ def launch(controller_class: type[Controller]) -> None: Args: controller_class (type[Controller]): The FastCS Controller to instantiate. - It must have a type-hinted __init__ method and no more than 2 arguments. + It must have a type-hinted __init__ method and no more than 2 arguments. + version (Optional[str]): The version of the FastCS Controller. + Optional Raises: LaunchError: If the class's __init__ is not as expected @@ -86,10 +93,13 @@ def __init__(self, my_arg: MyControllerOptions) -> None: if __name__ == "__main__": launch(MyController) """ - _launch(controller_class)() + _launch(controller_class, version)() -def _launch(controller_class: type[Controller]) -> typer.Typer: +def _launch( + controller_class: type[Controller], + version: str | None = None, +) -> typer.Typer: fastcs_options = _extract_options_model(controller_class) launch_typer = typer.Typer() @@ -146,6 +156,12 @@ def run( instance.create_docs() instance.run() + @launch_typer.command(name="version", help=f"{controller_class.__name__} version") + def version_command(): + if version: + print(f"{controller_class.__name__}: {version}") + print(f"FastCS: {__version__}") + return launch_typer diff --git a/tests/test_launch.py b/tests/test_launch.py index e703fcba..ad29f972 100644 --- a/tests/test_launch.py +++ b/tests/test_launch.py @@ -6,6 +6,7 @@ from pytest_mock import MockerFixture from typer.testing import CliRunner +from fastcs.__main__ import __version__ from fastcs.controller import Controller from fastcs.exceptions import LaunchError from fastcs.launch import TransportOptions, _launch, launch @@ -99,6 +100,23 @@ def test_over_defined_schema(): assert str(exc_info.value) == error +def test_version(): + impl_version = "0.0.1" + expected = f"SingleArg: {impl_version}\n" f"FastCS: {__version__}\n" + app = _launch(SingleArg, version=impl_version) + result = runner.invoke(app, ["version"]) + assert result.exit_code == 0 + assert result.stdout == expected + + +def test_no_version(): + expected = f"FastCS: {__version__}\n" + app = _launch(SingleArg) + result = runner.invoke(app, ["version"]) + assert result.exit_code == 0 + assert result.stdout == expected + + def test_launch_minimal(mocker: MockerFixture, data): run = mocker.patch("fastcs.launch.FastCS.run") gui = mocker.patch("fastcs.launch.FastCS.create_gui")