Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit 0ad1f51

Browse files
Migrate all drivers to use driver_click_group or driver_click_command decorator
Replace @click.group decorators with @driver_click_group and @click.command with @driver_click_command in all drivers, and use it to provide server-side driver description. The CLI client will retrieve customized driver's description via GetReport() from the exporter. When there's no customization it falls back to locally provided default in docstring or help=.
1 parent 347388c commit 0ad1f51

13 files changed

Lines changed: 51 additions & 27 deletions

File tree

  • packages
    • jumpstarter-driver-composite/jumpstarter_driver_composite
    • jumpstarter-driver-flashers/jumpstarter_driver_flashers
    • jumpstarter-driver-gpiod/jumpstarter_driver_gpiod
    • jumpstarter-driver-network/jumpstarter_driver_network
    • jumpstarter-driver-opendal/jumpstarter_driver_opendal
    • jumpstarter-driver-power/jumpstarter_driver_power
    • jumpstarter-driver-probe-rs/jumpstarter_driver_probe_rs
    • jumpstarter-driver-pyserial/jumpstarter_driver_pyserial
    • jumpstarter-driver-ridesx/jumpstarter_driver_ridesx
    • jumpstarter-driver-shell/jumpstarter_driver_shell
    • jumpstarter-driver-snmp/jumpstarter_driver_snmp
    • jumpstarter-driver-ssh/jumpstarter_driver_ssh
    • jumpstarter-driver-tmt/jumpstarter_driver_tmt

packages/jumpstarter-driver-composite/jumpstarter_driver_composite/client.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from rich import traceback
66

77
from jumpstarter.client import DriverClient
8+
from jumpstarter.client.decorators import driver_click_group
89

910

1011
def _opt_log_level_callback(ctx, param, value):
@@ -34,18 +35,18 @@ def close(self):
3435
v.close()
3536

3637
def cli(self):
37-
@click.group
38-
@click.option(
38+
@driver_click_group(self)
39+
def base():
40+
"""Generic composite device"""
41+
pass
42+
43+
base.add_option(
3944
"--log-level",
40-
"log_level",
4145
type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]),
4246
help="Set the log level",
4347
expose_value=False,
4448
callback=_opt_log_level_callback,
4549
)
46-
def base():
47-
"""Generic composite device"""
48-
pass
4950

5051
for k, v in self.children.items():
5152
if hasattr(v, "cli"):

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from jumpstarter_driver_flashers.bundle import FlasherBundleManifestV1Alpha1
2323

24+
from jumpstarter.client.decorators import driver_click_group
2425
from jumpstarter.common.exceptions import ArgumentError
2526

2627
debug_console_option = click.option("--console-debug", is_flag=True, help="Enable console debug mode")
@@ -750,7 +751,7 @@ def _validate_bearer_token(self, token: str | None) -> str | None:
750751
return token
751752

752753
def cli(self):
753-
@click.group
754+
@driver_click_group(self)
754755
def base():
755756
"""Software-defined flasher interface"""
756757
pass

packages/jumpstarter-driver-gpiod/jumpstarter_driver_gpiod/client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from jumpstarter_driver_power.client import PowerClient
66

77
from jumpstarter.client import DriverClient
8+
from jumpstarter.client.decorators import driver_click_group
89

910

1011
class PinState(Enum):
@@ -34,7 +35,7 @@ def read(self):
3435
return PinState(int(self.call("read_pin")))
3536

3637
def cli(self):
37-
@click.group()
38+
@driver_click_group(self)
3839
def gpio():
3940
"""GPIO power control commands."""
4041
pass
@@ -79,7 +80,7 @@ def read(self):
7980
return PinState(int(self.call("read_pin")))
8081

8182
def cli(self):
82-
@click.group()
83+
@driver_click_group(self)
8384
def gpio():
8485
"""GPIO input commands."""
8586
pass

packages/jumpstarter-driver-network/jumpstarter_driver_network/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .driver import DbusNetwork
1313
from jumpstarter.client import DriverClient
1414
from jumpstarter.client.core import DriverMethodNotImplemented
15+
from jumpstarter.client.decorators import driver_click_group
1516

1617

1718
class NetworkClient(DriverClient):
@@ -20,7 +21,7 @@ def address(self):
2021
return self.call("address")
2122

2223
def cli(self):
23-
@click.group
24+
@driver_click_group(self)
2425
def base():
2526
"""Generic Network Connection"""
2627
pass

packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from .adapter import OpendalAdapter
2020
from .common import Capability, HashAlgo, Metadata, Mode, PathBuf, PresignedRequest
2121
from jumpstarter.client import DriverClient
22+
from jumpstarter.client.decorators import driver_click_group
2223
from jumpstarter.common.exceptions import ArgumentError
2324
from jumpstarter.streams.encoding import Compression
2425

