Skip to content

Commit

Permalink
feature(cli): add command to export rules context in current environm…
Browse files Browse the repository at this point in the history
…ent (#492)

Following up #491.

This PR adds a new CLI command to allow export rules context in the
current environment. It aims to make rules writing easier:

```sh
> qdt export-rules-context -o qdt_rules_context.json
Rules context exported in qdt_rules_context.json
```
  • Loading branch information
Guts authored Apr 23, 2024
2 parents c7f7608 + 2399230 commit 8fbd297
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 24 deletions.
10 changes: 9 additions & 1 deletion docs/reference/qdt_profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Rules

> Added in version 0.34
You can add rules to make the profile deployment conditional. In the following example, the profile will be deployed only on Linux:

```json
Expand Down Expand Up @@ -35,7 +37,7 @@ You can add rules to make the profile deployment conditional. In the following e

The rules engine is based on [Python Rule Engine](https://github.com/santalvarez/python-rule-engine/) project whom rules syntax belongs to [JSON Rules Engine](https://github.com/CacheControl/json-rules-engine).

### Conditions
### Conditions and rules context

Rules is a set of conditions that use logical operators to compare values with context (a set of facts) which is exposed as a JSON object. Here comes the context for a Linux environment:

Expand All @@ -44,6 +46,12 @@ Rules is a set of conditions that use logical operators to compare values with c
:language: json
```

To help you writing rules, QDT provides a [command to export rules context](../usage/cli.md#rules-context-export):

```sh
qdt export-rules-context -o qdt_rules_context.json
```

----

## Model definition
Expand Down
2 changes: 0 additions & 2 deletions docs/usage/cli.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Command-line interface usage

## Main command

Aliases : `qdt`, `qgis-deployment-toolbelt`, `qdeploy-toolbelt`

```{sphinx_argparse_cli}
Expand Down
17 changes: 16 additions & 1 deletion qgis_deployment_toolbelt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
__uri_homepage__,
__version__,
)
from qgis_deployment_toolbelt.commands import parser_main_deployment, parser_upgrade
from qgis_deployment_toolbelt.commands.cmd_rules_context import (
parser_rules_context_export,
)
from qgis_deployment_toolbelt.commands.deployment import parser_main_deployment
from qgis_deployment_toolbelt.commands.upgrade import parser_upgrade
from qgis_deployment_toolbelt.utils.journalizer import configure_logger

# #############################################################################
Expand Down Expand Up @@ -166,6 +170,17 @@ def main(in_args: list[str] = None):
add_common_arguments(subcmd_deployment)
parser_main_deployment(subcmd_deployment)

# Rules context
subcmd_rules_context = subparsers.add_parser(
"export-rules-context",
help="Export QDT rules context taking into account the local environment to "
"help rules writing.",
formatter_class=main_parser.formatter_class,
prog="rules-context-export",
)
add_common_arguments(subcmd_rules_context)
parser_rules_context_export(subcmd_rules_context)

# Upgrader
subcmd_upgrade = subparsers.add_parser(
"upgrade",
Expand Down
5 changes: 0 additions & 5 deletions qgis_deployment_toolbelt/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +0,0 @@
#! python3 # noqa: E265

# submodules
from .deployment import parser_main_deployment # noqa: F401
from .upgrade import parser_upgrade # noqa: F401
91 changes: 91 additions & 0 deletions qgis_deployment_toolbelt/commands/cmd_rules_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#! python3 # noqa: E265


"""
Sub-command to export local rules context.
Author: Julien M. (https://github.com/guts)
"""


# ############################################################################
# ########## IMPORTS #############
# ################################

# standard library
import argparse
import logging
from pathlib import Path

# package
from qgis_deployment_toolbelt.constants import get_qdt_working_directory
from qgis_deployment_toolbelt.profiles.rules_context import QdtRulesContext
from qgis_deployment_toolbelt.utils.bouncer import exit_cli_error, exit_cli_success

# ############################################################################
# ########## GLOBALS #############
# ################################

logger = logging.getLogger(__name__)


# ############################################################################
# ########## CLI #################
# ################################


def parser_rules_context_export(
subparser: argparse.ArgumentParser,
) -> argparse.ArgumentParser:
"""Set the argument parser for subcommand.
Args:
subparser (argparse.ArgumentParser): parser to set up
Returns:
argparse.ArgumentParser: parser ready to use
"""

subparser.add_argument(
"-o",
"--output",
help="Path to the output file where to write rules context.",
default=get_qdt_working_directory().joinpath("export/qdt_rules_context.json"),
type=Path,
dest="output_path",
)

subparser.set_defaults(func=run)

return subparser


# ############################################################################
# ########## MAIN ################
# ################################


def run(args: argparse.Namespace):
"""Run the sub command logic.
Open result of a previous command.
Args:
args (argparse.Namespace): arguments passed to the subcommand
"""
logger.debug(f"Running {args.command} with {args}")

try:
context_json_path = Path(args.output_path)
context_json_path.parent.mkdir(parents=True, exist_ok=True)
rules_context = QdtRulesContext()

# write into the file passing extra parameters to json.dumps
with context_json_path.open("w", encoding="UTF8") as wf:
wf.write(rules_context.to_json(indent=4, sort_keys=True))

# exit nicely
print(f"Rules context exported in {args.output_path}")
exit_cli_success(f"Rules context exported in {args.output_path}")
except Exception as err:
exit_cli_error(err)
1 change: 0 additions & 1 deletion qgis_deployment_toolbelt/profiles/rules_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@


class QdtRulesContext:
pass

@property
def _context_date(self) -> dict:
Expand Down
17 changes: 5 additions & 12 deletions tests/test_cli_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def test_main_run(capsys, option):
with pytest.raises(SystemExit):
cli.main(option)

out, err = capsys.readouterr()
_, err = capsys.readouterr()
assert err == ""

# checks
Expand All @@ -128,7 +128,7 @@ def test_main_run_as_admin(capsys):
]
)

out, err = capsys.readouterr()
_, err = capsys.readouterr()
assert err == ""


Expand All @@ -142,7 +142,7 @@ def test_main_run_unexising_jobs(capsys):
]
)

out, err = capsys.readouterr()
_, err = capsys.readouterr()
assert err == ""


Expand All @@ -151,7 +151,7 @@ def test_main_run_failed(capsys):
with pytest.raises(FileExistsError):
cli.main(["deploy", f"--scenario={str(sample_scenario_false.resolve())}"])

out, err = capsys.readouterr()
_, err = capsys.readouterr()
assert err == ""


Expand All @@ -169,12 +169,5 @@ def test_main_run_removing_splash(capsys):
]
)

out, err = capsys.readouterr()
_, err = capsys.readouterr()
assert err == ""


# #############################################################################
# ######## Standalone ##############
# ##################################
if __name__ == "__main__":
pass
43 changes: 43 additions & 0 deletions tests/test_cli_rules_context_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#! python3 # noqa: E265

"""
Test CLI's rules context export command.
Author: Julien Moura (Oslandia)
"""

# #############################################################################
# ########## Libraries #############
# ##################################


# 3rd party
import pytest

# project
from qgis_deployment_toolbelt import cli

# #############################################################################
# ######## Classes #################
# ##################################


@pytest.mark.parametrize("option", ("-h", "--help"))
def test_cli_export_rules_context_help(capsys, option):
"""Test CLI help."""
with pytest.raises(SystemExit):
cli.main(["export-rules-context", option])

_, err = capsys.readouterr()

assert err == ""


def test_cli_export_rules_context(capsys):
"""Test CLI."""
with pytest.raises(SystemExit):
cli.main(["export-rules-context"])

_, err = capsys.readouterr()

assert err == ""
4 changes: 2 additions & 2 deletions tests/test_cli_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_cli_upgrade_check_only(capsys):
with pytest.raises(SystemExit):
cli.main(["upgrade", "-c"])

out, err = capsys.readouterr()
_, err = capsys.readouterr()

assert err == ""

Expand All @@ -48,7 +48,7 @@ def test_cli_upgrade_download(capsys):
with pytest.raises(SystemExit):
cli.main(["upgrade", "-n", "-w", "tests/"])

out, err = capsys.readouterr()
_, err = capsys.readouterr()

assert err == ""

Expand Down

0 comments on commit 8fbd297

Please sign in to comment.