Skip to content

Commit

Permalink
Add option to continue searching for configuration file even if .git …
Browse files Browse the repository at this point in the history
…is found (#941)
  • Loading branch information
bhirsz authored Oct 7, 2023
1 parent 29aa7c8 commit bf3632c
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 14 deletions.
3 changes: 3 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ provided using CLI, Robocop will try to find default configuration file using th
- otherwise, if the directory contains ``pyproject.toml`` file, load it
- otherwise, go to parent directory. Stop search if ``.git`` or top disk directory is found

It is possible to not stop searching parent directories even if ``.git`` directory is found using
``--ignore-git-dir`` flag.

``.robocop`` argument file
--------------------------

Expand Down
5 changes: 5 additions & 0 deletions docs/releasenotes/unreleased/other.2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
--ignore-git-dir option to ignore .git when searching for configuration file (#908)
------------------------------------------------------------------------------------

When searching for the default configuration file, Robocop stop searching if ``.git`` directory is found. It is now
possible to disable this behaviour using ``--ignore-git-dir`` flag.
24 changes: 16 additions & 8 deletions robocop/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ def __init__(self, root=None, from_cli: bool = False):
self.recursive = True
self.verbose = False
self.persistent = False
self.ignore_git_dir = False
self.config_from = ""
self.root = find_project_root(root, ["."])
self.parse()
Expand Down Expand Up @@ -374,6 +375,13 @@ def _create_parser(self):
)
optional.add_argument("-A", "--argumentfile", metavar="PATH", help="Path to file with arguments.")
optional.add_argument("--config", metavar="PATH", help="Path to TOML configuration file.")
optional.add_argument(
"--ignore-git-dir",
action="store_true",
default=self.ignore_git_dir,
help="Use this flag to continue searching for the default configuration file even if parent directory "
"contains '.git' directory. Useful for multirepo.",
)
optional.add_argument(
"-g",
"--ignore",
Expand Down Expand Up @@ -435,7 +443,7 @@ def parse(self):
return
args = sys.argv[1:]
if not self.config_file_in_cli(args):
self.load_default_config_file()
self.load_default_config_file(ignore_git_dir="--ignore-git-dir" in args)
self.parse_args(args)

@staticmethod
Expand All @@ -459,20 +467,20 @@ def print_config_source(self):
else:
print("No config file found or configuration is empty. Using default configuration")

def load_default_config_file(self):
def load_default_config_file(self, ignore_git_dir: bool = False):
"""Find and load default configuration file.
First look for .robocop file. If it does not exist, search for pyproject.toml file."""
if self.load_robocop_file():
if self.load_robocop_file(ignore_git_dir):
return
pyproject_path = find_file_in_project_root("pyproject.toml", self.root)
if pyproject_path.is_file():
pyproject_path = find_file_in_project_root("pyproject.toml", self.root, ignore_git_dir)
if pyproject_path is not None:
self.load_pyproject_file(pyproject_path)

def load_robocop_file(self):
def load_robocop_file(self, ignore_git_dir: bool):
"""Returns True if .robocop exists"""
robocop_path = find_file_in_project_root(".robocop", self.root)
if not robocop_path.is_file():
robocop_path = find_file_in_project_root(".robocop", self.root, ignore_git_dir)
if robocop_path is None:
return False
argument_files_parser = ArgumentFileParser()
args = argument_files_parser.load_argument_file(robocop_path, robocop_path.parent)
Expand Down
7 changes: 4 additions & 3 deletions robocop/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ def find_project_root(root, srcs):
return directory


def find_file_in_project_root(config_name, root):
def find_file_in_project_root(config_name, root, ignore_git_dir: bool):
for parent in (root, *root.parents):
if (parent / ".git").exists() or (parent / config_name).is_file():
if (parent / config_name).is_file():
return parent / config_name
return parent / config_name
if not ignore_git_dir and (parent / ".git").exists():
return None


@lru_cache()
Expand Down
Empty file.
17 changes: 14 additions & 3 deletions tests/utest/test_configuration_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,25 @@ class TestConfigurationFile:
def test_find_project_root_same_dir(self, path_to_test_data):
src = path_to_test_data / "default_config"
with working_directory(src):
root = find_file_in_project_root(".robocop", src)
root = find_file_in_project_root(".robocop", src, False)
assert root == src / ".robocop"

def test_find_project_root_missing_but_git(self, path_to_test_data):
src = path_to_test_data / "default_config_missing" / "nested" / "deeper"
with working_directory(src):
root = find_file_in_project_root(".robocop", src)
assert root == Path(__file__).parent.parent.parent / ".robocop"
root = find_file_in_project_root(".robocop", src, False)
assert root is None

def test_ignore_git_dir(self, path_to_test_data):
src = path_to_test_data / "default_config_outside_git"
cwd_src = src / "root"
(cwd_src / ".git").mkdir(parents=True, exist_ok=True)
with working_directory(cwd_src):
config_file_disabled = find_file_in_project_root("pyproject.toml", cwd_src, False)
config_file_enabled = find_file_in_project_root("pyproject.toml", cwd_src, True)

assert config_file_disabled is None
assert config_file_enabled == src / "pyproject.toml"

def test_load_config_from_default_file(self, path_to_test_data):
src = path_to_test_data / "default_config"
Expand Down

0 comments on commit bf3632c

Please sign in to comment.