Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Breaking Configuration Inheritance #326 #339

Merged
merged 23 commits into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
37abd5a
Add tests to test the inheritance break feature
ep-linden Feb 17, 2022
c20e97c
Add inner functions to break inheritance
ep-linden Feb 18, 2022
82bf36a
Add additional test cases and rename tests
ep-linden Feb 23, 2022
f179b68
Add validate break inheritance flag function
ep-linden Feb 23, 2022
d189335
Fix test subgroup test case
ep-linden Mar 1, 2022
c80d9d2
Call validation function from outside merge configs function
ep-linden Mar 1, 2022
d16fd11
Separate validation function from merge config function
ep-linden Mar 1, 2022
e4f111e
Rename test file
ep-linden Mar 1, 2022
e36c54a
Add initial tests for breaking inheritance from subgroups
ep-linden Mar 1, 2022
074901a
Remove unused keyword arguments
ep-linden Mar 2, 2022
50a1da0
Add test cases
ep-linden Mar 2, 2022
7d756ec
Remove the break inheritance flag
ep-linden Mar 11, 2022
02611a2
Refactor: move configs near the code that tests them
gdubicki Mar 12, 2022
554be4d
Clarify when to use each exit code
gdubicki Mar 12, 2022
895e8fd
Refactor the validate_break_inheritance_flag function
ep-linden Mar 23, 2022
8ebf17c
Remove new line
ep-linden Mar 23, 2022
6f09fbf
Change exit code to input error
ep-linden Mar 23, 2022
7b58bf9
Merge branch 'feature/issue-326' of github.com:ep-linden/gitlabform i…
ep-linden Mar 23, 2022
4b30d2f
Use constant instead of literal in test cases
ep-linden Mar 24, 2022
b702fb0
Combine non-reused fixtures with the corresponding test cases
ep-linden Mar 24, 2022
28d1095
Add test for flag set outside a section
ep-linden Apr 14, 2022
50c3aa2
Add logic to check if the inherit flag is set to true or false
ep-linden Apr 20, 2022
f0895b6
Remove test to check if inherit flag is set outside a section
ep-linden Apr 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions gitlabform/configuration/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
from yamlpath.common import Parsers
from yamlpath.wrappers import ConsolePrinter

from gitlabform import EXIT_INVALID_INPUT
from gitlabform import EXIT_INVALID_INPUT, EXIT_PROCESSING_ERROR
from ruamel.yaml.comments import CommentedMap


class ConfigurationCore(ABC):
Expand Down Expand Up @@ -162,13 +163,64 @@ def is_group_skipped(self, group) -> bool:
def is_skipped(self, an_array: list, item: str) -> bool:
pass

@staticmethod
def validate_break_inheritance_flag(config, **kwargs):
gdubicki marked this conversation as resolved.
Show resolved Hide resolved
has_invalid_flag = False
level = None
for key, value in config.items():
if "inherit" == key:
if kwargs["parent"] == "empty" and (
kwargs["level"] == "group"
or kwargs["level"] == "project"
or kwargs["level"] == "subgroup"
gdubicki marked this conversation as resolved.
Show resolved Hide resolved
):
level = kwargs["level"]
has_invalid_flag = True
elif kwargs["level"] == "common":
level = "common"
has_invalid_flag = True
if has_invalid_flag:
fatal(
"The inheritance break flag cannot be placed at the {config_level} level\n"
gdubicki marked this conversation as resolved.
Show resolved Hide resolved
"because {config_level} level is the highest level in the configuration file.\n".format(
config_level=level
),
exit_code=EXIT_PROCESSING_ERROR,
gdubicki marked this conversation as resolved.
Show resolved Hide resolved
)
elif type(value) is CommentedMap:
ConfigurationCore.validate_break_inheritance_flag(
value, level=kwargs["level"], parent=kwargs["parent"]
)

@staticmethod
def merge_configs(more_general_config, more_specific_config) -> dict:
"""
:return: merge more general config with more specific configs.
More specific config values take precedence over more general ones.
"""
return dict(merge({}, more_general_config, more_specific_config))

merged_dict = merge({}, more_general_config, more_specific_config)

def break_inheritance(specific_config, parent_key=""):
for key, value in specific_config.items():
if "inherit" == key:
gdubicki marked this conversation as resolved.
Show resolved Hide resolved
replace_config_sections(merged_dict, parent_key, specific_config)
break
elif type(value) is CommentedMap:
break_inheritance(value, key)

def replace_config_sections(merged_config, specific_key, specific_config):
for key, value in merged_config.items():
if specific_key == key:
del specific_config["inherit"]
merged_config[key] = specific_config
break
elif type(value) is CommentedMap:
replace_config_sections(value, specific_key, specific_config)

break_inheritance(more_specific_config)

return dict(merged_dict)


class ConfigFileNotFoundException(Exception):
Expand Down
22 changes: 21 additions & 1 deletion gitlabform/configuration/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ def get_effective_config_for_group(self, group) -> dict:
if not group_config and not common_config:
return {}

if common_config:
self.validate_break_inheritance_flag(
common_config, level="common", parent=""
)
elif not common_config and group_config:
self.validate_break_inheritance_flag(
group_config, level="group", parent="empty"
)

return self.merge_configs(common_config, group_config)

def get_effective_subgroup_config(self, subgroup):
Expand Down Expand Up @@ -75,8 +84,19 @@ def get_effective_subgroup_config(self, subgroup):
next_level_subgroup,
to_str(next_level_subgroup_config),
)

if effective_config:
self.validate_break_inheritance_flag(
effective_config, level="group", parent=""
)
elif not effective_config and next_level_subgroup_config:
self.validate_break_inheritance_flag(
next_level_subgroup_config, level="subgroup", parent="empty"
)

effective_config = self.merge_configs(
effective_config, next_level_subgroup_config
effective_config,
next_level_subgroup_config,
)
debug(
"Merged previous level config for '%s' with config for '%s': %s",
Expand Down
26 changes: 23 additions & 3 deletions gitlabform/configuration/projects_and_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,35 @@ def get_effective_config_for_project(self, group_and_project) -> dict:
debug("Effective group/subgroup config: %s", to_str(group_config))

project_config = self.get_project_config(group_and_project)
debug("Project config: %s", to_str(project_config))
debug("\nProject config: %s", to_str(project_config))
gdubicki marked this conversation as resolved.
Show resolved Hide resolved

common_and_group_config = self.merge_configs(common_config, group_config)
if common_config:
self.validate_break_inheritance_flag(
common_config, level="common", parent=""
)
elif not common_config and group_config:
self.validate_break_inheritance_flag(
group_config, level="group", parent="empty"
)

common_and_group_config = self.merge_configs(
common_config,
group_config,
)
debug(
"Effective config common+group/subgroup: %s",
to_str(common_and_group_config),
)

effective_config = self.merge_configs(common_and_group_config, project_config)
if not common_and_group_config and project_config:
self.validate_break_inheritance_flag(
project_config, level="project", parent="empty"
)

effective_config = self.merge_configs(
common_and_group_config,
project_config,
)
debug(
"Effective config common+group/subgroup+project: %s",
to_str(effective_config),
Expand Down
Loading