Initial upload: gitignore-cli-generator v1.0.0
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / type-check (push) Has been cancelled
CI / build (push) Has been cancelled
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / type-check (push) Has been cancelled
CI / build (push) Has been cancelled
This commit is contained in:
130
src/gitignore_cli/custom_patterns.py
Normal file
130
src/gitignore_cli/custom_patterns.py
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
"""Custom patterns module for managing user-defined ignore patterns."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
|
CUSTOM_PATTERNS_FILE = Path.home() / ".config" / "gitignore-cli" / "custom_patterns.yaml"
|
||||||
|
|
||||||
|
|
||||||
|
class CustomPattern:
|
||||||
|
"""Represents a custom pattern with metadata."""
|
||||||
|
|
||||||
|
def __init__(self, pattern: str, description: str = "", enabled: bool = True):
|
||||||
|
self.pattern = pattern
|
||||||
|
self.description = description
|
||||||
|
self.enabled = enabled
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"CustomPattern(pattern={self.pattern!r}, enabled={self.enabled})"
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"pattern": self.pattern,
|
||||||
|
"description": self.description,
|
||||||
|
"enabled": self.enabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: dict) -> "CustomPattern":
|
||||||
|
return cls(
|
||||||
|
pattern=data.get("pattern", ""),
|
||||||
|
description=data.get("description", ""),
|
||||||
|
enabled=data.get("enabled", True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomPatternManager:
|
||||||
|
"""Manages user-defined custom patterns."""
|
||||||
|
|
||||||
|
def __init__(self, patterns_file: Optional[Path] = None):
|
||||||
|
self.patterns_file = patterns_file or CUSTOM_PATTERNS_FILE
|
||||||
|
self._patterns: List[CustomPattern] = []
|
||||||
|
self._load_patterns()
|
||||||
|
|
||||||
|
def _load_patterns(self) -> None:
|
||||||
|
"""Load custom patterns from the storage file."""
|
||||||
|
self._patterns = []
|
||||||
|
|
||||||
|
if self.patterns_file.exists():
|
||||||
|
try:
|
||||||
|
with open(self.patterns_file, "r", encoding="utf-8") as f:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
if data and "patterns" in data:
|
||||||
|
for pattern_data in data["patterns"]:
|
||||||
|
self._patterns.append(CustomPattern.from_dict(pattern_data))
|
||||||
|
except (yaml.YAMLError, OSError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _save_patterns(self) -> None:
|
||||||
|
"""Save custom patterns to the storage file."""
|
||||||
|
self.patterns_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"version": "1.0",
|
||||||
|
"patterns": [p.to_dict() for p in self._patterns],
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(self.patterns_file, "w", encoding="utf-8") as f:
|
||||||
|
yaml.dump(data, f, default_flow_style=False)
|
||||||
|
|
||||||
|
def add_pattern(self, pattern: str, description: str = "") -> bool:
|
||||||
|
"""Add a new custom pattern."""
|
||||||
|
for existing in self._patterns:
|
||||||
|
if existing.pattern == pattern:
|
||||||
|
return False
|
||||||
|
|
||||||
|
new_pattern = CustomPattern(pattern=pattern, description=description)
|
||||||
|
self._patterns.append(new_pattern)
|
||||||
|
self._save_patterns()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def remove_pattern(self, pattern: str) -> bool:
|
||||||
|
"""Remove a custom pattern by its pattern string."""
|
||||||
|
for i, existing in enumerate(self._patterns):
|
||||||
|
if existing.pattern == pattern:
|
||||||
|
del self._patterns[i]
|
||||||
|
self._save_patterns()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def list_patterns(self, include_disabled: bool = False) -> List[CustomPattern]:
|
||||||
|
"""List all custom patterns."""
|
||||||
|
if include_disabled:
|
||||||
|
return list(self._patterns)
|
||||||
|
return [p for p in self._patterns if p.enabled]
|
||||||
|
|
||||||
|
def get_enabled_patterns(self) -> List[str]:
|
||||||
|
"""Get list of enabled pattern strings."""
|
||||||
|
return [p.pattern for p in self._patterns if p.enabled]
|
||||||
|
|
||||||
|
def toggle_pattern(self, pattern: str) -> Optional[bool]:
|
||||||
|
"""Toggle the enabled state of a pattern."""
|
||||||
|
for existing in self._patterns:
|
||||||
|
if existing.pattern == pattern:
|
||||||
|
existing.enabled = not existing.enabled
|
||||||
|
self._save_patterns()
|
||||||
|
return existing.enabled
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_patterns_content(self) -> str:
|
||||||
|
"""Get the content string for all enabled patterns."""
|
||||||
|
patterns = self.get_enabled_patterns()
|
||||||
|
if not patterns:
|
||||||
|
return ""
|
||||||
|
return "\n".join(patterns) + "\n"
|
||||||
|
|
||||||
|
def count(self) -> int:
|
||||||
|
"""Return the total number of patterns."""
|
||||||
|
return len(self._patterns)
|
||||||
|
|
||||||
|
def count_enabled(self) -> int:
|
||||||
|
"""Return the number of enabled patterns."""
|
||||||
|
return len(self.get_enabled_patterns())
|
||||||
|
|
||||||
|
|
||||||
|
def get_custom_patterns_manager() -> CustomPatternManager:
|
||||||
|
"""Get the global custom pattern manager instance."""
|
||||||
|
return CustomPatternManager()
|
||||||
Reference in New Issue
Block a user