Skip to content

Commit

Permalink
Merge pull request #16 from dbatten5/get-all-options
Browse files Browse the repository at this point in the history
Support retrieving all config options
  • Loading branch information
dbatten5 authored Oct 27, 2021
2 parents 93654ac + 48dc427 commit 8355a49
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 20 deletions.
4 changes: 4 additions & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
::: maison.config
selection:
filters:
- "!^__"
- "^__init__$"
1 change: 0 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ plugins:
fallback_to_build_date: true
- minify:
minify_html: true
- section-index

markdown_extensions:
- abbr
Expand Down
54 changes: 49 additions & 5 deletions src/maison/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,72 @@ class ProjectConfig:
"""Defines the `ProjectConfig` and provides accessors to get config values."""

def __init__(self, project_name: str, starting_path: Optional[Path] = None) -> None:
"""Initialize the config."""
"""Initialize the config.
Args:
project_name: the name of the project, to be used to find the right section
in the config file
starting_path: an optional starting path to start the search for config
file
"""
config_path, config_dict = _find_config(project_name, starting_path)
self._config_dict: Dict[str, Any] = config_dict or {}
self.config_path: Optional[Path] = config_path

def get_option(self, option: str, default: Optional[Any] = None) -> Optional[Any]:
def __repr__(self) -> str:
"""Return the __repr__.
Returns:
the representation
"""
return f"{self.__class__.__name__}" f" (config_path={self.config_path})"

def __str__(self) -> str:
"""Return the __str__.
Returns:
the representation
"""
return self.__repr__()

def to_dict(self) -> Dict[str, Any]:
"""Return a dict of all the config options.
Returns:
a dict of the config options
"""
return self._config_dict

def get_option(
self, option_name: str, default_value: Optional[Any] = None
) -> Optional[Any]:
"""Return the value of a config option.
Args:
option (str): the config option for which to return the value
default: an option default value if the option isn't set
option_name: the config option for which to return the value
default_value: an option default value if the option isn't set
Returns:
The value of the given config option or `None` if it doesn't exist
"""
return self._config_dict.get(option, default)
return self._config_dict.get(option_name, default_value)


def _find_config(
project_name: str,
starting_path: Optional[Path] = None,
) -> Tuple[Optional[Path], Dict[str, Any]]:
"""Find the desired config file.
Args:
project_name: the name of the project to be used to find the right section in
the config file
starting_path: an optional starting path to start the search
Returns:
a tuple of the path to the config file if found, and a dictionary of the config
values
"""
pyproject_path: Optional[Path] = get_pyproject_path(starting_path)
if pyproject_path:
return pyproject_path, toml.load(pyproject_path).get("tool", {}).get(
Expand Down
66 changes: 52 additions & 14 deletions tests/unit/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,49 @@


class TestProjectConfig:
"""Tests for the `ProjectConfig`."""
"""Tests for the `ProjectConfig` class."""

def test_repr(self, create_tmp_file: Callable[..., Path]) -> None:
"""
Given an instance of `ProjectConfig`,
When the string representation is retrieved,
Then a useful representation is returned
"""
pyproject_path = create_tmp_file(filename="pyproject.toml")

config = ProjectConfig(project_name="foo", starting_path=pyproject_path)

assert str(config) == f"ProjectConfig (config_path={pyproject_path})"

def test_repr_no_config_path(self, create_tmp_file: Callable[..., Path]) -> None:
"""
Given an instance of `ProjectConfig` without a `config_path`,
When the string representation is retrieved,
Then a useful representation is returned
"""
pyproject_path = create_tmp_file()

config = ProjectConfig(project_name="foo", starting_path=pyproject_path)

assert str(config) == "ProjectConfig (config_path=None)"

def test_to_dict(self, create_tmp_file: Callable[..., Path]) -> None:
"""
Given an instance of `ProjectConfig`,
When the `to_dict` method is invoked,
Then a dictionary of all config options is returned
"""
config_dict = {"tool": {"foo": {"bar": "baz"}}}
config_toml = toml.dumps(config_dict)
pyproject_path = create_tmp_file(content=config_toml, filename="pyproject.toml")

config = ProjectConfig(project_name="foo", starting_path=pyproject_path)

assert config.to_dict() == config_dict["tool"]["foo"]


class TestGetOption:
"""Tests for the `get_option` method."""

def test_valid_pyproject(self, create_tmp_file: Callable[..., Path]) -> None:
"""
Expand All @@ -18,11 +60,9 @@ def test_valid_pyproject(self, create_tmp_file: Callable[..., Path]) -> None:
"""
config_toml = toml.dumps({"tool": {"foo": {"bar": "baz"}}})
pyproject_path = create_tmp_file(content=config_toml, filename="pyproject.toml")
autoimport_config = ProjectConfig(
project_name="foo", starting_path=pyproject_path
)
config = ProjectConfig(project_name="foo", starting_path=pyproject_path)

result = autoimport_config.get_option("bar")
result = config.get_option("bar")

assert result == "baz"

Expand All @@ -32,9 +72,9 @@ def test_no_pyproject(self) -> None:
When the `ProjectConfig` class is instantiated,
Then the situation is handled gracefully
"""
autoimport_config = ProjectConfig(project_name="foo", starting_path=Path("/"))
config = ProjectConfig(project_name="foo", starting_path=Path("/"))

result = autoimport_config.get_option("bar")
result = config.get_option("bar")

assert result is None

Expand All @@ -44,13 +84,13 @@ def test_default(self) -> None:
When a missing option is retrieved with a given default,
Then the default is returned
"""
autoimport_config = ProjectConfig(project_name="foo", starting_path=Path("/"))
config = ProjectConfig(project_name="foo", starting_path=Path("/"))

result = autoimport_config.get_option("bar", "baz")
result = config.get_option("bar", "baz")

assert result == "baz"

def test_valid_pyproject_with_no_autoimport_section(
def test_valid_pyproject_with_no_project_section(
self, create_tmp_file: Callable[..., Path]
) -> None:
"""
Expand All @@ -60,10 +100,8 @@ def test_valid_pyproject_with_no_autoimport_section(
"""
config_toml = toml.dumps({"foo": "bar"})
pyproject_path = create_tmp_file(content=config_toml, filename="pyproject.toml")
autoimport_config = ProjectConfig(
project_name="baz", starting_path=pyproject_path
)
config = ProjectConfig(project_name="baz", starting_path=pyproject_path)

result = autoimport_config.get_option("foo")
result = config.get_option("foo")

assert result is None

0 comments on commit 8355a49

Please sign in to comment.