@@ -413,9 +414,10 @@ def cli(self): # noqa: C901
413414
arg_dst = click.argument("dst", type=click.Path())
414415
opt_expire_second = click.option("--expire-second", type=int, required=True)
415416

416-
@click.group
417+
@driver_click_group(self)
417418
def base():
418419
"""Opendal Storage"""
420+
pass
419421

420422
@base.command
421423
@arg_path
@@ -548,7 +550,7 @@ def dump(
548550
...
549551

550552
def cli(self):
551-
@click.group
553+
@driver_click_group(self)
552554
def base():
553555
"""Generic flasher interface"""
554556
pass
@@ -716,7 +718,10 @@ def read_local_file(self, filepath):
716718

717719
def cli(self, base=None):
718720
if base is None:
719-
base = click.group(lambda: None)
721+
@driver_click_group(self)
722+
def base():
723+
"""Storage operations"""
724+
pass
720725

721726
@base.command()
722727
def host():

packages/jumpstarter-driver-power/jumpstarter_driver_power/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from .common import PowerReading
77
from jumpstarter.client import DriverClient
8+
from jumpstarter.client.decorators import driver_click_group
89

910

1011
class PowerClient(DriverClient):
@@ -35,7 +36,7 @@ def read(self) -> Generator[PowerReading, None, None]:
3536
yield PowerReading.model_validate(v, strict=True)
3637

3738
def cli(self):
38-
@click.group
39+
@driver_click_group(self)
3940
def base():
4041
"""Generic power"""
4142
pass

packages/jumpstarter-driver-probe-rs/jumpstarter_driver_probe_rs/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from opendal import Operator
77

88
from jumpstarter.client import DriverClient
9+
from jumpstarter.client.decorators import driver_click_group
910
from jumpstarter.common.exceptions import ArgumentError
1011

1112

@@ -60,7 +61,7 @@ def read(self, width: int, address: int, words: int) -> list[int]:
6061
return [int(data, 16) for data in data_strs]
6162

6263
def cli(self): # noqa: C901
63-
@click.group
64+
@driver_click_group(self)
6465
def base():
6566
"""probe-rs client"""
6667
pass

packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from .console import Console
88
from jumpstarter.client import DriverClient
9+
from jumpstarter.client.decorators import driver_click_group
910

1011

1112
class PySerialClient(DriverClient):
@@ -36,7 +37,7 @@ def pexpect(self):
3637
yield adapter
3738

3839
def cli(self):
39-
@click.group
40+
@driver_click_group(self)
4041
def base():
4142
"""Serial port client"""
4243
pass

packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
from pathlib import Path
33
from typing import Dict, Optional
44

5-
import click
65
from jumpstarter_driver_composite.client import CompositeClient
76
from jumpstarter_driver_opendal.client import FlasherClient, operator_for_path
87
from jumpstarter_driver_power.client import PowerClient
98
from opendal import Operator
109

10+
from jumpstarter.client.decorators import driver_click_group
11+
1112
PROMPT = "CMD >> "
1213

1314

@@ -102,8 +103,9 @@ def flash(
102103
def cli(self):
103104
generic_cli = FlasherClient.cli(self)
104105

105-
@click.group()
106+
@driver_click_group(self)
106107
def storage():
108+
"""RideSX storage operations"""
107109
pass
108110

109111
for name, cmd in generic_cli.commands.items():

packages/jumpstarter-driver-shell/jumpstarter_driver_shell/client.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import click
55

66
from jumpstarter.client import DriverClient
7+
from jumpstarter.client.decorators import driver_click_group
78

89

910
@dataclass(kw_only=True)
@@ -41,7 +42,7 @@ def execute(*args, **kwargs):
4142

4243
def cli(self):
4344
"""Create CLI interface for dynamically configured shell methods"""
44-
@click.group
45+
@driver_click_group(self)
4546
def base():
4647
"""Shell command executor"""
4748
pass
@@ -80,12 +81,12 @@ def method_command(args, env):
8081
except Exception:
8182
description = f"Execute the {method_name} shell method"
8283

83-
# Decorate and register the command
84-
method_command.__doc__ = description
84+
# Decorate and register the command with help text
8585
method_command = click.argument('args', nargs=-1, type=click.UNPROCESSED)(method_command)
8686
method_command = click.option('--env', '-e', multiple=True,
8787
help='Environment variables in KEY=VALUE format')(method_command)
8888
method_command = group.command(
8989
name=method_name,
90+
help=description,
9091
context_settings={"ignore_unknown_options": True, "allow_interspersed_args": False},
9192
)(method_command)

0 commit comments

Comments
 (0)