Library for managing git hooks using pyproject.toml configuration with an extensible plugin system
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core API for developing autohooks plugins, providing configuration access, progress reporting, and terminal output utilities. This API enables plugins to integrate seamlessly with autohooks' execution framework.
Access to hierarchical configuration from pyproject.toml with convenient key-based navigation and value retrieval.
class Config:
"""
Config helper class for easier access to a tree of settings.
"""
def __init__(self, config_dict: Optional[Dict[str, Any]] = None) -> None:
"""
Create a new Config from a dictionary.
Args:
config_dict: Dictionary to be used for the Config
"""
def get(self, *keys: str) -> 'Config':
"""
Get a sub-config. If a sub-config with the passed keys does not exist,
an empty Config is returned.
Args:
*keys: Variable length of keys to resolve
Returns:
Sub-config for the specified key path
"""
def get_value(self, key: str, default: Any = None) -> Any:
"""
Get a config value.
Args:
key: Key to lookup in the config
default: Value to return if key is not in the config
Returns:
Configuration value or default
"""
def is_empty(self) -> bool:
"""
Returns True if the config has no data.
"""
def has_key(self, key: str) -> bool:
"""
Returns True if the key is in the config.
"""Usage Examples:
from autohooks.api import Config
def precommit(config: Config, report_progress, **kwargs):
# Access plugin-specific configuration
plugin_config = config.get("tool", "autohooks", "plugins", "my-plugin")
# Get configuration values with defaults
max_line_length = plugin_config.get_value("max-line-length", 88)
exclude_patterns = plugin_config.get_value("exclude", [])
# Check if configuration exists
if plugin_config.is_empty():
# Use default settings
passProgress reporting interface for providing user feedback during plugin execution with initialization and update capabilities.
class ReportProgress:
"""
A class to report progress of a plugin.
"""
def __init__(self, progress: Progress, task_id: int) -> None:
"""
Create progress reporter.
Args:
progress: Rich progress instance
task_id: Task identifier for this progress
"""
def init(self, total: int) -> None:
"""
Init the progress with the total number to process.
Args:
total: Most of the time this should be the number of files to process
"""
def update(self, advance: int = 1) -> None:
"""
Update the number of already processed steps/items/files.
This increases the progress indicator.
Args:
advance: Number of steps/items/files the progress advanced. Default: 1
"""Usage Examples:
from autohooks.api import ReportProgress
from autohooks.api.git import get_staged_status
def precommit(config, report_progress: ReportProgress, **kwargs):
# Get files to process
files = get_staged_status()
# Initialize progress with total count
report_progress.init(len(files))
# Process each file
for file_entry in files:
process_file(file_entry.absolute_path())
# Update progress
report_progress.update()
return 0Terminal output functions for consistent messaging and user feedback with different severity levels.
def error(message: str) -> None:
"""
Highlight message as an error in the terminal.
Args:
message: Message to print
"""
def fail(message: str) -> None:
"""
Highlight message as a failure in the terminal.
Args:
message: Message to print
"""
def info(message: str) -> None:
"""
Highlight message as an information in the terminal.
Args:
message: Message to print
"""
def bold_info(message: str) -> None:
"""
Highlight message as a strong information in the terminal.
Args:
message: Message to print
"""
def ok(message: str) -> None:
"""
Highlight message as a success/ok in the terminal.
Args:
message: Message to print
"""
def out(message: str):
"""
Print message to the terminal without highlighting.
Args:
message: Message to print
"""
def warning(message: str) -> None:
"""
Highlight message as a warning in the terminal.
Args:
message: Message to print
"""Usage Examples:
from autohooks.api import error, info, ok, warning
def precommit(config, report_progress, **kwargs):
info("Starting code formatting...")
try:
# Process files
result = format_files()
if result.errors:
for error_msg in result.errors:
error(f"Formatting error: {error_msg}")
return 1
elif result.warnings:
for warning_msg in result.warnings:
warning(f"Formatting warning: {warning_msg}")
ok(f"Successfully formatted {result.file_count} files")
return 0
except Exception as e:
error(f"Plugin execution failed: {e}")
return 1Every autohooks plugin must implement a precommit function with the following signature:
def precommit(config: Config, report_progress: ReportProgress, **kwargs):
"""
Main plugin entry point called during pre-commit hook execution.
Args:
config: Configuration object for accessing plugin settings
report_progress: Progress reporting interface for user feedback
**kwargs: Additional arguments for future compatibility
Returns:
int: 0 for success, non-zero for failure (stops commit process)
"""from autohooks.api import Config, ReportProgress, error, info, ok
from autohooks.api.git import get_staged_status
from autohooks.api.path import is_python_path
def precommit(config: Config, report_progress: ReportProgress, **kwargs):
"""Example plugin that processes Python files."""
# Get staged files
status_entries = get_staged_status()
python_files = [entry for entry in status_entries
if is_python_path(entry.path)]
if not python_files:
info("No Python files to process")
return 0
# Initialize progress
report_progress.init(len(python_files))
# Get plugin configuration
plugin_config = config.get("tool", "my-plugin")
strict_mode = plugin_config.get_value("strict", False)
errors = 0
# Process each file
for file_entry in python_files:
try:
process_python_file(file_entry.absolute_path(), strict_mode)
report_progress.update()
except ProcessingError as e:
error(f"Error processing {file_entry.path}: {e}")
errors += 1
if errors:
error(f"Processing failed for {errors} files")
return 1
ok(f"Successfully processed {len(python_files)} Python files")
return 0from typing import Any, Dict, Optional
from rich.progress import ProgressInstall with Tessl CLI
npx tessl i tessl/pypi-autohooks