diff --git a/docs/configuration.md b/docs/configuration.md index 6f8f746..545be55 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -16,6 +16,7 @@ below: [tool.dbt-score] rule_namespaces = ["dbt_score.rules", "dbt_score_rules", "custom_rules"] disabled_rules = ["dbt_score.rules.generic.columns_have_description"] +inject_cwd_in_python_path = true [tool.dbt-score.badges] first.threshold = 10.0 diff --git a/docs/create_rules.md b/docs/create_rules.md index 054c458..1efa1f8 100644 --- a/docs/create_rules.md +++ b/docs/create_rules.md @@ -62,7 +62,8 @@ By default `dbt-score` will look for rules in the Python namespace `dbt_score_rules`. Rules can be stored anywhere in the Python path under the `dbt_score_rules` namespace. In many cases, having such a folder in the dbt project from where you invoke dbt and dbt-score will work. In this folder, all -rules defined in `.py` files will be automatically discovered. +rules defined in `.py` files will be automatically discovered. By default, the +current working directory is injected in the Python path. If nested folders are used, e.g. `dbt_score_rules/generic_rules/rules.py`, an `__init__.py` file needs to be present in the nested folder to make it diff --git a/src/dbt_score/config.py b/src/dbt_score/config.py index f15e2a9..4862c4c 100644 --- a/src/dbt_score/config.py +++ b/src/dbt_score/config.py @@ -49,6 +49,7 @@ class Config: _options: Final[list[str]] = [ "rule_namespaces", "disabled_rules", + "inject_cwd_in_python_path", ] _rules_section: Final[str] = "rules" _badges_section: Final[str] = "badges" @@ -57,6 +58,7 @@ def __init__(self) -> None: """Initialize the Config object.""" self.rule_namespaces: list[str] = ["dbt_score.rules", "dbt_score_rules"] self.disabled_rules: list[str] = [] + self.inject_cwd_in_python_path = True self.rules_config: dict[str, RuleConfig] = {} self.config_file: Path | None = None self.badge_config: BadgeConfig = BadgeConfig() diff --git a/src/dbt_score/rule_registry.py b/src/dbt_score/rule_registry.py index 171abda..a8681b2 100644 --- a/src/dbt_score/rule_registry.py +++ b/src/dbt_score/rule_registry.py @@ -5,7 +5,9 @@ import importlib import logging +import os import pkgutil +import sys from typing import Iterator, Type from dbt_score.config import Config @@ -67,5 +69,13 @@ def _add_rule(self, rule: Type[Rule]) -> None: def load_all(self) -> None: """Load all rules, core and third-party.""" + # Add cwd to Python path + old_sys_path = sys.path # Save original values + if self.config.inject_cwd_in_python_path and os.getcwd() not in sys.path: + sys.path.append(os.getcwd()) + for namespace in self.config.rule_namespaces: self._load(namespace) + + # Restore original values + sys.path = old_sys_path