Skip to content

Commit aec438a

Browse files
authored
Show origin of subcommands in help message (#20)
Close #18
1 parent a763e13 commit aec438a

5 files changed

Lines changed: 63 additions & 6 deletions

File tree

pyodide_cli/app.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
from importlib.metadata import entry_points
55

66
import typer # type: ignore[import]
7+
from typer.main import TyperInfo, solve_typer_info_help # type: ignore[import]
78

89
from . import __version__
910

10-
app = typer.Typer(add_completion=False)
11+
app = typer.Typer(add_completion=False, rich_markup_mode="markdown")
1112

1213

1314
def version_callback(value: bool):
@@ -31,28 +32,45 @@ def callback(
3132
pass
3233

3334

34-
def entrypoint_to_pkgname(entrypoint: EntryPoint) -> str:
35+
def _entrypoint_to_pkgname(entrypoint: EntryPoint) -> str:
3536
"""Find package name from entrypoint"""
3637

3738
top_level = entrypoint.value.split(".")[0]
3839
dist = importlib_distribution(top_level)
3940
return dist.metadata["name"]
4041

4142

43+
def _inject_origin(docstring: str, origin: str) -> str:
44+
return f"{docstring}\n\n{origin}"
45+
46+
4247
def register_plugins():
4348
"""Register subcommands via the ``pyodide.cli`` entry-point"""
4449
eps = entry_points(group="pyodide.cli")
4550
plugins = {ep.name: (ep.load(), ep) for ep in eps}
4651
for plugin_name, (module, ep) in plugins.items():
47-
pkgname = entrypoint_to_pkgname(ep)
52+
pkgname = _entrypoint_to_pkgname(ep)
53+
origin_text = f"Registered by: {pkgname}"
54+
4855
if isinstance(module, typer.Typer):
56+
typer_info = TyperInfo(module)
57+
help_with_origin = _inject_origin(
58+
solve_typer_info_help(typer_info), origin_text
59+
)
4960
app.add_typer(
50-
module, name=plugin_name, rich_help_panel=f"Registered by: {pkgname}"
61+
module,
62+
name=plugin_name,
63+
rich_help_panel=origin_text,
64+
help=help_with_origin,
5165
)
5266
elif callable(module):
5367
typer_kwargs = getattr(module, "typer_kwargs", {})
68+
help_with_origin = _inject_origin(module.__doc__, origin_text)
5469
app.command(
55-
plugin_name, rich_help_panel=f"Registered by: {pkgname}", **typer_kwargs
70+
plugin_name,
71+
rich_help_panel=origin_text,
72+
help=help_with_origin,
73+
**typer_kwargs,
5674
)(module)
5775
else:
5876
raise RuntimeError(f"Invalid plugin: {plugin_name}")
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import typer # type: ignore[import]
2+
3+
app = typer.Typer()
4+
5+
6+
@app.callback()
7+
def callback():
8+
"""
9+
Test help message short desc
10+
11+
Test help message long desc
12+
"""
13+
pass
14+
15+
16+
@app.command()
17+
def hello(name: str = typer.Argument(..., help="Test argument")):
18+
"""
19+
Test help message short desc
20+
21+
Test help message long desc
22+
"""
23+
typer.echo(f"Hello {name}")
24+
pass
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
def main():
2+
"""
3+
Test help message short desc
4+
5+
Test help message long desc
6+
"""
27
pass

pyodide_cli/tests/plugin-test/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ version = "1.0.0"
88
authors = []
99

1010
[project.entry-points."pyodide.cli"]
11-
plugin_test = "plugin_test.main:main"
11+
plugin_test_func = "plugin_test.main:main"
12+
plugin_test_app = "plugin_test.app:app"

pyodide_cli/tests/test_cli.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,12 @@ def test_plugin_origin(plugins):
5757
msg = "Registered by: plugin-test"
5858

5959
assert msg in output
60+
61+
62+
@pytest.mark.parametrize("entrypoint", ["plugin_test_app", "plugin_test_func"])
63+
def test_plugin_origin_subcommand(plugins, entrypoint):
64+
65+
output = check_output(["pyodide", entrypoint, "--help"]).decode("utf-8")
66+
msg = "Registered by: plugin-test"
67+
68+
assert msg in output

0 commit comments

Comments
 (0)