Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions src/itzi/itzi.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
from datetime import datetime, timedelta
from importlib.metadata import version
from multiprocessing import Process
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Callable

import numpy as np

from itzi.configreader import ConfigReader
import itzi.itzi_error as itzi_error
import itzi.messenger as msgr
from itzi.const import VerbosityLevel
from itzi import parser
from itzi.parser import build_parser
from itzi.profiler import profile_context
from itzi.simulation_builder import SimulationBuilder
from itzi.grass_session import GrassSessionManager
Expand All @@ -52,16 +52,17 @@
from itzi.simulation import Simulation


def main():
# default functions for subparsers
parser.run_parser.set_defaults(func=itzi_run)
parser.version_parser.set_defaults(func=itzi_version)
# get parsed arguments
args = parser.arg_parser.parse_args()
try:
args.func(args)
except AttributeError:
parser.arg_parser.print_usage()
def main(argv=None):
"""argv: alternative CLI arguments, used for testing (default to sys.argv)"""
args = build_parser().parse_args(argv)

command_mapper: dict[str, Callable] = {
"run": itzi_run,
"version": itzi_version,
}

# args.command is the name of the subcommand
command_mapper[args.command](args)


class SimulationRunner:
Expand Down
39 changes: 21 additions & 18 deletions src/itzi/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@

DESCR = "A dynamic, fully distributed hydraulic and hydrologic model."

arg_parser = argparse.ArgumentParser(description=DESCR)
subparsers = arg_parser.add_subparsers()

# run a simulation
run_parser = subparsers.add_parser("run", help="run a simulation")
run_parser.add_argument(
"config_file",
nargs="+",
help=("an Itzï configuration file (if several given, run in batch mode)"),
)
run_parser.add_argument("-o", action="store_true", help="overwrite files if exist")
verbosity_parser = run_parser.add_mutually_exclusive_group()
verbosity_parser.add_argument("-v", action="count", help="increase verbosity")
verbosity_parser.add_argument("-q", action="count", help="decrease verbosity")


# display version
version_parser = subparsers.add_parser("version", help="display software version number")

def build_parser() -> argparse.ArgumentParser:
arg_parser = argparse.ArgumentParser(description=DESCR)
subparsers = arg_parser.add_subparsers(dest="command", required=True)

# run a simulation
run_parser = subparsers.add_parser("run", help="run a simulation")
run_parser.add_argument(
"config_file",
nargs="+",
help=("an Itzï configuration file (if several given, run in batch mode)"),
)
run_parser.add_argument("-o", action="store_true", help="overwrite files if exist")
verbosity_parser = run_parser.add_mutually_exclusive_group()
verbosity_parser.add_argument("-v", action="count", help="increase verbosity")
verbosity_parser.add_argument("-q", action="count", help="decrease verbosity")

# display version
subparsers.add_parser("version", help="display software version number")

return arg_parser
52 changes: 52 additions & 0 deletions tests/cli/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Test the CLI"""

import argparse
import os

import pytest

from itzi.const import VerbosityLevel
from itzi.itzi import main, itzi_run
from itzi.parser import build_parser


def test_run_parser_accepts_multiple_config_files():
args = build_parser().parse_args(["run", "a.ini", "b.ini", "-o", "-vv"])
assert args.config_file == ["a.ini", "b.ini"]
assert args.o is True
assert args.v == 2
assert args.q is None


def test_run_parser_rejects_v_and_q_together():
with pytest.raises(SystemExit):
build_parser().parse_args(["run", "a.ini", "-v", "-q"])


def test_prints_version(monkeypatch, capsys):
monkeypatch.setattr("itzi.itzi.version", lambda _: "22.2")
assert main(["version"]) is None
assert capsys.readouterr().out.strip() == "22.2"


def test_itzi_run_sets_env_and_dispatches(monkeypatch):
calls = []
messages = []

monkeypatch.setattr("itzi.itzi.itzi_run_one", calls.append)
monkeypatch.setattr("itzi.itzi.msgr.message", messages.append)

args = argparse.Namespace(
config_file=["a.ini", "b.ini"],
o=True,
v=1,
q=None,
)

itzi_run(args)

assert calls == ["a.ini", "b.ini"]
assert os.environ["GRASS_OVERWRITE"] == "1"
assert os.environ["ITZI_VERBOSE"] == str(VerbosityLevel.VERBOSE)
assert os.environ["GRASS_VERBOSE"] == "2"
assert any("Simulation(s) complete" in m for m in messages)
File renamed without changes.
Loading