Repository: miurahr/aqtinstall
Pull request #291 (2021-07-01 19:14:53)

Add error messages when user inputs an invalid semantic version
Currently, if a user uses `aqt install 5.12 mac desktop`, `semantic_version.Version` will raise a `ValueError` because `5.12` is missing a patch number. This change catches that exception and emits an error message that asks the user to fix that problem.


Patch:
diff --git a/aqt/installer.py b/aqt/installer.py
index 0636b48..0ab3eab 100644
--- a/aqt/installer.py
+++ b/aqt/installer.py
@@ -190,6 +190,7 @@ class Cli:
         target = args.target
         os_name = args.host
         qt_version = args.qt_version
+        self._validate_version_str(qt_version)
         keep = args.keep
         output_dir = args.outputdir
         if output_dir is None:
@@ -295,6 +296,7 @@ class Cli:
         target = args.target
         os_name = args.host
         qt_version = args.qt_version
+        self._validate_version_str(qt_version)
         output_dir = args.outputdir
         if output_dir is None:
             base_dir = os.getcwd()
@@ -466,6 +468,7 @@ class Cli:
         """Run list subcommand"""
         self.show_aqt_version()
         qt_version = args.qt_version
+        self._validate_version_str(qt_version)
         host = args.host
         target = args.target
         try:
@@ -693,6 +696,17 @@ class Cli:
         listener.enqueue_sentinel()
         listener.stop()
 
+    def _validate_version_str(self, version_str: str) -> None:
+        try:
+            Version(version_str)
+        except ValueError:
+            self.logger.error(
+                "Invalid version: '{}'! Please use the form '5.X.Y'.".format(
+                    version_str
+                )
+            )
+            exit(1)
+
 
 def installer(qt_archive, base_dir, command, queue, keep=False, response_timeout=None):
     """


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 082f05e..d96a259 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -1,3 +1,9 @@
+import re
+import sys
+
+import pytest
+from semantic_version import Version
+
 import aqt
 
 
@@ -51,6 +57,39 @@ def test_cli_check_version():
     assert not cli._check_qt_arg_versions("5.12")
 
 
+@pytest.mark.parametrize(
+    "invalid_version",
+    ("5.15", "five-dot-fifteen", "5", "5.5.5.5"),
+)
+def test_cli_invalid_version(capsys, invalid_version):
+    """Checks that invalid version strings are handled properly"""
+
+    # Ensure that invalid_version cannot be a Version
+    with pytest.raises(ValueError):
+        Version(invalid_version)
+
+    cli = aqt.installer.Cli()
+    cli._setup_settings()
+
+    matcher = re.compile(
+        r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+        r".*Invalid version: '"
+        + invalid_version
+        + r"'! Please use the form '5\.X\.Y'\.\n.*"
+    )
+
+    for cmd in "install", "doc", "list":
+        with pytest.raises(SystemExit) as pytest_wrapped_e:
+            cli = aqt.installer.Cli()
+            cli.run([cmd, invalid_version, "mac", "desktop"])
+        assert pytest_wrapped_e.type == SystemExit
+        assert pytest_wrapped_e.value.code == 1
+        out, err = capsys.readouterr()
+        sys.stdout.write(out)
+        sys.stderr.write(err)
+        assert matcher.match(err)
+
+
 def test_cli_check_mirror():
     cli = aqt.installer.Cli()
     cli._setup_settings()