Skip to content

Commit

Permalink
refactor: move 'check' and 'export-config' under a 'config' command
Browse files Browse the repository at this point in the history
  • Loading branch information
azmeuk committed Jan 31, 2025
1 parent 6f0cd76 commit 7ed3b15
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 61 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ Added
^^^^^
- Add screenshots in the documentation. :issue:`210`
- Implement a ``canaille run`` command that runs a production server with Hypercorn. :pr:`219`
- Implement a ``canaille export-config`` command that create a commented config file. :pr:`223`
- Implement a ``canaille config dump`` command that create a commented config file. :pr:`223`
- Load configuration from local ``canaille.toml`` files. :pr:`225`

Changed
^^^^^^^
- Avoid displaying password strength progress bar in login form.
- Mysql extra depends on ``pymysql`` instead of ``mysql-connector``.
- :attr:`~canaille.app.configuration.RootSettings.SECRET_KEY` is not mandatory anymore, but displays warnings when unset. :pr:`221`
- Move the ``canaille check`` command under ``canaille config``.

Fixed
^^^^^
Expand Down
91 changes: 48 additions & 43 deletions canaille/app/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,6 @@ def _func(*args, **kwargs):
return _func


@click.command()
@with_appcontext
@with_backendcontext
def check():
"""Test the configuration file.
Attempt to reach the database and the SMTP server with the provided
credentials.
"""
from canaille.app.configuration import ConfigurationException
from canaille.app.configuration import validate

try:
validate(current_app.config, validate_remote=True)
except ConfigurationException as exc:
print(exc)
sys.exit(1)


@click.command()
@with_appcontext
def install():
Expand All @@ -70,12 +51,42 @@ def install():
sys.exit(1)


@click.command()
if HAS_HYPERCORN: # pragma: no cover

@click.command()
@with_appcontext
@click.option(
"--config",
default=None,
help="Path to a TOML hypercorn configuration file.",
type=click.Path(),
)
def run(config: str | None):
"""Run Canaille in a hypercorn application server.
Have a look at the :doc:`Hypercorn configuration documentation <hypercorn:how_to_guides/configuring>` to find how to configure it.
"""
from hypercorn.config import Config
from hypercorn.run import run as hypercorn_run

config_obj = Config.from_toml(config) if config else Config()
config_obj.application_path = "canaille.app.server:app"
exitcode = hypercorn_run(config_obj)
sys.exit(exitcode)


@click.group()
def config():
"""Handle Canaille configuration file."""
pass


@config.command()
@with_appcontext
@click.option(
"--path", default=None, type=click.Path(), help="The path to the config file"
)
def export_config(path: Path | None):
def dump(path: Path | None):
"""Export the configuration in TOML format.
The configuration is exported to the file path passed by ``--path`` if set,
Expand All @@ -94,33 +105,27 @@ def export_config(path: Path | None):
click.echo(f"Wrote configuration file at {config_file}")


if HAS_HYPERCORN: # pragma: no cover

@click.command()
@with_appcontext
@click.option(
"--config",
default=None,
help="Path to a TOML hypercorn configuration file.",
type=click.Path(),
)
def run(config: str | None):
"""Run Canaille in a hypercorn application server.
@config.command()
@with_appcontext
@with_backendcontext
def check():
"""Test the configuration file.
Have a look at the :doc:`Hypercorn configuration documentation <hypercorn:how_to_guides/configuring>` to find how to configure it.
"""
from hypercorn.config import Config
from hypercorn.run import run as hypercorn_run
Attempt to reach the database and the SMTP server with the provided
credentials.
"""
from canaille.app.configuration import ConfigurationException
from canaille.app.configuration import validate

config_obj = Config.from_toml(config) if config else Config()
config_obj.application_path = "canaille.app.server:app"
exitcode = hypercorn_run(config_obj)
sys.exit(exitcode)
try:
validate(current_app.config, validate_remote=True)
except ConfigurationException as exc:
print(exc)
sys.exit(1)


def register(cli):
cli.add_command(check)
cli.add_command(install)
cli.add_command(export_config)
if HAS_HYPERCORN: # pragma: no branch
cli.add_command(run)
cli.add_command(config)
2 changes: 1 addition & 1 deletion doc/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ Command Line Interface

Canaille comes with a :abbr:`CLI (Command Line Interface)` to help administrators in hosting and management.

There are tools to :ref:`check your configuration <cli_check>` or to :ref:`install missing parts <cli_install>`.
There are tools to :ref:`generate and check a configuration file <cli_config>` or to :ref:`install missing parts <cli_install>`.
You can use the CLI to :ref:`create <cli_create>`, :ref:`read <cli_get>`, :ref:`update <cli_set>` and :ref:`delete <cli_delete>` models such as :class:`users <canaille.core.models.User>`, :class:`groups <canaille.core.models.Group>` or :class:`OIDC clients <canaille.oidc.basemodels.Client>`.

There are also tools to :ref:`fill your database <cli_populate>` with random objects, for tests purpose for instance.
Expand Down
12 changes: 3 additions & 9 deletions doc/references/commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ For the sake of readability, it is omitted in the following examples.
env CONFIG=path/to/config.toml canaille ...
.. _cli_check:
.. _cli_config:

.. click:: canaille.app.commands:check
:prog: canaille check
.. click:: canaille.app.commands:config
:prog: canaille config
:nested: full

.. _cli_run:
Expand All @@ -29,12 +29,6 @@ For the sake of readability, it is omitted in the following examples.
:prog: canaille clean
:nested: full

.. _cli_export_config:

.. click:: canaille.app.commands:export_config
:prog: canaille export-config
:nested: full

.. _cli_dump:

.. click:: canaille.backends.commands:dump
Expand Down
2 changes: 1 addition & 1 deletion doc/references/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Parameters
Example file
============

Here is a configuration file example that can be generated with the :ref:`canaille export-config <cli_export_config>` command:
Here is a configuration file example that can be generated with the :ref:`canaille config dump <cli_config>` command:

.. literalinclude :: ../config.sample.toml
:language: toml
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorial/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Configure

The :doc:`configuration documentation<../references/configuration>` describe several ways to configure Canaille,
however the most common is to use a TOML configuration file and pass its path with the :envvar:`CONFIG` environment variable.
A configuration file with default values can be initialized with the :ref:`export-config <cli_export_config>` command.
A configuration file with default values can be initialized with the :ref:`config dump <cli_config>` command.

.. code-block:: bash
:caption: Initialize a configuration file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

def test_check_command(testclient, mock_smpp):
runner = testclient.app.test_cli_runner()
res = runner.invoke(cli, ["check"])
res = runner.invoke(cli, ["config", "check"])
assert res.exit_code == 0, res.stdout


def test_check_command_fail(testclient):
testclient.app.config["CANAILLE"]["SMTP"]["HOST"] = "invalid-domain.com"
runner = testclient.app.test_cli_runner()
res = runner.invoke(cli, ["check"])
res = runner.invoke(cli, ["config", "check"])
assert res.exit_code == 1, res.stdout


def test_check_command_no_smtp(testclient, mock_smpp):
testclient.app.config["CANAILLE"]["SMTP"] = None
runner = testclient.app.test_cli_runner()
res = runner.invoke(cli, ["check"])
res = runner.invoke(cli, ["config", "check"])
assert res.exit_code == 0, res.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_export_current_config(testclient, backend, tmp_path):

runner = testclient.app.test_cli_runner()
res = runner.invoke(
cli, ["export-config", "--path", str(toml_export)], catch_exceptions=False
cli, ["config", "dump", "--path", str(toml_export)], catch_exceptions=False
)
assert res.exit_code == 0, res.stdout

Expand Down Expand Up @@ -49,7 +49,7 @@ def test_export_env_config(testclient, tmp_path, backend):

os.environ["CONFIG"] = str(toml_export)
runner = testclient.app.test_cli_runner()
res = runner.invoke(cli, ["export-config"], catch_exceptions=False)
res = runner.invoke(cli, ["config", "dump"], catch_exceptions=False)
assert res.exit_code == 0, res.stdout

with open(toml_export) as fd:
Expand Down

0 comments on commit 7ed3b15

Please sign in to comment.