diff --git a/aider/watch.py b/aider/watch.py index 8ffea6fe3..bec632e11 100644 --- a/aider/watch.py +++ b/aider/watch.py @@ -1,7 +1,9 @@ from pathlib import Path -from typing import Set +from typing import Set, Optional from watchfiles import watch +from pathspec import PathSpec +from pathspec.patterns import GitWildMatchPattern def is_source_file(path: Path) -> bool: @@ -40,16 +42,37 @@ def is_source_file(path: Path) -> bool: return path.suffix.lower() in COMMENT_STYLE_EXTENSIONS -def watch_source_files(directory: str) -> Set[str]: +def load_gitignore(gitignore_path: Path) -> Optional[PathSpec]: + """Load and parse a .gitignore file""" + if not gitignore_path.exists(): + return None + + with open(gitignore_path) as f: + patterns = f.readlines() + + return PathSpec.from_lines(GitWildMatchPattern, patterns) + +def watch_source_files(directory: str, gitignore: str = None) -> Set[str]: """ Watch for changes to source files in the given directory and its subdirectories. Returns a set of changed file paths whenever changes are detected. + + Args: + directory: Root directory to watch + gitignore: Path to .gitignore file (optional) """ root = Path(directory) + gitignore_spec = None + + if gitignore: + gitignore_spec = load_gitignore(Path(gitignore)) - # Create a filter function that only accepts source files + # Create a filter function that only accepts source files and respects gitignore def filter_func(change_type, path): - return is_source_file(Path(path)) + path_obj = Path(path) + if gitignore_spec and gitignore_spec.match_file(str(path_obj.relative_to(root))): + return False + return is_source_file(path_obj) # Watch the directory for changes for changes in watch(root, watch_filter=filter_func): @@ -61,16 +84,18 @@ def watch_source_files(directory: str) -> Set[str]: def main(): """Example usage of the file watcher""" import sys + import argparse + + parser = argparse.ArgumentParser(description="Watch source files for changes") + parser.add_argument("directory", help="Directory to watch") + parser.add_argument("--gitignore", help="Path to .gitignore file") + args = parser.parse_args() - if len(sys.argv) != 2: - print("Usage: python watch.py ") - sys.exit(1) - - directory = sys.argv[1] + directory = args.directory print(f"Watching source files in {directory}...") try: - for changed_files in watch_source_files(directory): + for changed_files in watch_source_files(directory, args.gitignore): print("\nChanged files:") for file in sorted(changed_files): print(f" {file}")