config: Start configuration file with books path.

Ultimately I would like to make it possible to configure the software
entirely through this file, rather than the hodgepodge system we have
now. But that can come later.
This commit is contained in:
Brett Smith 2020-04-12 22:27:52 -04:00
parent 8fa9a0ffe6
commit 7f45788235
2 changed files with 44 additions and 0 deletions

View file

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import configparser
import decimal
import functools
import os
@ -74,6 +75,15 @@ class Config:
'XDG_CONFIG_HOME': Path('.config'),
}
def __init__(self) -> None:
self.file_config = configparser.ConfigParser()
def load_file(self, config_path: Optional[Path]=None) -> None:
if config_path is None:
config_path = self.config_file_path()
with config_path.open() as config_file:
self.file_config.read_file(config_file)
def _dir_or_none(self, path: Path) -> Optional[Path]:
try:
path.mkdir(exist_ok=True)
@ -94,6 +104,15 @@ class Config:
retval = default or (Path.home() / self._ENVIRON_DEFAULT_PATHS[key])
return retval
def books_path(self) -> Optional[Path]:
try:
retval = Path(self.file_config['Beancount'].get('books dir'))
except (KeyError, ValueError):
ok = False
else:
ok = retval.is_absolute()
return retval if ok else None
def cache_dir_path(self, name: str='conservancy_beancount') -> Optional[Path]:
cache_root = self._path_from_environ('XDG_CACHE_HOME')
return (

View file

@ -16,6 +16,7 @@
import contextlib
import decimal
import operator
import os
import re
@ -317,3 +318,27 @@ def test_config_file_path_with_subdir():
expected = testutil.test_path('userconfig/conftest/config.ini')
config = config_mod.Config()
assert config.config_file_path('conftest') == expected
@pytest.mark.parametrize('path', [
None,
testutil.test_path('userconfig/conservancy_beancount/config.ini'),
])
def test_load_file(path):
config = config_mod.Config()
config.load_file(path)
assert config.books_path() == Path('/test/conservancy_beancount')
@pytest.mark.parametrize('path_func', [
lambda path: None,
operator.methodcaller('touch', 0o200),
])
def test_load_file_error(tmp_path, path_func):
config_path = tmp_path / 'nonexistent.ini'
path_func(config_path)
config = config_mod.Config()
with pytest.raises(OSError):
config.load_file(config_path)
def test_no_books_path():
config = config_mod.Config()
assert config.books_path() is None