Browse Source

path to tootown engine may be provided via env var `$TOONCHER_ENGINE_PATH`

https://git.hammerle.me/fphammerle/pyftpd-sink/commit/5daf383bc238425cd37d011959a8eeffab0112c3
Fabian Peter Hammerle 4 years ago
parent
commit
df13d336e0
3 changed files with 103 additions and 11 deletions
  1. 4 1
      CHANGELOG.md
  2. 78 0
      tests/test_cli.py
  3. 21 10
      tooncher/_cli.py

+ 4 - 1
CHANGELOG.md

@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## Unreleased
+### Added
+- path to tootown engine may be provided via env var `$TOONCHER_ENGINE_PATH`
+
 ### Changed
 - install command line interface via `setuptools.setup(entry_points=…)`
 - now private:
@@ -25,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - `tooncher.request_active_invasions`
 
 ### Fixed
-- mac: set DYLD_LIBRARY_PATH & DYLD_FRAMEWORK_PATH relatively to engine path
+- mac: `$DYLD_LIBRARY_PATH` & `$DYLD_FRAMEWORK_PATH` relative to engine path
 
 ## [0.4.1] - 2019-12-22
 ### Fixed

+ 78 - 0
tests/test_cli.py

@@ -1,4 +1,9 @@
+import pathlib
 import subprocess
+from unittest.mock import patch
+
+# pylint: disable=protected-access
+import tooncher._cli
 
 
 def test_cli_help():
@@ -10,3 +15,76 @@ def test_cli_help():
     )
     assert b"optional arguments:" in proc_info.stdout
     assert not proc_info.stderr
+
+
+@patch("tooncher._cli.run")
+@patch("os.environ", {})
+def test_engine_path_arg(run_mock):
+    with patch("sys.argv", ["", "--engine-path", "/opt/ttr/TTREngine", "username"]):
+        tooncher._cli.main()
+    run_mock.assert_called_once()
+    args, kwargs = run_mock.call_args
+    assert not args
+    assert kwargs["engine_path"] == "/opt/ttr/TTREngine"
+
+
+@patch("tooncher._cli.run")
+@patch("os.environ", {"TOONCHER_ENGINE_PATH": "/opt/ttr/TTREnvine"})
+def test_engine_path_env(run_mock):
+    with patch("sys.argv", ["", "username"]):
+        tooncher._cli.main()
+    run_mock.assert_called_once()
+    args, kwargs = run_mock.call_args
+    assert not args
+    assert kwargs["engine_path"] == "/opt/ttr/TTREnvine"
+
+
+@patch("tooncher._cli.run")
+@patch("os.environ", {"TOONCHER_ENGINE_PATH": "/opt/ttr/TTREnvine"})
+def test_engine_path_arg_env(run_mock):
+    with patch("sys.argv", ["", "--engine-path", "/opt/ttr/TTREngine", "username"]):
+        tooncher._cli.main()
+    run_mock.assert_called_once()
+    args, kwargs = run_mock.call_args
+    assert not args
+    assert kwargs["engine_path"] == "/opt/ttr/TTREngine"
+
+
+@patch("tooncher.launch")
+@patch("os.environ", {})
+def test_engine_path_config(launch_mock, tmpdir):
+    config_file = tmpdir.join("config")
+    config_file.write(
+        yaml.safe_dump(
+            {
+                "engine_path": "/opt/conf/TTR",
+                "accounts": [{"username": "someone", "password": "secret"}],
+            }
+        )
+    )
+    with patch("sys.argv", ["", "--config", config_file.strpath, "someone"]):
+        tooncher._cli.main()
+    launch_mock.assert_called_once()
+    args, kwargs = launch_mock.call_args
+    assert not args
+    assert kwargs["engine_path"] == pathlib.Path("/opt/conf/TTR")
+
+
+@patch("tooncher.launch")
+@patch("os.environ", {"TOONCHER_ENGINE_PATH": "/opt/ttr/TTREnvine"})
+def test_engine_path_env_config(launch_mock, tmpdir):
+    config_file = tmpdir.join("config")
+    config_file.write(
+        yaml.safe_dump(
+            {
+                "engine_path": "/opt/conf/TTR",
+                "accounts": [{"username": "someone", "password": "secret"}],
+            }
+        )
+    )
+    with patch("sys.argv", ["", "--config", config_file.strpath, "someone"]):
+        tooncher._cli.main()
+    launch_mock.assert_called_once()
+    args, kwargs = launch_mock.call_args
+    assert not args
+    assert kwargs["engine_path"] == pathlib.Path("/opt/ttr/TTREnvine")

+ 21 - 10
tooncher/_cli.py

@@ -35,7 +35,12 @@ def run(
         if "engine_path" in config:
             engine_path = config["engine_path"]
         else:
-            raise Exception("missing path to toontown engine")
+            engine_path = _TOONTOWN_ENGINE_DEFAULT_PATH
+    if engine_path is None:
+        raise ValueError(
+            "missing path to toontown engine\n"
+            + "pass --engine-path, set $TOONCHER_ENGINE_PATH, or add to config file"
+        )
     accounts = config["accounts"] if "accounts" in config else []
     for account in accounts:
         if account["username"] == username:
@@ -48,8 +53,18 @@ def run(
             )
 
 
+class _EnvDefaultArgparser(argparse.ArgumentParser):
+    def add_argument(self, *args, envvar=None, **kwargs):
+        if envvar:
+            envvar_value = os.environ.get(envvar, None)
+            if envvar_value:
+                kwargs["required"] = False
+                kwargs["default"] = envvar_value
+        super().add_argument(*args, **kwargs)
+
+
 def _init_argparser():
-    argparser = argparse.ArgumentParser(description=None)
+    argparser = _EnvDefaultArgparser(description=None)
     argparser.add_argument("username")
     argparser.add_argument(
         "--config",
@@ -64,14 +79,10 @@ def _init_argparser():
         "-e",
         metavar="path",
         dest="engine_path",
-        default=_TOONTOWN_ENGINE_DEFAULT_PATH,
-        help="\n".join(
-            [
-                "path to toontown engine.",
-                "this overrides the one specified in config file",
-                "(default: %(default)s)",
-            ]
-        ),
+        envvar="TOONCHER_ENGINE_PATH",
+        default=None,
+        help="path to toontown engine (overrides path in config file, "
+        + "may also be set via env var $TOONCHER_ENGINE_PATH)",
     )
     argparser.add_argument(
         "--no-ssl-cert-validation",