Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 43 additions & 19 deletions webhook_server_container/libs/github_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2038,16 +2038,18 @@ def get_all_approvers(self) -> list[str]:
_approvers: list[str] = []
for list_of_approvers in self.owners_data_for_changed_files().values():
for _approver in list_of_approvers.get("approvers", []):
_approvers.append(_approver)
if _approver not in _approvers:
_approvers.append(_approver)

_approvers.sort()
return _approvers

def get_all_reviewers(self) -> list[str]:
_reviewers: list[str] = []
for list_of_reviewers in self.owners_data_for_changed_files().values():
for _approver in list_of_reviewers.get("reviewers", []):
_reviewers.append(_approver)
for _reviewer in list_of_reviewers.get("reviewers", []):
if _reviewer not in _reviewers:
_reviewers.append(_reviewer)

_reviewers.sort()
return _reviewers
Expand All @@ -2056,29 +2058,51 @@ def owners_data_for_changed_files(self) -> dict[str, dict[str, Any]]:
data: dict[str, dict[str, Any]] = {}

changed_folders = {Path(cf).parent for cf in self.changed_files}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add docstring that shows examples?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still have not added docstring. Will do it next.


changed_folder_match: list[str] = []

require_root_approvers: bool = False
for changed_folder in changed_folders:
changed_folder_str = str(changed_folder)
_owners_data = self._get_owner_data_for_changed_folder(_changed_folder=changed_folder_str)
data[changed_folder_str] = _owners_data

for owners_dir, owners_data in self.all_approvers_and_reviewers.items():
_owners_dir = Path(owners_dir)

for changed_folder in changed_folders:
if _owners_dir == changed_folder or _owners_dir.parents == changed_folders:
data[owners_dir] = owners_data
changed_folder_match.append(owners_dir)
if not require_root_approvers:
require_root_approvers = owners_data.get("root-approvers", True)

if [_folder for _folder in changed_folders if str(_folder) not in changed_folder_match]:
data["."] = self.all_approvers_and_reviewers.get(".", {})
if not require_root_approvers:
require_root_approvers = _owners_data.get("root-approvers", True)

if require_root_approvers:
data["."] = self.all_approvers_and_reviewers.get(".", {})

return data

def _get_owner_data_for_changed_folder(self, _changed_folder: str) -> dict[str, Any]:
# if we find entry for the changed folder in self.all_approvers_and_reviewers, then we return it
# else we start from the parent and go all the way to root and combine all approvers and owners found
# return the same. "root-approvers" would be copied from the owner file found below root
# Example: if a file file1.txt is changed, that is found under
# test_folder0/test_folder_1/test_folder2/test_folder3/, reviewers and
# approvers from test_folder3, test_folder2, test_folder1, test_folder0 and root all would be combined
# to get approvers and reviewers of file1.txt

_aggregated_owners: dict[str, Any] = {"approvers": [], "reviewers": []}
owners_data = self.all_approvers_and_reviewers
if owners_data.get(_changed_folder):
return owners_data[_changed_folder]
else:
# find all owners files till root and combine them all
while _changed_folder != ".":
_changed_folder = str(Path(_changed_folder).parent) or "."
if owners_data.get(_changed_folder):
_aggregated_owners["approvers"].extend([
_approver
for _approver in owners_data[_changed_folder].get("approvers", [])
if _approver not in _aggregated_owners["approvers"]
])
_aggregated_owners["reviewers"].extend([
_reviewer
for _reviewer in owners_data[_changed_folder].get("reviewers", [])
if _reviewer not in _aggregated_owners["reviewers"]
])
if _changed_folder != ".":
_aggregated_owners["root-approvers"] = owners_data[_changed_folder].get("root-approvers", True)
return _aggregated_owners

def _validate_owners_content(self, content: Any, path: str) -> bool:
"""Validate OWNERS file content structure."""
try:
Expand Down
Loading