Skip to content

Commit 67dec6d

Browse files
author
Daniel Sanz
committed
chore(elementsinteractive#153): Use FileHandler in ConfigHandler
1 parent 8a411a1 commit 67dec6d

File tree

5 files changed

+43
-48
lines changed

5 files changed

+43
-48
lines changed

src/twyn/config/config_handler.py

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import logging
22
from dataclasses import asdict, dataclass
33
from enum import Enum
4-
from os import getcwd
5-
from pathlib import Path
64
from typing import Optional
75

86
from tomlkit import TOMLDocument, dumps, parse, table
@@ -18,6 +16,8 @@
1816
AllowlistPackageDoesNotExistError,
1917
TOMLError,
2018
)
19+
from twyn.file_handler.exceptions import PathNotFoundError
20+
from twyn.file_handler.file_handler import FileHandler
2121

2222
logger = logging.getLogger("twyn")
2323

@@ -47,8 +47,9 @@ class ReadTwynConfiguration:
4747
class ConfigHandler:
4848
"""Manage reading and writing configurations for Twyn."""
4949

50-
def __init__(self, file_path: Optional[str] = None, enforce_file: bool = True):
51-
self._file_path = file_path or DEFAULT_PROJECT_TOML_FILE
50+
def __init__(self, file_path: Optional[str] = None, enforce_file: bool = True) -> None:
51+
file_path = file_path or DEFAULT_PROJECT_TOML_FILE
52+
self.file_handler = FileHandler(file_path)
5253
self._enforce_file = enforce_file
5354

