Skip to main content
Glama
jolfr

Commit Helper MCP

by jolfr
repository_config.py7.7 kB
""" Repository Configuration Handles repository-specific configuration including Commitizen config files, git configuration, and repository validation. """ import os import json import toml from pathlib import Path from typing import Dict, Any, Optional, List from dataclasses import dataclass, field from ..errors import ( handle_errors, ConfigurationError, RepositoryError, create_success_response, ) @dataclass class RepositoryConfig: """Repository-specific configuration.""" repo_path: Path commitizen_config: Dict[str, Any] = field(default_factory=dict) git_config: Dict[str, Any] = field(default_factory=dict) is_valid_repo: bool = field(default=False) config_file_path: Optional[Path] = field(default=None) def __post_init__(self): """Initialize repository configuration.""" self.repo_path = Path(self.repo_path).resolve() self._detect_repository() self._load_commitizen_config() self._load_git_config() @handle_errors(log_errors=True) def _detect_repository(self): """Detect if path is a valid git repository.""" git_dir = self.repo_path / ".git" self.is_valid_repo = git_dir.exists() and ( git_dir.is_dir() or git_dir.is_file() ) @handle_errors(log_errors=True) def _load_commitizen_config(self): """Load Commitizen configuration from various sources.""" config_files = ["pyproject.toml", ".cz.toml", ".cz.json", "setup.cfg"] for config_file in config_files: config_path = self.repo_path / config_file if config_path.exists(): try: config = self._parse_config_file(config_path) if config: self.commitizen_config = config self.config_file_path = config_path break except Exception as e: # Continue to next file pass @handle_errors(log_errors=True) def _parse_config_file(self, config_path: Path) -> Optional[Dict[str, Any]]: """Parse configuration file based on extension.""" if config_path.suffix == ".toml": return self._parse_toml_config(config_path) elif config_path.suffix == ".json": return self._parse_json_config(config_path) elif config_path.name == "setup.cfg": return self._parse_setup_cfg(config_path) return None @handle_errors(log_errors=True) def _parse_toml_config(self, config_path: Path) -> Optional[Dict[str, Any]]: """Parse TOML configuration file.""" try: data = toml.load(config_path) # Check for commitizen config in pyproject.toml if "tool" in data and "commitizen" in data["tool"]: return data["tool"]["commitizen"] # Check for direct commitizen config in .cz.toml if "commitizen" in data: return data["commitizen"] # Return root level for .cz.toml files return data except Exception as e: raise ConfigurationError( f"Failed to parse TOML config file: {config_path}", config_file=str(config_path), cause=e, ) @handle_errors(log_errors=True) def _parse_json_config(self, config_path: Path) -> Optional[Dict[str, Any]]: """Parse JSON configuration file.""" try: with open(config_path, "r") as f: return json.load(f) except Exception as e: raise ConfigurationError( f"Failed to parse JSON config file: {config_path}", config_file=str(config_path), cause=e, ) @handle_errors(log_errors=True) def _parse_setup_cfg(self, config_path: Path) -> Optional[Dict[str, Any]]: """Parse setup.cfg configuration file.""" try: import configparser config = configparser.ConfigParser() config.read(config_path) if "tool:commitizen" in config: return dict(config["tool:commitizen"]) except Exception as e: raise ConfigurationError( f"Failed to parse setup.cfg file: {config_path}", config_file=str(config_path), cause=e, ) return None @handle_errors(log_errors=True) def _load_git_config(self): """Load git configuration if available.""" if not self.is_valid_repo: return try: # Try to load git config using GitPython if available from git import Repo repo = Repo(self.repo_path) config_reader = repo.config_reader() self.git_config = { "user_name": config_reader.get_value("user", "name", fallback=""), "user_email": config_reader.get_value("user", "email", fallback=""), "core_editor": config_reader.get_value("core", "editor", fallback=""), } except Exception as e: # Fallback to basic git config detection self.git_config = {} raise RepositoryError( f"Failed to load git configuration for repository: {self.repo_path}", repo_path=str(self.repo_path), cause=e, ) @handle_errors(log_errors=True) def get_commitizen_setting(self, key: str, default: Any = None) -> Any: """Get specific Commitizen setting.""" return self.commitizen_config.get(key, default) @handle_errors(log_errors=True) def get_plugin_name(self) -> str: """Get configured plugin name.""" return self.get_commitizen_setting("name", "cz_conventional_commits") @handle_errors(log_errors=True) def get_version_scheme(self) -> str: """Get version scheme.""" return self.get_commitizen_setting("version_scheme", "semver") @handle_errors(log_errors=True) def get_tag_format(self) -> str: """Get tag format.""" return self.get_commitizen_setting("tag_format", "v$version") @handle_errors(log_errors=True) def validate_configuration(self) -> List[str]: """Validate repository configuration and return issues.""" issues = [] if not self.is_valid_repo: issues.append("Not a valid git repository") if not self.commitizen_config: issues.append("No Commitizen configuration found") if not self.git_config.get("user_name"): issues.append("Git user.name not configured") if not self.git_config.get("user_email"): issues.append("Git user.email not configured") return issues @handle_errors(log_errors=True) def to_dict(self) -> Dict[str, Any]: """Convert to dictionary representation.""" return create_success_response( { "repo_path": str(self.repo_path), "commitizen_config": self.commitizen_config, "git_config": self.git_config, "is_valid_repo": self.is_valid_repo, "config_file_path": str(self.config_file_path) if self.config_file_path else None, } ) @handle_errors(log_errors=True) def load_repository_config(repo_path: str) -> RepositoryConfig: """Load configuration for a specific repository.""" if not repo_path: raise RepositoryError("Repository path cannot be empty", repo_path=repo_path) return RepositoryConfig(repo_path=repo_path)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jolfr/commit-helper-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server