Commit 0c719260 authored by Eric Duminil's avatar Eric Duminil
Browse files

Allow params for regionchooser

parent dd949c28
...@@ -17,7 +17,7 @@ dependencies = [ ...@@ -17,7 +17,7 @@ dependencies = [
[project.scripts] [project.scripts]
simstadt = "simstadt:main" simstadt = "simstadt:main"
regionchooser = "simstadt:run_regionchooser" regionchooser = "simstadt:regionchooser_app"
[dependency-groups] [dependency-groups]
dev = ["pytest>=8.0", "rich", "pytest-cov"] dev = ["pytest>=8.0", "rich", "pytest-cov"]
......
...@@ -34,9 +34,18 @@ __all__ = [ ...@@ -34,9 +34,18 @@ __all__ = [
"photovoltaic_simulation", "photovoltaic_simulation",
"run_regionchooser", "run_regionchooser",
"run_workflow_with_citygml", "run_workflow_with_citygml",
"main",
"regionchooser_app",
] ]
def main() -> None: def main() -> None:
from .cli import app from .cli import simstadt_app
app()
simstadt_app()
def regionchooser_app() -> None:
from .cli import regionchooser_app as _regionchooser_app
_regionchooser_app()
...@@ -6,12 +6,19 @@ import re ...@@ -6,12 +6,19 @@ import re
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
from .install import cmd_install from .install import cmd_install
from .runner import run_regionchooser
from .utils import chdir from .utils import chdir
def cmd_info(args: argparse.Namespace) -> None: def cmd_info(args: argparse.Namespace) -> None:
from .runner import get_simstadt_folder, get_simstadt_output, _simstadt_script, SIMSTADT_VERSION_FORMAT from .runner import (
SIMSTADT_VERSION_FORMAT,
_simstadt_script,
get_simstadt_folder,
get_simstadt_output,
)
try: try:
folder = get_simstadt_folder() folder = get_simstadt_folder()
...@@ -35,7 +42,9 @@ def cmd_info(args: argparse.Namespace) -> None: ...@@ -35,7 +42,9 @@ def cmd_info(args: argparse.Namespace) -> None:
if m: if m:
version, branch, commit, date = m.groups() version, branch, commit, date = m.groups()
yyyy, mm, dd = date[:4], date[4:6], date[6:8] yyyy, mm, dd = date[:4], date[4:6], date[6:8]
print(f"SimStadt version: {version} (branch: {branch}, rev: {commit}, date: {yyyy}-{mm}-{dd})") print(
f"SimStadt version: {version} (branch: {branch}, rev: {commit}, date: {yyyy}-{mm}-{dd})"
)
else: else:
print("SimStadt version: unknown (could not parse version string)") print("SimStadt version: unknown (could not parse version string)")
...@@ -83,19 +92,49 @@ def build_parser() -> argparse.ArgumentParser: ...@@ -83,19 +92,49 @@ def build_parser() -> argparse.ArgumentParser:
description="simstadt - Python library for SimStadt workflows.", description="simstadt - Python library for SimStadt workflows.",
) )
parser.add_argument("--gui", action="store_true", help="Launch the SimStadt GUI.") parser.add_argument("--gui", action="store_true", help="Launch the SimStadt GUI.")
parser.add_argument("--install", action="store_true", help="Download and install the latest SimStadt release to ~/Desktop.") parser.add_argument(
parser.add_argument("template", nargs="?", help="Template name (from SIMSTADT_TEMPLATE_PATH) or path to a .flow directory.") "--install",
parser.add_argument("citygml", nargs="?", type=Path, help="Path to the CityGML input file.") action="store_true",
parser.add_argument("-d", "--description", help="Human-readable label for the result.") help="Download and install the latest SimStadt release to ~/Desktop.",
parser.add_argument("--destination", help="Workflow folder name (default: timestamped random id).") )
parser.add_argument("-p", "--project-path", dest="project_path", type=Path, help="Directory where the workflow folder is created.") parser.add_argument(
parser.add_argument("-f", "--files", action="store_true", help="Show output files after the run.") "template",
parser.add_argument("-s", "--save", type=Path, metavar="PATH", help="Save result DataFrame to a file (.csv or .json).") nargs="?",
parser.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging.") help="Template name (from SIMSTADT_TEMPLATE_PATH) or path to a .flow directory.",
)
parser.add_argument(
"citygml", nargs="?", type=Path, help="Path to the CityGML input file."
)
parser.add_argument(
"-d", "--description", help="Human-readable label for the result."
)
parser.add_argument(
"--destination", help="Workflow folder name (default: timestamped random id)."
)
parser.add_argument(
"-p",
"--project-path",
dest="project_path",
type=Path,
help="Directory where the workflow folder is created.",
)
parser.add_argument(
"-f", "--files", action="store_true", help="Show output files after the run."
)
parser.add_argument(
"-s",
"--save",
type=Path,
metavar="PATH",
help="Save result DataFrame to a file (.csv or .json).",
)
parser.add_argument(
"-v", "--verbose", action="store_true", help="Enable debug logging."
)
return parser return parser
def app() -> None: def simstadt_app() -> None:
parser = build_parser() parser = build_parser()
args = parser.parse_args() args = parser.parse_args()
...@@ -106,3 +145,14 @@ def app() -> None: ...@@ -106,3 +145,14 @@ def app() -> None:
cmd_run(args) cmd_run(args)
else: else:
cmd_info(args) cmd_info(args)
def regionchooser_app() -> None:
try:
print(run_regionchooser(*sys.argv[1:]))
except ValueError as e:
print(f"Error: {e}", file=sys.stderr)
raise SystemExit(1)
except subprocess.CalledProcessError as e:
print(e.stderr, file=sys.stderr)
raise SystemExit(e.returncode)
"""Tests for the simstadt CLI.""" """Tests for the simstadt CLI."""
import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
import pytest import pytest
from simstadt.cli import app, build_parser from simstadt.cli import build_parser, regionchooser_app, simstadt_app
from .test_runner import CITYGML, HEAT_TEMPLATE, PV_TEMPLATE from .test_runner import CITYGML, HEAT_TEMPLATE, PV_TEMPLATE
...@@ -16,7 +17,7 @@ def run_cli(monkeypatch): ...@@ -16,7 +17,7 @@ def run_cli(monkeypatch):
def _run(capsys, *args): def _run(capsys, *args):
monkeypatch.setattr(sys, "argv", ["simstadt", *[str(a) for a in args]]) monkeypatch.setattr(sys, "argv", ["simstadt", *[str(a) for a in args]])
app() simstadt_app()
return capsys.readouterr() return capsys.readouterr()
return _run return _run
...@@ -98,7 +99,7 @@ def test_run_error_on_stderr(monkeypatch, capsys): ...@@ -98,7 +99,7 @@ def test_run_error_on_stderr(monkeypatch, capsys):
monkeypatch.setattr("simstadt.runner.run_simstadt", _broken_simstadt) monkeypatch.setattr("simstadt.runner.run_simstadt", _broken_simstadt)
monkeypatch.setattr(sys, "argv", ["simstadt", str(HEAT_TEMPLATE), str(CITYGML)]) monkeypatch.setattr(sys, "argv", ["simstadt", str(HEAT_TEMPLATE), str(CITYGML)])
with pytest.raises(SystemExit): with pytest.raises(SystemExit):
app() simstadt_app()
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert "BOOM" in err assert "BOOM" in err
assert out == "" assert out == ""
...@@ -138,3 +139,64 @@ def test_run_save_goes_to_stderr(mock_simstadt, run_cli, capsys, tmp_path): ...@@ -138,3 +139,64 @@ def test_run_save_goes_to_stderr(mock_simstadt, run_cli, capsys, tmp_path):
out, err = run_cli(capsys, HEAT_TEMPLATE, CITYGML, "-p", proj, "-s", out_file) out, err = run_cli(capsys, HEAT_TEMPLATE, CITYGML, "-p", proj, "-s", out_file)
assert "Saved to" in err assert "Saved to" in err
assert "Saved to" not in out assert "Saved to" not in out
# ---------------------------------------------------------------------------
# regionchooser_app
# ---------------------------------------------------------------------------
def test_regionchooser_get_hull(monkeypatch, capsys):
def _mock(*params):
assert params == ("--get-hull", str(CITYGML))
return "HULL_WKT_OUTPUT\n"
monkeypatch.setattr("simstadt.cli.run_regionchooser", _mock)
monkeypatch.setattr(sys, "argv", ["regionchooser", "--get-hull", str(CITYGML)])
regionchooser_app()
out, err = capsys.readouterr()
assert "HULL_WKT_OUTPUT" in out
assert err == ""
def test_regionchooser_simstadt_not_found(monkeypatch, capsys):
def _mock(*_params):
raise ValueError("SimStadt not found")
monkeypatch.setattr("simstadt.cli.run_regionchooser", _mock)
monkeypatch.setattr(sys, "argv", ["regionchooser", "--get-hull", str(CITYGML)])
with pytest.raises(SystemExit) as exc_info:
regionchooser_app()
assert exc_info.value.code == 1
out, err = capsys.readouterr()
assert "Error: SimStadt not found" in err
assert out == ""
def test_regionchooser_script_failure(monkeypatch, capsys):
def _mock(*_params):
raise subprocess.CalledProcessError(
returncode=2, cmd=["RegionChooser.sh"], stderr="BOOM!"
)
monkeypatch.setattr("simstadt.cli.run_regionchooser", _mock)
monkeypatch.setattr(sys, "argv", ["regionchooser", "--get-hull", str(CITYGML)])
with pytest.raises(SystemExit) as exc_info:
regionchooser_app()
assert exc_info.value.code == 2
out, err = capsys.readouterr()
assert "BOOM!" in err
assert out == ""
@pytest.mark.integration
def test_regionchooser_get_hull_real(simstadt_folder, monkeypatch, capsys):
monkeypatch.setattr(
sys,
"argv",
["regionchooser", "--get-hull", f"--input={CITYGML.as_posix()}"],
)
regionchooser_app()
out, err = capsys.readouterr()
assert "POLYGON" in out.upper()
assert err == ""
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment