From dc19a1fe4b6dd974f238a013e5595f8c3e824381 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 29 Sep 2023 13:44:49 -0700 Subject: [PATCH] /add treats args as literal filenames initially, only glob if they do not exist #195 --- aider/commands.py | 30 ++++++++--------- tests/test_commands.py | 74 ++++++++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 38 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index 9313a50d6..a0aacedbd 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -273,25 +273,21 @@ class Commands: all_matched_files = set() for word in args.split(): + fname = Path(self.coder.root) / word + if fname.exists(): + if fname.is_file(): + all_matched_files.add(str(fname)) + continue + # else we fall through and glob will pickup all files within a dir + matched_files = self.glob_filtered_to_repo(word) + if matched_files: + all_matched_files.update(matched_files) + continue - if not matched_files: - if any(char in word for char in "*?[]"): - self.io.tool_error(f"No files to add matching pattern: {word}") - else: - fname = Path(self.coder.root) / word - if fname.exists(): - if fname.is_file(): - matched_files = [str(fname)] - else: - self.io.tool_error(f"Unable to add: {word}") - elif self.io.confirm_ask( - f"No files matched '{word}'. Do you want to create {fname}?" - ): - fname.touch() - matched_files = [str(fname)] - - all_matched_files.update(matched_files) + if self.io.confirm_ask(f"No files matched '{word}'. Do you want to create {fname}?"): + fname.touch() + all_matched_files.add(str(fname)) for matched_file in all_matched_files: abs_file_path = self.coder.abs_root_path(matched_file) diff --git a/tests/test_commands.py b/tests/test_commands.py index 346d2fa27..025d82010 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -69,8 +69,8 @@ class TestCommands(TestCase): self.assertNotIn(str(Path("test.txt").resolve()), coder.abs_fnames) def test_cmd_add_no_match(self): - # Initialize the Commands and InputOutput objects - io = InputOutput(pretty=False, yes=True) + # yes=False means we will *not* create the file when it is not found + io = InputOutput(pretty=False, yes=False) from aider.coders import Coder coder = Coder.create(models.GPT35, None, io) @@ -82,6 +82,23 @@ class TestCommands(TestCase): # Check if no files have been added to the chat session self.assertEqual(len(coder.abs_fnames), 0) + def test_cmd_add_no_match_but_make_it(self): + # yes=True means we *will* create the file when it is not found + io = InputOutput(pretty=False, yes=True) + from aider.coders import Coder + + coder = Coder.create(models.GPT35, None, io) + commands = Commands(io, coder) + + fname = Path("*.nonexistent") + + # Call the cmd_add method with a non-existent file pattern + commands.cmd_add(str(fname)) + + # Check if no files have been added to the chat session + self.assertEqual(len(coder.abs_fnames), 1) + self.assertTrue(fname.exists()) + def test_cmd_add_drop_directory(self): # Initialize the Commands and InputOutput objects io = InputOutput(pretty=False, yes=False) @@ -255,6 +272,25 @@ class TestCommands(TestCase): self.assertNotIn(filenames[1], coder.abs_fnames) self.assertIn(filenames[2], coder.abs_fnames) + def test_cmd_add_from_subdir_again(self): + with GitTemporaryDirectory(): + io = InputOutput(pretty=False, yes=False) + from aider.coders import Coder + + coder = Coder.create(models.GPT35, None, io) + commands = Commands(io, coder) + + Path("side_dir").mkdir() + os.chdir("side_dir") + + # add a file that is in the side_dir + with open("temp.txt", "w"): + pass + + # this was blowing up with GitCommandError, per: + # https://github.com/paul-gauthier/aider/issues/201 + commands.cmd_add("temp.txt") + def test_cmd_commit(self): with GitTemporaryDirectory(): fname = "test.txt" @@ -277,25 +313,6 @@ class TestCommands(TestCase): commands.cmd_commit(commit_message) self.assertFalse(repo.is_dirty()) - def test_cmd_add_from_sub_dir(self): - with GitTemporaryDirectory(): - io = InputOutput(pretty=False, yes=False) - from aider.coders import Coder - - coder = Coder.create(models.GPT35, None, io) - commands = Commands(io, coder) - - Path("side_dir").mkdir() - os.chdir("side_dir") - - # add a file that is in the side_dir - with open("temp.txt", "w"): - pass - - # this was blowing up with GitCommandError, per: - # https://github.com/paul-gauthier/aider/issues/201 - commands.cmd_add("temp.txt") - def test_cmd_add_from_outside_root(self): with ChdirTemporaryDirectory() as tmp_dname: root = Path("root") @@ -340,3 +357,18 @@ class TestCommands(TestCase): commands.cmd_add("../outside.txt") self.assertEqual(len(coder.abs_fnames), 0) + + def test_cmd_add_filename_with_special_chars(self): + with ChdirTemporaryDirectory(): + io = InputOutput(pretty=False, yes=False) + from aider.coders import Coder + + coder = Coder.create(models.GPT35, None, io) + commands = Commands(io, coder) + + fname = Path("with[brackets].txt") + fname.touch() + + commands.cmd_add(str(fname)) + + self.assertIn(str(fname.resolve()), coder.abs_fnames)