5455
def resolve_config(
@@ -119,36 +120,19 @@ def _write_config(self, toml: TOMLDocument, config: ReadTwynConfiguration) -> No
119120
if "twyn" not in toml["tool"]: # type: ignore[operator]
120121
toml["tool"]["twyn"] = {} # type: ignore[index]
121122
toml["tool"]["twyn"] = twyn_toml_data # type: ignore[index]
123+
122124
self._write_toml(toml)
123125

126+
def _write_toml(self, toml: TOMLDocument) -> None:
127+
self.file_handler.write(dumps(toml))
128+
124129
def _read_toml(self) -> TOMLDocument:
125130
try:
126-
fp = self._get_toml_file_pointer()
127-
except FileNotFoundError:
128-
if not self._enforce_file and self._file_path == DEFAULT_PROJECT_TOML_FILE:
131+
return parse(self.file_handler.read())
132+
except PathNotFoundError:
133+
if not self._enforce_file and self.file_handler.is_handler_of_file(DEFAULT_PROJECT_TOML_FILE):
129134
return TOMLDocument()
130-
raise TOMLError(f"Error reading toml from {self._file_path}") from None
131-
132-
with open(fp, "r") as f:
133-
content = parse(f.read())
134-
return content
135-
136-
def _get_toml_file_pointer(self) -> Path:
137-
"""Create a path for the toml file with the format <current working directory>/self.file_path."""
138-
fp = Path(getcwd()) / Path(self._file_path)
139-
140-
if not fp.is_file():
141-
raise FileNotFoundError(f"File not found at path '{fp}'.")
142-
143-
return fp
144-
145-
def _write_toml(self, toml: TOMLDocument) -> None:
146-
with open(self._get_toml_file_pointer(), "w") as f:
147-
try:
148-
f.write(dumps(toml))
149-
except Exception:
150-
logger.exception("Error writing toml file")
151-
raise TOMLError(f"Error writing toml to {self._file_path}") from None
135+
raise TOMLError(f"Error reading toml from {self.file_handler.file_path}") from None
152136

153137

154138
def _get_logging_level(

src/twyn/dependency_parser/abstract_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from abc import ABC, abstractmethod
44
from pathlib import Path
55

6-
from twyn.file_handler.file_handler import FileHandlerPathlib
6+
from twyn.file_handler.file_handler import FileHandler
77

88
logger = logging.getLogger("twyn")
99

@@ -17,7 +17,7 @@ class AbstractParser(ABC):
1717

1818
def __init__(self, file_path: str) -> None:
1919
self.file_path = Path(os.path.abspath(os.path.join(os.getcwd(), file_path)))
20-
self.file_handler = FileHandlerPathlib(file_path=self.file_path)
20+
self.file_handler = FileHandler(file_path=self.file_path)
2121

2222
def __str__(self) -> str:
2323
return self.__class__.__name__

src/twyn/file_handler/file_handler.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@
1010

1111

1212
class BaseFileHandler(Protocol):
13-
def __init__(self, file_path: str) -> None: ...
1413
def read(self) -> str: ...
1514
def file_exists(self) -> bool: ...
15+
def write(self, data: str) -> None: ...
1616

1717

18-
class FileHandlerPathlib(BaseFileHandler):
18+
class FileHandler(BaseFileHandler):
1919
def __init__(self, file_path: str) -> None:
20-
self.file_path = Path(os.path.abspath(os.path.join(os.getcwd(), file_path)))
20+
self.file_path = self._get_file_path(file_path)
21+
22+
def _get_file_path(self, file_path: str) -> Path:
23+
return Path(os.path.abspath(os.path.join(os.getcwd(), file_path)))
24+
25+
def is_handler_of_file(self, name: str) -> bool:
26+
return self._get_file_path(name) == self.file_path
2127

2228
def read(self) -> str:
2329
self._raise_for_file_exists()
@@ -40,3 +46,7 @@ def _raise_for_file_exists(self) -> None:
4046

4147
if not self.file_path.is_file():
4248
raise PathIsNotFileError
49+
50+
def write(self, data: str) -> None:
51+
self._raise_for_file_exists()
52+
self.file_path.write_text(data)

tests/core/test_config_handler.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@
1111
AllowlistPackageDoesNotExistError,
1212
TOMLError,
1313
)
14+
from twyn.file_handler.exceptions import PathNotFoundError
1415

1516

1617
class TestConfig:
1718
def throw_exception(self):
18-
raise FileNotFoundError
19+
raise PathNotFoundError
1920

20-
@patch("twyn.config.config_handler.ConfigHandler._get_toml_file_pointer")
21+
@patch("twyn.file_handler.file_handler.FileHandler.read")
2122
def test_enforce_file_error(self, mock_is_file):
2223
mock_is_file.side_effect = self.throw_exception
2324
with pytest.raises(TOMLError):
2425
ConfigHandler(enforce_file=True).resolve_config()
2526

26-
@patch("twyn.config.config_handler.ConfigHandler._get_toml_file_pointer")
27+
@patch("twyn.file_handler.file_handler.FileHandler.read")
2728
def test_no_enforce_file_on_non_existent_file(self, mock_is_file):
2829
"""Resolving the config without enforcing the file to be present gives you defaults."""
2930
mock_is_file.side_effect = self.throw_exception
@@ -49,10 +50,10 @@ def test_read_config_values(self, pyproject_toml_file):
4950
assert config.allowlist == {"boto4", "boto2"}
5051

5152
def test_get_twyn_data_from_file(self, pyproject_toml_file):
52-
handler = ConfigHandler(file_path=pyproject_toml_file)
53+
handler = ConfigHandler(pyproject_toml_file)
5354

5455
toml = handler._read_toml()
55-
twyn_data = ConfigHandler(file_path=pyproject_toml_file)._get_read_config(toml)
56+
twyn_data = ConfigHandler(pyproject_toml_file)._get_read_config(toml)
5657
assert twyn_data == ReadTwynConfiguration(
5758
dependency_file="my_file.txt",
5859
selector_method="my_selector",
@@ -62,7 +63,7 @@ def test_get_twyn_data_from_file(self, pyproject_toml_file):
6263
)
6364

6465
def test_write_toml(self, pyproject_toml_file):
65-
handler = ConfigHandler(file_path=pyproject_toml_file)
66+
handler = ConfigHandler(pyproject_toml_file)
6667
toml = handler._read_toml()
6768

6869
initial_config = handler.resolve_config()
@@ -103,12 +104,12 @@ def test_write_toml(self, pyproject_toml_file):
103104

104105

105106
class TestAllowlistConfigHandler:
106-
@patch("twyn.config.config_handler.ConfigHandler._write_toml")
107+
@patch("twyn.file_handler.file_handler.FileHandler.write")
107108
@patch("twyn.config.config_handler.ConfigHandler._read_toml")
108109
def test_allowlist_add(self, mock_toml, mock_write_toml):
109110
mock_toml.return_value = TOMLDocument()
110111

111-
config = ConfigHandler()
112+
config = ConfigHandler("some-file")
112113

113114
config.add_package_to_allowlist("mypackage")
114115

tests/file_handler/test_file_handler.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22

33
import pytest
44
from twyn.file_handler.exceptions import PathIsNotFileError, PathNotFoundError
5-
from twyn.file_handler.file_handler import FileHandlerPathlib
5+
from twyn.file_handler.file_handler import FileHandler
66

77

8-
class TestFileHandlerPathlib:
8+
class TestFileHandler:
99
def test_file_exists(self, pyproject_toml_file: str):
10-
parser = FileHandlerPathlib(pyproject_toml_file)
10+
parser = FileHandler(pyproject_toml_file)
1111
assert parser.file_exists() is True
1212

1313
def test_read_file_success(self, pyproject_toml_file: str):
14-
parser = FileHandlerPathlib(pyproject_toml_file)
14+
parser = FileHandler(pyproject_toml_file)
1515
read = parser.read()
1616
assert len(read) > 1
1717
assert isinstance(read, str)
1818

1919
def test_read_file_does_not_exist(
2020
self,
2121
):
22-
parser = FileHandlerPathlib("")
22+
parser = FileHandler("")
2323
with pytest.raises(PathIsNotFileError):
2424
parser.read()
2525

@@ -33,5 +33,5 @@ def test_raise_for_valid_file(self, mock_is_file, mock_exists, file_exists, is_f
3333
mock_exists.return_value = file_exists
3434
mock_is_file.return_value = is_file
3535

36-
parser = FileHandlerPathlib("fake.txt")
36+
parser = FileHandler("fake.txt")
3737
assert parser.file_exists() is False

0 commit comments

Comments
 (0)