From 64c50bab48a3e963aafca6601196119bda49fda8 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 24 Jul 2023 17:31:00 -0300 Subject: [PATCH] Accept either a git dname or a list of fnames --- aider/coders/base_coder.py | 8 ++- aider/main.py | 117 +++++++++++++++++++++++++++++-------- aider/repo.py | 11 +++- 3 files changed, 109 insertions(+), 27 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index d4bdcf504..6fc81c8f2 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -98,6 +98,7 @@ class Coder: main_model, io, fnames=None, + git_dname=None, pretty=True, show_diffs=False, auto_commits=True, @@ -155,11 +156,14 @@ class Coder: fname.parent.mkdir(parents=True, exist_ok=True) fname.touch() + if not fname.is_file(): + raise ValueError(f"{fname} is not a file") + self.abs_fnames.add(str(fname.resolve())) if use_git: try: - self.repo = GitRepo(self.io, fnames) + self.repo = GitRepo(self.io, fnames, git_dname) self.root = self.repo.root except FileNotFoundError: self.repo = None @@ -197,7 +201,7 @@ class Coder: self.io.tool_output(f"Added {fname} to the chat.") if self.repo: - self.repo.add_new_files(fnames) + self.repo.add_new_files(fname for fname in fnames if not Path(fname).is_dir()) # validate the functions jsonschema if self.functions: diff --git a/aider/main.py b/aider/main.py index 1eba45db1..f8bcae55b 100644 --- a/aider/main.py +++ b/aider/main.py @@ -9,10 +9,14 @@ import openai from aider import __version__, models from aider.coders import Coder from aider.io import InputOutput +from aider.repo import GitRepo from aider.versioncheck import check_version +from .dump import dump # noqa: F402 + def get_git_root(): + """Try and guess the git repo, since the conf.yml can be at the repo root""" try: repo = git.Repo(search_parent_directories=True) return repo.working_tree_dir @@ -20,6 +24,33 @@ def get_git_root(): return None +def guessed_wrong_repo(io, git_root, fnames, git_dname): + """After we parse the args, we can determine the real repo. Did we guess wrong?""" + + dump(git_root) + + try: + check_repo = Path(GitRepo(io, fnames, git_dname).root).resolve() + except FileNotFoundError: + return + + dump(check_repo) + + # we had no guess, rely on the "true" repo result + if not git_root: + return str(check_repo) + + git_root = Path(git_root).resolve() + if check_repo == git_root: + return + + print("guessed the wrong repo") + dump(check_repo) + dump(git_root) + + return str(check_repo) + + def setup_git(git_root, io): if git_root: return git_root @@ -71,11 +102,14 @@ def check_gitignore(git_root, io, ask=True): io.tool_output(f"Added {pat} to .gitignore") -def main(args=None, input=None, output=None): - if args is None: - args = sys.argv[1:] +def main(argv=None, input=None, output=None, force_git_root=None): + if argv is None: + argv = sys.argv[1:] - git_root = get_git_root() + if force_git_root: + git_root = force_git_root + else: + git_root = get_git_root() conf_fname = Path(".aider.conf.yml") @@ -344,7 +378,7 @@ def main(args=None, input=None, output=None): ), ) - args = parser.parse_args(args) + args = parser.parse_args(argv) if args.dark_mode: args.user_input_color = "#32FF32" @@ -371,6 +405,38 @@ def main(args=None, input=None, output=None): dry_run=args.dry_run, ) + fnames = args.files + if len(args.files) > 1: + good = True + for fname in args.files: + if Path(fname).is_dir(): + io.tool_error(f"{fname} is a directory, not provided alone.") + good = False + if not good: + io.tool_error( + "Provide either a single directory of a git repo, or a list of one or more files." + ) + return 1 + + git_dname = None + if len(args.files) == 1: + if Path(args.files[0]).is_dir(): + if args.git: + git_dname = args.files[0] + fnames = [] + else: + io.tool_error(f"{args.files[0]} is a directory, but --no-git selected.") + return -1 + + # We can't know the git repo for sure until after parsing the args. + # If we guessed wrong, reparse because that changes things like + # the location of the config.yml and history files. + if args.git and not force_git_root: + right_repo_root = guessed_wrong_repo(io, git_root, fnames, git_dname) + if right_repo_root: + print("guessed wrong") + return main(argv, input, output, right_repo_root) + io.tool_output(f"Aider v{__version__}") check_version(io.tool_error) @@ -418,24 +484,29 @@ def main(args=None, input=None, output=None): setattr(openai, mod_key, val) io.tool_output(f"Setting openai.{mod_key}={val}") - coder = Coder.create( - main_model, - args.edit_format, - io, - ## - fnames=args.files, - pretty=args.pretty, - show_diffs=args.show_diffs, - auto_commits=args.auto_commits, - dirty_commits=args.dirty_commits, - dry_run=args.dry_run, - map_tokens=args.map_tokens, - verbose=args.verbose, - assistant_output_color=args.assistant_output_color, - code_theme=args.code_theme, - stream=args.stream, - use_git=args.git, - ) + try: + coder = Coder.create( + main_model, + args.edit_format, + io, + ## + fnames=fnames, + git_dname=git_dname, + pretty=args.pretty, + show_diffs=args.show_diffs, + auto_commits=args.auto_commits, + dirty_commits=args.dirty_commits, + dry_run=args.dry_run, + map_tokens=args.map_tokens, + verbose=args.verbose, + assistant_output_color=args.assistant_output_color, + code_theme=args.code_theme, + stream=args.stream, + use_git=args.git, + ) + except ValueError as err: + io.tool_error(str(err)) + return if args.show_repo_map: repo_map = coder.get_repo_map() diff --git a/aider/repo.py b/aider/repo.py index 473234c20..16bcc45e4 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -12,10 +12,12 @@ from .dump import dump # noqa: F401 class GitRepo: repo = None - def __init__(self, io, fnames): + def __init__(self, io, fnames, git_dname): self.io = io - if fnames: + if git_dname: + check_fnames = [git_dname] + elif fnames: check_fnames = fnames else: check_fnames = ["."] @@ -25,6 +27,9 @@ class GitRepo: fname = Path(fname) fname = fname.resolve() + if not fname.exists() and fname.parent.exists(): + fname = fname.parent + try: repo_path = git.Repo(fname, search_parent_directories=True).working_dir repo_path = utils.safe_abs_path(repo_path) @@ -49,6 +54,8 @@ class GitRepo: for fname in fnames: if Path(fname).resolve() in cur_files: continue + if not Path(fname).exists(): + continue self.io.tool_output(f"Adding {fname} to git") self.repo.git.add(fname)