diff --git a/CHANGELOG.md b/CHANGELOG.md index fb9b3dd..3631d4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Note: Breaking changes between versions are indicated by "💥". ## Latest +- [Improvement] Better yaml value parsing from command line - [Feature] Add `dev exec` command - [Bugfix] Fix incorrect notes settings definition - [Improvement] Make it possible to start/stop/reboot a selection of services diff --git a/tests/test_serialize.py b/tests/test_serialize.py new file mode 100644 index 0000000..c960d39 --- /dev/null +++ b/tests/test_serialize.py @@ -0,0 +1,24 @@ +import unittest + +from tutor import serialize + + +class SerializeTests(unittest.TestCase): + def test_parse_str(self): + self.assertEqual("abcd", serialize.parse("abcd")) + + def test_parse_int(self): + self.assertEqual(1, serialize.parse("1")) + + def test_parse_bool(self): + self.assertEqual(True, serialize.parse("true")) + self.assertEqual(False, serialize.parse("false")) + + def test_parse_null(self): + self.assertIsNone(serialize.parse("null")) + + def test_parse_invalid_format(self): + self.assertEqual('["abcd"', serialize.parse('["abcd"')) + + def test_parse_list(self): + self.assertEqual(["abcd"], serialize.parse('["abcd"]')) diff --git a/tests/test_utils.py b/tests/test_utils.py index 2e91a3c..09fe807 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,10 +20,3 @@ class UtilsTests(unittest.TestCase): def test_reverse_host(self): self.assertEqual("com.google.www", utils.reverse_host("www.google.com")) - - -class SerializeTests(unittest.TestCase): - def test_parse_value(self): - self.assertEqual(True, serialize.parse_value("true")) - self.assertEqual(False, serialize.parse_value("false")) - self.assertEqual(None, serialize.parse_value("null")) diff --git a/tutor/commands/dev.py b/tutor/commands/dev.py index 19511cd..ba738e3 100644 --- a/tutor/commands/dev.py +++ b/tutor/commands/dev.py @@ -33,6 +33,7 @@ def run(root, edx_platform_path, edx_platform_settings, service, command, args): root, edx_platform_path, edx_platform_settings, port, *run_command ) + @click.command( help="Exec a command in a running container", context_settings={"ignore_unknown_options": True}, @@ -47,6 +48,7 @@ def execute(root, service, command, args): exec_command += args docker_compose(root, *exec_command) + @click.command(help="Run a development server") @opts.root @opts.edx_platform_path diff --git a/tutor/config.py b/tutor/config.py index 85e683a..7c2a224 100644 --- a/tutor/config.py +++ b/tutor/config.py @@ -84,7 +84,7 @@ def load_env(config, defaults): for k in defaults.keys(): env_var = "TUTOR_" + k if env_var in os.environ: - config[k] = serialize.parse_value(os.environ[env_var]) + config[k] = serialize.parse(os.environ[env_var]) def load_required(config, defaults): diff --git a/tutor/opts.py b/tutor/opts.py index 136d4fc..bf0d494 100644 --- a/tutor/opts.py +++ b/tutor/opts.py @@ -39,4 +39,4 @@ class YamlParamType(click.ParamType): k, v = value.split("=") except ValueError: self.fail("'{}' is not of the form 'key=value'.".format(value), param, ctx) - return k, serialize.parse_value(v) + return k, serialize.parse(v) diff --git a/tutor/serialize.py b/tutor/serialize.py index 34351d1..1c11885 100644 --- a/tutor/serialize.py +++ b/tutor/serialize.py @@ -1,4 +1,5 @@ import yaml +from yaml.parser import ParserError def load(stream): @@ -9,15 +10,12 @@ def dump(content, fileobj): yaml.dump(content, fileobj, default_flow_style=False) -def parse_value(v): +def parse(v): """ - Parse a yaml-formatted string. This is fairly basic and should only be used - for parsing of elementary values. + Parse a yaml-formatted string. """ - if v.isdigit(): - v = int(v) - elif v == "null": - v = None - elif v in ["true", "false"]: - v = v == "true" + try: + return load(v) + except ParserError: + pass return v