Add utils, templates, config, interactive, and github modules
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-02-05 08:45:43 +00:00
parent 8fea9ced0c
commit 413d038e9a

View File

@@ -0,0 +1,183 @@
"""Configuration file support for the Auto README Generator."""
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional
import yaml
import sys
if sys.version_info >= (3, 11):
import tomllib
else:
try:
import tomli as tomllib
except ImportError:
tomllib = None
@dataclass
class ReadmeConfig:
"""Configuration for README generation."""
project_name: Optional[str] = None
description: Optional[str] = None
template: str = "base"
interactive: bool = False
sections: dict = field(default_factory=dict)
output_filename: str = "README.md"
custom_fields: dict = field(default_factory=dict)
class ConfigLoader:
"""Loads and validates configuration files."""
CONFIG_FILES = [".readmerc", ".readmerc.yaml", ".readmerc.yml", "readme.config.yaml"]
@classmethod
def find_config(cls, directory: Path) -> Optional[Path]:
"""Find a configuration file in the directory."""
for config_name in cls.CONFIG_FILES:
config_path = directory / config_name
if config_path.exists():
return config_path
return None
@classmethod
def load(cls, path: Path) -> ReadmeConfig:
"""Load configuration from a file."""
if not path.exists():
return ReadmeConfig()
config = ReadmeConfig()
if path.suffix in (".yaml", ".yml"):
config = cls._load_yaml(path, config)
elif path.suffix == ".toml":
config = cls._load_toml(path, config)
return config
@classmethod
def _load_yaml(cls, path: Path, config: ReadmeConfig) -> ReadmeConfig:
"""Load configuration from YAML file."""
try:
with open(path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f) or {}
except yaml.YAMLError as e:
raise ValueError(f"Invalid YAML in config file: {e}")
if not isinstance(data, dict):
raise ValueError("Config file must contain a dictionary")
if "project_name" in data:
config.project_name = data["project_name"]
if "description" in data:
config.description = data["description"]
if "template" in data:
config.template = data["template"]
if "interactive" in data:
config.interactive = data["interactive"]
if "filename" in data:
config.output_filename = data["filename"]
if "sections" in data:
config.sections = data["sections"]
if "custom_fields" in data:
config.custom_fields = data["custom_fields"]
return config
@classmethod
def _load_toml(cls, path: Path, config: ReadmeConfig) -> ReadmeConfig:
"""Load configuration from TOML file."""
if tomllib is None:
raise ValueError("TOML support requires Python 3.11+ or tomli package")
try:
with open(path, "rb") as f:
data = tomllib.load(f)
except Exception as e:
raise ValueError(f"Invalid TOML in config file: {e}")
if "auto-readme" in data:
auto_readme = data["auto-readme"]
if "filename" in auto_readme:
config.output_filename = auto_readme["filename"]
if "sections" in auto_readme:
config.sections = auto_readme["sections"]
return config
class ConfigValidator:
"""Validates configuration files."""
VALID_TEMPLATES = ["base", "minimal", "detailed"]
VALID_SECTIONS = [
"title",
"description",
"badges",
"table_of_contents",
"overview",
"installation",
"usage",
"features",
"api",
"contributing",
"license",
]
@classmethod
def validate(cls, config: ReadmeConfig) -> list[str]:
"""Validate a configuration and return any errors."""
errors = []
if config.template and config.template not in cls.VALID_TEMPLATES:
errors.append(f"Invalid template: {config.template}. Valid options: {cls.VALID_TEMPLATES}")
if config.sections:
if "order" in config.sections:
for section in config.sections["order"]:
if section not in cls.VALID_SECTIONS:
errors.append(f"Invalid section in order: {section}")
return errors
@classmethod
def generate_template(cls) -> str:
"""Generate a template configuration file."""
template = """# Auto README Configuration File
# https://github.com/yourusername/yourrepo
# Project metadata
project_name: "My Project"
description: "A brief description of your project"
# Template to use
template: "base"
# Interactive mode
interactive: false
# Output filename
filename: "README.md"
# Section configuration
sections:
order:
- title
- description
- overview
- installation
- usage
- features
- api
- contributing
- license
optional:
Contributing: false
# Custom fields to include
custom_fields:
author: "Your Name"
email: "your.email@example.com"
"""
return template