Initial upload: Local Commit Message Generator v0.1.0
This commit is contained in:
125
app/local_commit_message_generator/src/config.py
Normal file
125
app/local_commit_message_generator/src/config.py
Normal file
@@ -0,0 +1,125 @@
|
||||
"""Configuration management for local-commit-message-generator."""
|
||||
|
||||
import os
|
||||
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"])
|
||||
Reference in New Issue
Block a user