From 6a18cc19d994a26b5b67883facc607d9a4d3d634 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 16:59:22 +0000 Subject: [PATCH] fix: Add Gitea Actions CI workflow and fix linting issues --- src/config.py | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/config.py diff --git a/src/config.py b/src/config.py new file mode 100644 index 0000000..f41279f --- /dev/null +++ b/src/config.py @@ -0,0 +1,124 @@ +"""Configuration management for local-commit-message-generator.""" + +from pathlib import Path +from typing import Any, Dict, Optional + +import tomlkit + + +class ConfigError(Exception): + """Raised when configuration errors occur.""" + pass + + +DEFAULT_TYPE_RULES: Dict[str, list[str]] = { + "feat": ["src/", "lib/", "app/", "controllers/", "models/"], + "fix": ["src/", "lib/", "bug", "fix", "issue", "hotfix"], + "docs": [".md", ".rst", "docs/", "documentation/"], + "style": [".css", ".scss", ".sass", ".less", "styles/"], + "refactor": ["refactor/", "rewrite/", "restructure/"], + "test": ["test/", "tests/", "__tests__/", ".test.", ".spec."], + "chore": ["package.json", "pyproject.toml", "requirements", ".gitignore", "Makefile"], + "perf": ["performance/", "perf/", "optimize/", "optimization/"], + "ci": [".github/", ".gitlab-ci.yml", ".travis.yml", "Jenkinsfile", "tox.ini"], + "build": ["build/", "webpack/", "vite.config", "babel.config", "rollup.config"], +} + +DEFAULT_CONFIG: Dict[str, Any] = { + "type_rules": DEFAULT_TYPE_RULES, + "template": "{type}{scope}: {description}", + "scopes": {}, + "description_length": 72, + "max_files": 5, + "include_file_list": True, + "file_list_template": "\n\nFiles changed:\n{files}", +} + + +def get_config_path() -> Path: + """Get the path to the user configuration file.""" + home = Path.home() + return home / ".local_commit_gen.toml" + + +def load_config(config_path: Optional[Path] = None) -> Dict[str, Any]: + """Load configuration from file. + + Args: + config_path: Optional path to config file. If not provided, uses default path. + + Returns: + Dictionary containing configuration. + """ + if config_path is None: + config_path = get_config_path() + + if not config_path.exists(): + return DEFAULT_CONFIG.copy() + + try: + with open(config_path, "r") as f: + config = tomlkit.parse(f.read()) + except tomlkit.exceptions.ParseError as e: + raise ConfigError(f"Invalid TOML syntax in config file: {e}") + + merged = DEFAULT_CONFIG.copy() + for key, value in config.items(): + if key == "type_rules" and isinstance(value, dict): + merged["type_rules"] = {**DEFAULT_TYPE_RULES, **value} + else: + merged[key] = value + + return merged + + +def save_config(config: Dict[str, Any], config_path: Optional[Path] = None) -> None: + """Save configuration to file. + + Args: + config: Configuration dictionary to save. + config_path: Optional path to config file. If not provided, uses default path. + """ + if config_path is None: + config_path = get_config_path() + + try: + with open(config_path, "w") as f: + tomlkit.dump(config, f) + except OSError as e: + raise ConfigError(f"Failed to write config file: {e}") + + +def ensure_config_exists() -> None: + """Ensure default config file exists.""" + config_path = get_config_path() + if not config_path.exists(): + save_config(DEFAULT_CONFIG.copy()) + + +def get_type_rules(config: Optional[Dict[str, Any]] = None) -> Dict[str, list[str]]: + """Get type rules from configuration. + + Args: + config: Optional configuration dictionary. If not provided, loads from file. + + Returns: + Dictionary mapping commit types to patterns. + """ + if config is None: + config = load_config() + return config.get("type_rules", DEFAULT_TYPE_RULES) + + +def get_template(config: Optional[Dict[str, Any]] = None) -> str: + """Get message template from configuration. + + Args: + config: Optional configuration dictionary. If not provided, loads from file. + + Returns: + Message template string. + """ + if config is None: + config = load_config() + return config.get("template", DEFAULT_CONFIG["template"])