Skip to content

Commit

Permalink
Scan for config files up to 2 levels up
Browse files Browse the repository at this point in the history
The domain object can be instantiated within the src folder, but the .toml
file can be present in the project root. This commit adds the capability
to scan for config files up to 2 levels up from the file in which the
domain object is instantiated.
  • Loading branch information
subhashb committed May 28, 2024
1 parent c2089eb commit 907d826
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 17 deletions.
39 changes: 23 additions & 16 deletions src/protean/domain/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,29 @@ def load_from_dict(cls, config: dict):

@classmethod
def load_from_path(cls, path: str, defaults: dict = None):
# Derive the path of parent directory
dir_path = os.path.abspath(os.path.dirname(path))

# Find config files in the directory in the following order:
# 1. .domain.toml
# 2. domain.toml
# 3. pyproject.toml
config_file_name = os.path.join(dir_path, ".domain.toml")
if not os.path.exists(config_file_name):
config_file_name = os.path.join(dir_path, "domain.toml")
if not os.path.exists(config_file_name):
config_file_name = os.path.join(dir_path, "pyproject.toml")
if not os.path.exists(config_file_name):
raise ConfigurationError(
f"No configuration file found in {dir_path}"
)
def find_config_file(directory: str):
config_files = [".domain.toml", "domain.toml", "pyproject.toml"]
for config_file in config_files:
config_file_path = os.path.join(directory, config_file)
if os.path.exists(config_file_path):
return config_file_path
return None

# Start checking from the provided path up to 2 parent directories
current_dir = os.path.abspath(os.path.dirname(path))
config_file_name = None

for _ in range(3): # Check the current directory and up to 2 parent directories
config_file_name = find_config_file(current_dir)
if config_file_name:
break

current_dir = os.path.dirname(current_dir) # Move to the parent directory

if not config_file_name:
raise ConfigurationError(
f"No configuration file found in {os.path.dirname(path)}"
)

config = {}
if config_file_name:
Expand Down
14 changes: 14 additions & 0 deletions tests/config/test_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,17 @@ def test_that_config_is_loaded_from_dict(self):
assert config["databases"]["default"]["provider"] == "memory"
assert config["custom"]["FOO"] == "bar"
assert config["custom"]["qux"] == "quux"


def test_that_config_is_loaded_from_1st_parent_folder_of_path():
change_working_directory_to("test22")

domain = derive_domain("src/publishing/domain22")
assert domain.config["custom"]["foo"] == "corge"


def test_that_config_is_loaded_from_2nd_parent_folder_of_path():
change_working_directory_to("test23")

domain = derive_domain("src/publishing/domain23")
assert domain.config["custom"]["foo"] == "grault"
5 changes: 4 additions & 1 deletion tests/support/test_domains/test21/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
This folder contains a single domain spanning multiple folders. Tests are
related to scanning domain elements across subfolders.
related to scanning domain elements across subfolders and avoiding folders
containing a known config file.

`auth` subdirectory, in this example, is a model of its own.
2 changes: 2 additions & 0 deletions tests/support/test_domains/test22/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This test folder is to test that files that are 1 level up from the domain
instantiation file are still considered.
5 changes: 5 additions & 0 deletions tests/support/test_domains/test22/src/domain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
debug = true
testing = true

[custom]
foo = "corge"
4 changes: 4 additions & 0 deletions tests/support/test_domains/test22/src/publishing/domain22.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from protean import Domain


domain = Domain(__file__, "TEST22")
2 changes: 2 additions & 0 deletions tests/support/test_domains/test23/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This test folder is to test that files that are 2 levels up from the domain
instantiation file are still considered.
5 changes: 5 additions & 0 deletions tests/support/test_domains/test23/domain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
debug = true
testing = true

[custom]
foo = "grault"
4 changes: 4 additions & 0 deletions tests/support/test_domains/test23/src/publishing/domain23.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from protean import Domain


domain = Domain(__file__, "TEST23")

0 comments on commit 907d826

Please sign in to comment.