From 2242140dcd46aa7b599e287587331d734cd53a8a Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Thu, 5 Mar 2026 00:32:03 -0600 Subject: [PATCH] refactor: extract duplicate command hash logic into _compute_command_hash (#31) Both _should_sync_commands and _save_command_hash contained an identical ~35-line block building the command data list and computing the SHA-256 hash. Extracted into a new synchronous helper method _compute_command_hash() that both callers now delegate to. Co-Authored-By: Claude Sonnet 4.6 --- bot.py | 104 ++++++++++++++++++++------------------------------------- 1 file changed, 37 insertions(+), 67 deletions(-) diff --git a/bot.py b/bot.py index ca1c07e..10e5bd0 100644 --- a/bot.py +++ b/bot.py @@ -220,43 +220,45 @@ class SBABot(commands.Bot): f"❌ Failed to initialize background tasks: {e}", exc_info=True ) + def _compute_command_hash(self) -> str: + """Compute a hash of the current command tree for change detection.""" + commands_data = [] + for cmd in self.tree.get_commands(): + # Handle different command types properly + cmd_dict = {} + cmd_dict["name"] = cmd.name + cmd_dict["type"] = type(cmd).__name__ + + # Add description if available (most command types have this) + if hasattr(cmd, "description"): + cmd_dict["description"] = cmd.description # type: ignore + + # Add parameters for Command objects + if isinstance(cmd, discord.app_commands.Command): + cmd_dict["parameters"] = [ + { + "name": param.name, + "description": param.description, + "required": param.required, + "type": str(param.type), + } + for param in cmd.parameters + ] + elif isinstance(cmd, discord.app_commands.Group): + # For groups, include subcommands + cmd_dict["subcommands"] = [subcmd.name for subcmd in cmd.commands] + + commands_data.append(cmd_dict) + + commands_data.sort(key=lambda x: x["name"]) + return hashlib.sha256( + json.dumps(commands_data, sort_keys=True).encode() + ).hexdigest() + async def _should_sync_commands(self) -> bool: """Check if commands have changed since last sync.""" try: - # Create hash of current command tree - commands_data = [] - for cmd in self.tree.get_commands(): - # Handle different command types properly - cmd_dict = {} - cmd_dict["name"] = cmd.name - cmd_dict["type"] = type(cmd).__name__ - - # Add description if available (most command types have this) - if hasattr(cmd, "description"): - cmd_dict["description"] = cmd.description # type: ignore - - # Add parameters for Command objects - if isinstance(cmd, discord.app_commands.Command): - cmd_dict["parameters"] = [ - { - "name": param.name, - "description": param.description, - "required": param.required, - "type": str(param.type), - } - for param in cmd.parameters - ] - elif isinstance(cmd, discord.app_commands.Group): - # For groups, include subcommands - cmd_dict["subcommands"] = [subcmd.name for subcmd in cmd.commands] - - commands_data.append(cmd_dict) - - # Sort for consistent hashing - commands_data.sort(key=lambda x: x["name"]) - current_hash = hashlib.sha256( - json.dumps(commands_data, sort_keys=True).encode() - ).hexdigest() + current_hash = self._compute_command_hash() # Compare with stored hash hash_file = ".last_command_hash" @@ -276,39 +278,7 @@ class SBABot(commands.Bot): async def _save_command_hash(self): """Save current command hash for future comparison.""" try: - # Create hash of current command tree (same logic as _should_sync_commands) - commands_data = [] - for cmd in self.tree.get_commands(): - # Handle different command types properly - cmd_dict = {} - cmd_dict["name"] = cmd.name - cmd_dict["type"] = type(cmd).__name__ - - # Add description if available (most command types have this) - if hasattr(cmd, "description"): - cmd_dict["description"] = cmd.description # type: ignore - - # Add parameters for Command objects - if isinstance(cmd, discord.app_commands.Command): - cmd_dict["parameters"] = [ - { - "name": param.name, - "description": param.description, - "required": param.required, - "type": str(param.type), - } - for param in cmd.parameters - ] - elif isinstance(cmd, discord.app_commands.Group): - # For groups, include subcommands - cmd_dict["subcommands"] = [subcmd.name for subcmd in cmd.commands] - - commands_data.append(cmd_dict) - - commands_data.sort(key=lambda x: x["name"]) - current_hash = hashlib.sha256( - json.dumps(commands_data, sort_keys=True).encode() - ).hexdigest() + current_hash = self._compute_command_hash() # Save hash to file with open(".last_command_hash", "w") as f: