Skip to content

Commit 35c04ce

Browse files
committed
improve handling of empty owner configuration
This keeps backward compatibility. Also refactor a bit to make code easier to read
1 parent 473e267 commit 35c04ce

File tree

2 files changed

+72
-55
lines changed

2 files changed

+72
-55
lines changed

gh_org_mgr/_gh_org.py

+70-55
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"""Class for the GitHub organization which contains most of the logic"""
66

77
import logging
8-
import sys
98
from dataclasses import asdict, dataclass, field
109

1110
from github import Github, UnknownObjectException
@@ -187,19 +186,29 @@ def _get_current_org_owners(self) -> None:
187186
for member in self.org.get_members(role="admin"):
188187
self.current_org_owners.append(member)
189188

190-
def _get_configured_org_owners(self, cfg_org_owners: list[str]) -> None:
189+
def _get_configured_org_owners(self, cfg_org_owners: list[str] | str | None) -> None:
191190
"""Import configured owners for the organization from the org configuration"""
192-
# Sanity check
193-
if not cfg_org_owners or not isinstance(cfg_org_owners, list):
194-
logging.critical(
195-
"No owners for GitHub organisation defined or not as list. "
196-
"This would make the organization unmanageable. Will not continue."
191+
# Add configured owners if they are a list
192+
if isinstance(cfg_org_owners, list):
193+
# Import users to dataclass attribute, lower-case
194+
for user in cfg_org_owners:
195+
self.configured_org_owners.append(user.lower())
196+
else:
197+
logging.warning(
198+
"The organisation owners are not configured as a proper list. Will not handle them."
199+
)
200+
201+
def _check_non_empty_configured_owners(self) -> bool:
202+
"""Handle if there are no configured owners. Returns True if owners are configured."""
203+
if not self.configured_org_owners:
204+
logging.warning(
205+
"No owners for your GitHub organisation configured. Will not make any "
206+
"change regarding the ownership, and continue with the current owners: %s",
207+
", ".join([user.login for user in self.current_org_owners]),
197208
)
198-
sys.exit(1)
209+
return False
199210

200-
# Import users to dataclass attribute, lower-case
201-
for user in cfg_org_owners:
202-
self.configured_org_owners.append(user.lower())
211+
return True
203212

204213
def _is_user_authenticated_user(self, user: NamedUser) -> bool:
205214
"""Check if a given NamedUser is the authenticated user"""
@@ -213,58 +222,64 @@ def sync_org_owners(self, cfg_org_owners: list, dry: bool = False, force: bool =
213222
self._get_current_org_owners()
214223
self._get_configured_org_owners(cfg_org_owners=cfg_org_owners)
215224

225+
# Abort owner synchronisation if there are no configured owners
226+
if not self._check_non_empty_configured_owners():
227+
return
228+
229+
# Get differences between the current and configured owners
230+
owners_remove, owners_ok, owners_add = self.compare_two_lists(
231+
self.configured_org_owners, [user.login for user in self.current_org_owners]
232+
)
216233
# Compare configured (lower-cased) owners with lower-cased list of current owners
217-
current_org_owners_str = [user.login for user in self.current_org_owners]
218-
if self.configured_org_owners == current_org_owners_str:
234+
if not owners_remove and not owners_add:
219235
logging.info("Organization owners are in sync, no changes")
220-
else:
221-
# Get differences between the two lists
222-
remove, match, add = self.compare_two_lists(
223-
self.configured_org_owners, current_org_owners_str
224-
)
225-
logging.debug(
226-
"Organization owners are not in sync. Config: '%s' vs. Current: '%s'",
227-
self.configured_org_owners,
228-
current_org_owners_str,
229-
)
230-
logging.debug("Will remove %s, will not change %s, will add %s", remove, match, add)
236+
return
231237

232-
# Add the missing owners
233-
for user in add:
234-
if gh_user := self._resolve_gh_username(user, "<org owners>"):
235-
logging.info("Adding user '%s' as organization owner", gh_user.login)
236-
if not dry:
237-
self.org.add_to_members(gh_user, "admin")
238+
logging.debug(
239+
"Organization owners are not in sync. Config: '%s' vs. Current: '%s'",
240+
self.configured_org_owners,
241+
self.current_org_owners,
242+
)
243+
logging.debug(
244+
"Will remove %s, will not change %s, will add %s", owners_remove, owners_ok, owners_add
245+
)
238246

239-
# Remove the surplus owners
240-
for user in remove:
241-
if gh_user := self._resolve_gh_username(user, "<org owners>"):
242-
logging.info(
243-
"User '%s' is not configured as organization owners. "
244-
"Will make them a normal member",
247+
# Add the missing owners
248+
for user in owners_add:
249+
if gh_user := self._resolve_gh_username(user, "<org owners>"):
250+
logging.info("Adding user '%s' as organization owner", gh_user.login)
251+
if not dry:
252+
self.org.add_to_members(gh_user, "admin")
253+
254+
# Remove the surplus owners
255+
for user in owners_remove:
256+
if gh_user := self._resolve_gh_username(user, "<org owners>"):
257+
logging.info(
258+
"User '%s' is not configured as organization owners. "
259+
"Will make them a normal member",
260+
gh_user.login,
261+
)
262+
# Handle authenticated user being the same as the one you want to degrade
263+
if self._is_user_authenticated_user(gh_user):
264+
logging.warning(
265+
"The user '%s' you want to remove from owners is the one you "
266+
"authenticated with. This may disrupt all further operations. "
267+
"Unless you run the program with --force, "
268+
"this operation will not be executed.",
245269
gh_user.login,
246270
)
247-
# Handle authenticated user being the same as the one you want to degrade
248-
if self._is_user_authenticated_user(gh_user):
249-
logging.warning(
250-
"The user '%s' you want to remove from owners is the one you "
251-
"authenticated with. This may disrupt all further operations. "
252-
"Unless you run the program with --force, "
253-
"this operation will not be executed.",
254-
gh_user.login,
271+
# Check if user forced this operation
272+
if force:
273+
logging.info(
274+
"You called the program with --force, "
275+
"so it will remove yourself from the owners"
255276
)
256-
# Check if user forced this operation
257-
if force:
258-
logging.info(
259-
"You called the program with --force, "
260-
"so it will remove yourself from the owners"
261-
)
262-
else:
263-
continue
277+
else:
278+
continue
264279

265-
# Execute the degradation of the owner
266-
if not dry:
267-
self.org.add_to_members(gh_user, "member")
280+
# Execute the degradation of the owner
281+
if not dry:
282+
self.org.add_to_members(gh_user, "member")
268283

269284
# Update the current organisation owners
270285
self._get_current_org_owners()

gh_org_mgr/manage.py

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ def main():
9494
if args.command == "sync":
9595
if args.dry:
9696
logging.info("Dry-run mode activated, will not make any changes at GitHub")
97+
if args.force:
98+
logging.info("Force mode activated, will make potentially dangerous actions")
9799

98100
org = GHorg()
99101

0 commit comments

Comments
 (0)