0
0
mirror of https://github.com/ihabunek/toot.git synced 2025-06-30 22:18:36 -04:00

Rework how app, user are passed to context

This commit is contained in:
Ivan Habunek 2023-12-14 10:11:09 +01:00
parent 164016481d
commit 2f3f686a00
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
3 changed files with 46 additions and 28 deletions

View File

@ -24,6 +24,7 @@ from click.testing import CliRunner, Result
from pathlib import Path from pathlib import Path
from toot import api, App, User from toot import api, App, User
from toot.cli import Context from toot.cli import Context
from toot.cli.base import TootObj
def pytest_configure(config): def pytest_configure(config):
@ -116,24 +117,24 @@ def runner():
@pytest.fixture @pytest.fixture
def run(app, user, runner): def run(app, user, runner):
def _run(command, *params, input=None) -> Result: def _run(command, *params, input=None) -> Result:
ctx = Context(app, user) obj = TootObj(test_ctx=Context(app, user))
return runner.invoke(command, params, obj=ctx, input=input) return runner.invoke(command, params, obj=obj, input=input)
return _run return _run
@pytest.fixture @pytest.fixture
def run_as(app, runner): def run_as(app, runner):
def _run_as(user, command, *params, input=None) -> Result: def _run_as(user, command, *params, input=None) -> Result:
ctx = Context(app, user) obj = TootObj(test_ctx=Context(app, user))
return runner.invoke(command, params, obj=ctx, input=input) return runner.invoke(command, params, obj=obj, input=input)
return _run_as return _run_as
@pytest.fixture @pytest.fixture
def run_json(app, user, runner): def run_json(app, user, runner):
def _run_json(command, *params): def _run_json(command, *params):
ctx = Context(app, user) obj = TootObj(test_ctx=Context(app, user))
result = runner.invoke(command, params, obj=ctx) result = runner.invoke(command, params, obj=obj)
assert result.exit_code == 0 assert result.exit_code == 0
return json.loads(result.stdout) return json.loads(result.stdout)
return _run_json return _run_json
@ -142,8 +143,8 @@ def run_json(app, user, runner):
@pytest.fixture @pytest.fixture
def run_anon(runner): def run_anon(runner):
def _run(command, *params) -> Result: def _run(command, *params) -> Result:
ctx = Context(None, None) obj = TootObj(test_ctx=Context(None, None))
return runner.invoke(command, params, obj=ctx) return runner.invoke(command, params, obj=obj)
return _run return _run

View File

@ -64,7 +64,6 @@ CONTEXT = dict(
) )
# Data object to add to Click context
class Context(t.NamedTuple): class Context(t.NamedTuple):
app: t.Optional[App] app: t.Optional[App]
user: t.Optional[User] = None user: t.Optional[User] = None
@ -73,16 +72,39 @@ class Context(t.NamedTuple):
quiet: bool = False quiet: bool = False
class TootObj(t.NamedTuple):
"""Data to add to Click context"""
color: bool = True
debug: bool = False
quiet: bool = False
# Pass a context for testing purposes
test_ctx: t.Optional[Context] = None
def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]":
"""Pass `obj` from click context as first argument.""" """Pass the toot Context as first argument."""
@wraps(f) @wraps(f)
def wrapped(*args: "P.args", **kwargs: "P.kwargs") -> R: def wrapped(*args: "P.args", **kwargs: "P.kwargs") -> R:
ctx = click.get_current_context() return f(_get_context(), *args, **kwargs)
return f(ctx.obj, *args, **kwargs)
return wrapped return wrapped
def _get_context() -> Context:
click_context = click.get_current_context()
obj: TootObj = click_context.obj
# This is used to pass a context for testing, not used in normal usage
if obj.test_ctx:
return obj.test_ctx
user, app = config.get_active_user_app()
if not user or not app:
raise click.ClickException("This command requires you to be logged in.")
return Context(app, user, obj.color, obj.debug, obj.quiet)
json_option = click.option( json_option = click.option(
"--json", "--json",
is_flag=True, is_flag=True,
@ -98,18 +120,9 @@ json_option = click.option(
@click.option("--quiet/--no-quiet", default=False, help="Don't print anything to stdout") @click.option("--quiet/--no-quiet", default=False, help="Don't print anything to stdout")
@click.version_option(__version__, message="%(prog)s v%(version)s") @click.version_option(__version__, message="%(prog)s v%(version)s")
@click.pass_context @click.pass_context
def cli( def cli(ctx: click.Context, max_width: int, color: bool, debug: bool, quiet: bool):
ctx: click.Context,
max_width: int,
color: bool,
debug: bool,
quiet: bool,
app: t.Optional[App] = None,
user: t.Optional[User] = None,
):
"""Toot is a Mastodon CLI""" """Toot is a Mastodon CLI"""
user, app = config.get_active_user_app() ctx.obj = TootObj(color, debug, quiet)
ctx.obj = Context(app, user, color, debug, quiet)
ctx.color = color ctx.color = color
ctx.max_content_width = max_width ctx.max_content_width = max_width

View File

@ -1,6 +1,6 @@
import click import click
from toot import api from toot import api, config
from toot.cli.base import Context, cli, pass_context from toot.cli.base import Context, cli, pass_context
from toot.output import print_list_accounts, print_lists, print_warning from toot.output import print_list_accounts, print_lists, print_warning
@ -11,8 +11,12 @@ def lists(ctx: click.Context):
"""Display and manage lists""" """Display and manage lists"""
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
print_warning("`toot lists` is deprecated in favour of `toot lists list`") print_warning("`toot lists` is deprecated in favour of `toot lists list`")
lists = api.get_lists(ctx.obj.app, ctx.obj.user)
user, app = config.get_active_user_app()
if not user or not app:
raise click.ClickException("This command requires you to be logged in.")
lists = api.get_lists(app, user)
if lists: if lists:
print_lists(lists) print_lists(lists)
else: else:
@ -20,10 +24,10 @@ def lists(ctx: click.Context):
@lists.command() @lists.command()
@click.pass_context @pass_context
def list(ctx: click.Context): def list(ctx: Context):
"""List all your lists""" """List all your lists"""
lists = api.get_lists(ctx.obj.app, ctx.obj.user) lists = api.get_lists(ctx.app, ctx.user)
if lists: if lists:
print_lists(lists) print_lists(lists)