Skip to content

Commit

Permalink
fix: format output of config printvalue as yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
regisb committed May 22, 2023
1 parent f7978d7 commit dcd155e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 8 deletions.
1 change: 1 addition & 0 deletions changelog.d/20230412_100608_regis_palm.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
- [Improvement] The `IMAGES_BUILD` filter now supports relative paths as strings, and not just as tuple of strings.
- [Improvement] Auto-complete the image names in the `images build/pull/push/printtag` commands.
- [Deprecation] For local installations, Docker v20.10.15 and Compose v2.0.0 are now the minimum required versions.
- [Bugfix] Make `tutor config printvalue ...` print actual yaml-formatted values, such as "true" and "null"
14 changes: 14 additions & 0 deletions tests/test_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@ def test_parse_key_value(self) -> None:
"x=key1:\n subkey: value\nkey2:\n subkey: value"
),
)

def test_str_format(self) -> None:
self.assertEqual("true", serialize.str_format(True))
self.assertEqual("false", serialize.str_format(False))
self.assertEqual("null", serialize.str_format(None))
self.assertEqual("éü©", serialize.str_format("éü©"))
self.assertEqual("""[1, 'abcd']""", serialize.str_format([1, "abcd"]))

def test_load_str_format(self) -> None:
self.assertEqual(True, serialize.load(serialize.str_format(True)))
self.assertEqual(False, serialize.load(serialize.str_format(False)))
self.assertEqual(None, serialize.load(serialize.str_format(None)))
self.assertEqual("éü©", serialize.load(serialize.str_format("éü©")))
self.assertEqual([1, "abcd"], serialize.load(serialize.str_format([1, "abcd"])))
4 changes: 2 additions & 2 deletions tutor/commands/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ def printroot(context: Context) -> None:
def printvalue(context: Context, key: str) -> None:
config = tutor_config.load(context.root)
try:
# Note that this will incorrectly print None values
fmt.echo(str(config[key]))
value = config[key]
except KeyError as e:
raise exceptions.TutorError(f"Missing configuration value: {key}") from e
fmt.echo(serialize.str_format(value))


@click.group(name="patches", help="Commands related to patches in configurations")
Expand Down
7 changes: 4 additions & 3 deletions tutor/commands/mounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
import click
import yaml

from tutor import bindmount, exceptions, fmt, hooks
from tutor.commands.context import Context
from tutor.commands.params import ConfigLoaderParam
from tutor import bindmount
from tutor import config as tutor_config
from tutor import exceptions, fmt, hooks
from tutor.commands.config import save as config_save
from tutor.commands.context import Context
from tutor.commands.params import ConfigLoaderParam


class MountParamType(ConfigLoaderParam):
Expand Down
23 changes: 20 additions & 3 deletions tutor/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,36 @@ def load_all(stream: str) -> t.Iterator[t.Any]:


def dump_all(documents: t.Sequence[t.Any], fileobj: TextIOWrapper) -> None:
yaml.safe_dump_all(documents, stream=fileobj, default_flow_style=False)
yaml.safe_dump_all(
documents, stream=fileobj, default_flow_style=False, allow_unicode=True
)


def dump(content: t.Any, fileobj: TextIOWrapper) -> None:
yaml.dump(content, stream=fileobj, default_flow_style=False)
yaml.dump(content, stream=fileobj, default_flow_style=False, allow_unicode=True)


def dumps(content: t.Any) -> str:
result = yaml.dump(content, default_flow_style=False)
result = yaml.dump(content, default_flow_style=False, allow_unicode=True)
assert isinstance(result, str)
return result


def str_format(content: t.Any) -> str:
"""
Convert a value to str.
This is almost like json, but more convenient for printing to the standard output.
"""
if content is True:
return "true"
if content is False:
return "false"
if content is None:
return "null"
return str(content)


def parse(v: t.Union[str, t.IO[str]]) -> t.Any:
"""
Parse a yaml-formatted string.
Expand Down

0 comments on commit dcd155e

Please sign in to comment.