From 90df92bffaca2817a3c4717c364ae82d92ca2fab Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 14 Jul 2023 20:05:11 -0700 Subject: [PATCH 01/16] aider: Add .aider* to .gitignore if it is not already present. # Aider chat conversation: USER: do the TODO ASSISTANT: To complete the TODO task in the `aider/main.py` file, we need to check if `.aider*` is in `.gitignore`, and if not, add it. Here are the steps to do this: 1. Open the `.gitignore` file in the root directory of the git repository. 2. Read the contents of the file. 3. Check if `.aider*` is present in the file. 4. If not, append `.aider*` to the file and save it. However, the code in `aider/main.py` does not currently have the ability to modify files. We need to add a function to handle this. Here is the proposed change: ```python aider/main.py <<<<<<< ORIGINAL if git_root: # TODO: check if .aider* is in .gitignore, add it if not pass ======= if git_root: gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): with open(gitignore_file, "r") as file: content = file.read() if ".aider*" not in content: with open(gitignore_file, "a") as file: file.write("\n.aider*") else: with open(gitignore_file, "w") as file: file.write(".aider*") >>>>>>> UPDATED ``` This code will open the `.gitignore` file in the git root directory, check if `.aider*` is present, and if not, append it to the file. If the `.gitignore` file does not exist, it will create one and add `.aider*` to it. --- aider/main.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/aider/main.py b/aider/main.py index c7364dc84..5a4fef84c 100644 --- a/aider/main.py +++ b/aider/main.py @@ -337,6 +337,19 @@ def main(args=None, input=None, output=None): 'Update git email with: git config --global user.email "you@example.com"' ) io.tool_output("Git repository created in the current working directory.") + git_root = str(Path.cwd().resolve()) + + if git_root: + gitignore_file = Path(git_root) / ".gitignore" + if gitignore_file.exists(): + with open(gitignore_file, "r") as file: + content = file.read() + if ".aider*" not in content: + with open(gitignore_file, "a") as file: + file.write("\n.aider*") + else: + with open(gitignore_file, "w") as file: + file.write(".aider*") def scrub_sensitive_info(text): # Replace sensitive information with placeholder From fb444d99544b11f41d9f79c35f0f710aa25c71f3 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 14 Jul 2023 20:06:34 -0700 Subject: [PATCH 02/16] aider: Refactored open calls in `aider/main.py` to use `Path.read_text()` and `Path.write_text()` with `encoding='utf-8'`. # Aider chat conversation: USER: add encoding=utf-8 to all that ASSISTANT: To add the encoding declaration to the `aider/main.py` file, we need to add `# -*- coding: utf-8 -*-` at the top of the file. Here is the proposed change: ^C KeyboardInterrupt USER: add encoding=utf-8 to those open calls ASSISTANT: To specify the encoding as utf-8 in the open calls in the `aider/main.py` file, we need to add `encoding='utf-8'` to each open call. Here are the proposed changes: ```python aider/main.py <<<<<<< ORIGINAL if git_root: gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): with open(gitignore_file, "r") as file: content = file.read() if ".aider*" not in content: with open(gitignore_file, "a") as file: file.write("\n.aider*") else: with open(gitignore ^C KeyboardInterrupt USER: actually use Path.read_text and be sure to encoding=utf-8 ASSISTANT: To use `Path.read_text()` with `encoding='utf-8'` in the `aider/main.py` file, we need to replace the `open()` calls with `Path.read_text()` and `Path.write_text()`. Here are the proposed changes: ```python aider/main.py <<<<<<< ORIGINAL if git_root: gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): with open(gitignore_file, "r") as file: content = file.read() if ".aider*" not in content: with open(gitignore_file, "a") as file: file.write("\n.aider*") else: with open(gitignore_file, "w") as file: file.write(".aider*") ======= if git_root: gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): content = gitignore_file.read_text(encoding='utf-8') if ".aider*" not in content: gitignore_file.write_text("\n.aider*", encoding='utf-8', append=True) else: gitignore_file.write_text(".aider*", encoding='utf-8') >>>>>>> UPDATED ``` This code will open the `.gitignore` file in the git root directory, check if `.aider*` is present, and if not, append it to the file. If the `.gitignore` file does not exist, it will create one and add `.aider*` to it. The encoding is specified as utf-8. --- aider/main.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/aider/main.py b/aider/main.py index 5a4fef84c..0d39b34a1 100644 --- a/aider/main.py +++ b/aider/main.py @@ -342,14 +342,11 @@ def main(args=None, input=None, output=None): if git_root: gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): - with open(gitignore_file, "r") as file: - content = file.read() + content = gitignore_file.read_text(encoding='utf-8') if ".aider*" not in content: - with open(gitignore_file, "a") as file: - file.write("\n.aider*") + gitignore_file.write_text("\n.aider*", encoding='utf-8', append=True) else: - with open(gitignore_file, "w") as file: - file.write(".aider*") + gitignore_file.write_text(".aider*", encoding='utf-8') def scrub_sensitive_info(text): # Replace sensitive information with placeholder From 6f460bd050b1c29fe2bfcceade7fae1f417e8249 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 14 Jul 2023 20:10:10 -0700 Subject: [PATCH 03/16] wip --- aider/main.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/aider/main.py b/aider/main.py index 0d39b34a1..b4332ae30 100644 --- a/aider/main.py +++ b/aider/main.py @@ -340,17 +340,20 @@ def main(args=None, input=None, output=None): git_root = str(Path.cwd().resolve()) if git_root: + updated_ignore = None gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): - content = gitignore_file.read_text(encoding='utf-8') - if ".aider*" not in content: - gitignore_file.write_text("\n.aider*", encoding='utf-8', append=True) + content = gitignore_file.read_text(encoding="utf-8") + if ".aider*" not in content.splitlines(): + updated_ignore = content + "\n.aider.*\n" else: - gitignore_file.write_text(".aider*", encoding='utf-8') + updated_ignore = "aider.*" + if updated_ignore and io.confirm_ask("Add .aider* to .gitignore (recommended)?"): + gitignore_file.write_text("\n.aider*", encoding="utf-8", append=True) def scrub_sensitive_info(text): # Replace sensitive information with placeholder - return text.replace(args.openai_api_key, '***') + return text.replace(args.openai_api_key, "***") if args.verbose: show = scrub_sensitive_info(parser.format_values()) From c08527dbbcec1f7a45fa34c91b5ea942d586cc50 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sat, 15 Jul 2023 13:34:58 -0700 Subject: [PATCH 04/16] refac; added check_gitignore --- aider/main.py | 71 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/aider/main.py b/aider/main.py index b4332ae30..00f303281 100644 --- a/aider/main.py +++ b/aider/main.py @@ -19,6 +19,47 @@ def get_git_root(): return None +def setup_git(git_root, io): + if git_root: + return git_root + + if not io.confirm_ask("No git repo found, create one to track GPT's changes (recommended)?"): + return + + repo = git.Repo.init(os.getcwd()) + global_git_config = git.GitConfigParser([str(Path.home() / ".gitconfig")], read_only=True) + with repo.config_writer() as git_config: + if not global_git_config.has_option("user", "name"): + git_config.set_value("user", "name", "Your Name") + io.tool_error('Update git name with: git config --global user.name "Your Name"') + if not global_git_config.has_option("user", "email"): + git_config.set_value("user", "email", "you@example.com") + io.tool_error('Update git email with: git config --global user.email "you@example.com"') + + io.tool_output("Git repository created in the current working directory.") + git_root = str(Path.cwd().resolve()) + return git_root + + +def check_gitignore(git_root, io): + pat = ".aider*" + + updated_ignore = None + gitignore_file = Path(git_root) / ".gitignore" + if gitignore_file.exists(): + content = gitignore_file.read_text(encoding="utf-8") + if pat in content.splitlines(): + return + else: + content = "" + + if not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): + return + + updated_ignore = content + "\n" + pat + "\n" + gitignore_file.write_text(updated_ignore, encoding="utf-8") + + def main(args=None, input=None, output=None): if args is None: args = sys.argv[1:] @@ -321,35 +362,11 @@ def main(args=None, input=None, output=None): io.tool_output(f"Aider v{__version__}") - if not git_root and args.git: - if io.confirm_ask("No git repo found, create one to track GPT's changes (recommended)?"): - repo = git.Repo.init(os.getcwd()) - global_git_config = git.GitConfigParser( - [str(Path.home() / ".gitconfig")], read_only=True - ) - with repo.config_writer() as git_config: - if not global_git_config.has_option("user", "name"): - git_config.set_value("user", "name", "Your Name") - io.tool_error('Update git name with: git config --global user.name "Your Name"') - if not global_git_config.has_option("user", "email"): - git_config.set_value("user", "email", "you@example.com") - io.tool_error( - 'Update git email with: git config --global user.email "you@example.com"' - ) - io.tool_output("Git repository created in the current working directory.") - git_root = str(Path.cwd().resolve()) + if args.git: + git_root = setup_git(git_root, io) if git_root: - updated_ignore = None - gitignore_file = Path(git_root) / ".gitignore" - if gitignore_file.exists(): - content = gitignore_file.read_text(encoding="utf-8") - if ".aider*" not in content.splitlines(): - updated_ignore = content + "\n.aider.*\n" - else: - updated_ignore = "aider.*" - if updated_ignore and io.confirm_ask("Add .aider* to .gitignore (recommended)?"): - gitignore_file.write_text("\n.aider*", encoding="utf-8", append=True) + check_gitignore(git_root, io) def scrub_sensitive_info(text): # Replace sensitive information with placeholder From b0ec8205f371af7e23bf1fe25fe108a88a634c4c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sat, 15 Jul 2023 13:36:57 -0700 Subject: [PATCH 05/16] Add pattern to .gitignore if user confirms, by appending it to the existing content of the file. # Aider chat conversation: --- aider/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/aider/main.py b/aider/main.py index 00f303281..b7508d4d8 100644 --- a/aider/main.py +++ b/aider/main.py @@ -56,8 +56,10 @@ def check_gitignore(git_root, io): if not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): return - updated_ignore = content + "\n" + pat + "\n" - gitignore_file.write_text(updated_ignore, encoding="utf-8") + if not content.endswith("\n"): + content += "\n" + content += pat + "\n" + gitignore_file.write_text(content, encoding="utf-8") def main(args=None, input=None, output=None): From c8d69f84ce24bc040f818477166dfe2ce411db82 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sat, 15 Jul 2023 13:37:39 -0700 Subject: [PATCH 06/16] aider: Add test for `setup_git` function. # Aider chat conversation: USER: add tests for `setup_git` ASSISTANT: To add tests for the `setup_git` function, we need to modify the `tests/test_main.py` file. We will add a new test function `test_setup_git` in the `TestMain` class. Here is the change: ```python tests/test_main.py <<<<<<< ORIGINAL def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: # --yes will just ok the git repo without blocking on input # following calls to main will see the new repo already main(["--no-auto-commits", "--yes"], input=DummyInput()) _, kwargs = MockCoder.call_args assert kwargs["auto_commits"] is False ======= def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: # --yes will just ok the git repo without blocking on input # following calls to main will see the new repo already main(["--no-auto-commits", "--yes"], input=DummyInput()) _, kwargs = MockCoder.call_args assert kwargs["auto_commits"] is False def test_setup_git(self): with patch("aider.main.git.Repo.init") as MockRepoInit: MockRepoInit.return_value = git.Repo(self.tempdir) git_root = setup_git(None, self.io) self.assertEqual(git_root, self.tempdir) MockRepoInit.assert_called_once_with(self.tempdir) >>>>>>> UPDATED ``` In the new test `test_setup_git`, we are mocking the `git.Repo.init` function to return a git repository at `self.tempdir`. Then we call `setup_git` with `None` as the `git_root` and check if it returns `self.tempdir` as the new `git_root`. We also check if `git.Repo.init` was called once with `self.tempdir` as the argument. --- tests/test_main.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index c8fdf9406..3ebc6869c 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -83,6 +83,13 @@ class TestMain(TestCase): _, kwargs = MockCoder.call_args assert kwargs["auto_commits"] is False + def test_setup_git(self): + with patch("aider.main.git.Repo.init") as MockRepoInit: + MockRepoInit.return_value = git.Repo(self.tempdir) + git_root = setup_git(None, self.io) + self.assertEqual(git_root, self.tempdir) + MockRepoInit.assert_called_once_with(self.tempdir) + with patch("aider.main.Coder.create") as MockCoder: main(["--auto-commits"], input=DummyInput()) _, kwargs = MockCoder.call_args From 50c8a96eddf499268442f0d7b84091dd5f952ee1 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 08:18:05 -0300 Subject: [PATCH 07/16] wip --- tests/test_main.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 3ebc6869c..cc6fa8705 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,10 +6,12 @@ from pathlib import Path from unittest import TestCase from unittest.mock import patch +import git from prompt_toolkit.input import DummyInput from prompt_toolkit.output import DummyOutput from aider.dump import dump # noqa: F401 +from aider.io import InputOutput from aider.main import main @@ -75,6 +77,14 @@ class TestMain(TestCase): # Because aider will try and `git add` a file that's already in the repo. main(["--yes", str(fname)], input=DummyInput(), output=DummyOutput()) + def test_setup_git(self): + io = InputOutput(pretty=False, yes=True) + with patch("aider.main.git.Repo.init") as MockRepoInit: + MockRepoInit.return_value = git.Repo(self.tempdir) + git_root = setup_git(None, self.io) + self.assertEqual(git_root, self.tempdir) + MockRepoInit.assert_called_once_with(self.tempdir) + def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: # --yes will just ok the git repo without blocking on input @@ -83,13 +93,6 @@ class TestMain(TestCase): _, kwargs = MockCoder.call_args assert kwargs["auto_commits"] is False - def test_setup_git(self): - with patch("aider.main.git.Repo.init") as MockRepoInit: - MockRepoInit.return_value = git.Repo(self.tempdir) - git_root = setup_git(None, self.io) - self.assertEqual(git_root, self.tempdir) - MockRepoInit.assert_called_once_with(self.tempdir) - with patch("aider.main.Coder.create") as MockCoder: main(["--auto-commits"], input=DummyInput()) _, kwargs = MockCoder.call_args From 108abe4a49d45686d93d6a71b8506bc66087b1d2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 12:26:31 -0300 Subject: [PATCH 08/16] aider: Replace all `subprocess.run(git` calls that are making new repos and setting config with `make_repo` calls. # Aider chat conversation: USER: replace all the `subprocess.run(git` calls that are making new repos and setting config with `make_repo` calls ASSISTANT: To replace all the `subprocess.run(git` calls that are making new repos and setting config with `make_repo` calls, we need to modify the `tests/test_main.py` file. Here are the changes: ```python tests/test_main.py <<<<<<< ORIGINAL subprocess.run(["git", "init"]) subprocess.run(["git", "config", "user.email", "dummy@example.com"]) subprocess.run(["git", "config", "user.name", "Dummy User"]) ======= from tests.utils import make_repo make_repo() >>>>>>> UPDATED ``` ```python tests/test_main.py <<<<<<< ORIGINAL subprocess.run(["git", "init"]) subprocess.run(["git", "config", "user.email", "dummy@example.com"]) subprocess.run(["git", "config", "user.name", "Dummy User"]) ======= from tests.utils import make_repo make_repo() >>>>>>> UPDATED ``` ```python tests/test_main.py <<<<<<< ORIGINAL subprocess.run(["git", "init"]) subprocess.run(["git", "config", "user.email", "dummy@example.com"]) subprocess.run(["git", "config", "user.name", "Dummy User"]) ======= from tests.utils import make_repo make_repo() >>>>>>> UPDATED ``` Please note that you need to import the `make_repo` function from `tests.utils` in each test where it's used. --- tests/test_main.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index cc6fa8705..41e1717bc 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -38,16 +38,14 @@ class TestMain(TestCase): self.assertTrue(os.path.exists("foo.txt")) def test_main_with_empty_git_dir_new_file(self): - subprocess.run(["git", "init"]) - subprocess.run(["git", "config", "user.email", "dummy@example.com"]) - subprocess.run(["git", "config", "user.name", "Dummy User"]) + from tests.utils import make_repo + make_repo() main(["--yes", "foo.txt"], input=DummyInput(), output=DummyOutput()) self.assertTrue(os.path.exists("foo.txt")) def test_main_with_git_config_yml(self): - subprocess.run(["git", "init"]) - subprocess.run(["git", "config", "user.email", "dummy@example.com"]) - subprocess.run(["git", "config", "user.name", "Dummy User"]) + from tests.utils import make_repo + make_repo() Path(".aider.conf.yml").write_text("no-auto-commits: true\n") with patch("aider.main.Coder.create") as MockCoder: @@ -62,9 +60,8 @@ class TestMain(TestCase): assert kwargs["auto_commits"] is True def test_main_with_empty_git_dir_new_subdir_file(self): - subprocess.run(["git", "init"]) - subprocess.run(["git", "config", "user.email", "dummy@example.com"]) - subprocess.run(["git", "config", "user.name", "Dummy User"]) + from tests.utils import make_repo + make_repo() subdir = Path("subdir") subdir.mkdir() fname = subdir / "foo.txt" From 7096f7287c844ce4bd0aeffd6746ae98054d3645 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 12:30:40 -0300 Subject: [PATCH 09/16] simplify with make_repo --- tests/test_main.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 41e1717bc..1e0259b9a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -12,7 +12,8 @@ from prompt_toolkit.output import DummyOutput from aider.dump import dump # noqa: F401 from aider.io import InputOutput -from aider.main import main +from aider.main import main, setup_git +from tests.utils import make_repo class TestMain(TestCase): @@ -38,18 +39,16 @@ class TestMain(TestCase): self.assertTrue(os.path.exists("foo.txt")) def test_main_with_empty_git_dir_new_file(self): - from tests.utils import make_repo make_repo() main(["--yes", "foo.txt"], input=DummyInput(), output=DummyOutput()) self.assertTrue(os.path.exists("foo.txt")) def test_main_with_git_config_yml(self): - from tests.utils import make_repo make_repo() Path(".aider.conf.yml").write_text("no-auto-commits: true\n") with patch("aider.main.Coder.create") as MockCoder: - main([], input=DummyInput(), output=DummyOutput()) + main(["--yes"], input=DummyInput(), output=DummyOutput()) _, kwargs = MockCoder.call_args assert kwargs["auto_commits"] is False @@ -60,7 +59,6 @@ class TestMain(TestCase): assert kwargs["auto_commits"] is True def test_main_with_empty_git_dir_new_subdir_file(self): - from tests.utils import make_repo make_repo() subdir = Path("subdir") subdir.mkdir() @@ -75,7 +73,7 @@ class TestMain(TestCase): main(["--yes", str(fname)], input=DummyInput(), output=DummyOutput()) def test_setup_git(self): - io = InputOutput(pretty=False, yes=True) + # io = InputOutput(pretty=False, yes=True) with patch("aider.main.git.Repo.init") as MockRepoInit: MockRepoInit.return_value = git.Repo(self.tempdir) git_root = setup_git(None, self.io) From 7d8069d778340f75781039ed8e118b00002c907c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 12:33:56 -0300 Subject: [PATCH 10/16] test_setup_git works --- tests/test_main.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 1e0259b9a..a30e3ec3c 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,7 +6,6 @@ from pathlib import Path from unittest import TestCase from unittest.mock import patch -import git from prompt_toolkit.input import DummyInput from prompt_toolkit.output import DummyOutput @@ -73,12 +72,10 @@ class TestMain(TestCase): main(["--yes", str(fname)], input=DummyInput(), output=DummyOutput()) def test_setup_git(self): - # io = InputOutput(pretty=False, yes=True) - with patch("aider.main.git.Repo.init") as MockRepoInit: - MockRepoInit.return_value = git.Repo(self.tempdir) - git_root = setup_git(None, self.io) - self.assertEqual(git_root, self.tempdir) - MockRepoInit.assert_called_once_with(self.tempdir) + io = InputOutput(pretty=False, yes=True) + git_root = setup_git(None, io) + git_root = Path(git_root).resolve() + self.assertEqual(git_root, Path(self.tempdir).resolve()) def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: From 1e0443cc868537d44c62359708870a8c0bd2fc59 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 12:36:19 -0300 Subject: [PATCH 11/16] better test --- tests/test_main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index a30e3ec3c..847b47c08 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,6 +6,7 @@ from pathlib import Path from unittest import TestCase from unittest.mock import patch +import git from prompt_toolkit.input import DummyInput from prompt_toolkit.output import DummyOutput @@ -77,6 +78,8 @@ class TestMain(TestCase): git_root = Path(git_root).resolve() self.assertEqual(git_root, Path(self.tempdir).resolve()) + self.assertTrue(git.Repo(self.tempdir)) + def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: # --yes will just ok the git repo without blocking on input From 0f14947a4ce6424f97ccaa401529cfc6fe1952a5 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 12:49:27 -0300 Subject: [PATCH 12/16] test_check_gitignore --- aider/main.py | 8 ++++---- tests/test_main.py | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/aider/main.py b/aider/main.py index b7508d4d8..775e49762 100644 --- a/aider/main.py +++ b/aider/main.py @@ -42,9 +42,11 @@ def setup_git(git_root, io): def check_gitignore(git_root, io): + if not git_root: + return + pat = ".aider*" - updated_ignore = None gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): content = gitignore_file.read_text(encoding="utf-8") @@ -56,7 +58,7 @@ def check_gitignore(git_root, io): if not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): return - if not content.endswith("\n"): + if content and not content.endswith("\n"): content += "\n" content += pat + "\n" gitignore_file.write_text(content, encoding="utf-8") @@ -366,8 +368,6 @@ def main(args=None, input=None, output=None): if args.git: git_root = setup_git(git_root, io) - - if git_root: check_gitignore(git_root, io) def scrub_sensitive_info(text): diff --git a/tests/test_main.py b/tests/test_main.py index 847b47c08..ed818cc84 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -12,7 +12,7 @@ from prompt_toolkit.output import DummyOutput from aider.dump import dump # noqa: F401 from aider.io import InputOutput -from aider.main import main, setup_git +from aider.main import check_gitignore, main, setup_git from tests.utils import make_repo @@ -80,6 +80,22 @@ class TestMain(TestCase): self.assertTrue(git.Repo(self.tempdir)) + def test_check_gitignore(self): + make_repo() + io = InputOutput(pretty=False, yes=True) + cwd = Path.cwd() + gitignore = cwd / ".gitignore" + + self.assertFalse(gitignore.exists()) + check_gitignore(cwd, io) + self.assertTrue(gitignore.exists()) + + self.assertEqual(".aider*", gitignore.read_text().splitlines()[0]) + + gitignore.write_text("one\ntwo\n") + check_gitignore(cwd, io) + self.assertEqual("one\ntwo\n.aider*\n", gitignore.read_text()) + def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: # --yes will just ok the git repo without blocking on input From 180ca7c4645eba0595fb438b57d03168cad53835 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 12:56:55 -0300 Subject: [PATCH 13/16] test_main_git_ignore --- aider/main.py | 3 ++- tests/test_main.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/aider/main.py b/aider/main.py index 775e49762..23c2b2a9a 100644 --- a/aider/main.py +++ b/aider/main.py @@ -38,6 +38,7 @@ def setup_git(git_root, io): io.tool_output("Git repository created in the current working directory.") git_root = str(Path.cwd().resolve()) + check_gitignore(git_root, None) return git_root @@ -55,7 +56,7 @@ def check_gitignore(git_root, io): else: content = "" - if not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): + if io and not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): return if content and not content.endswith("\n"): diff --git a/tests/test_main.py b/tests/test_main.py index ed818cc84..e85c8439d 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -80,6 +80,10 @@ class TestMain(TestCase): self.assertTrue(git.Repo(self.tempdir)) + gitignore = Path.cwd() / ".gitignore" + self.assertTrue(gitignore.exists()) + self.assertEqual(".aider*", gitignore.read_text().splitlines()[0]) + def test_check_gitignore(self): make_repo() io = InputOutput(pretty=False, yes=True) @@ -96,6 +100,17 @@ class TestMain(TestCase): check_gitignore(cwd, io) self.assertEqual("one\ntwo\n.aider*\n", gitignore.read_text()) + def test_main_git_ignore(self): + cwd = Path().cwd() + self.assertFalse((cwd / ".git").exists()) + self.assertFalse((cwd / ".gitignore").exists()) + + with patch("aider.main.Coder.create"): + main(["--yes"], input=DummyInput()) + + self.assertTrue((cwd / ".git").exists()) + self.assertTrue((cwd / ".gitignore").exists()) + def test_main_args(self): with patch("aider.main.Coder.create") as MockCoder: # --yes will just ok the git repo without blocking on input From 9c40fc34156f0b679c0aea998377575b4a1503d9 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 16 Jul 2023 18:27:17 -0300 Subject: [PATCH 14/16] Path.cwd --- aider/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/main.py b/aider/main.py index 23c2b2a9a..568dd0d11 100644 --- a/aider/main.py +++ b/aider/main.py @@ -26,7 +26,7 @@ def setup_git(git_root, io): if not io.confirm_ask("No git repo found, create one to track GPT's changes (recommended)?"): return - repo = git.Repo.init(os.getcwd()) + repo = git.Repo.init(Path.cwd()) global_git_config = git.GitConfigParser([str(Path.home() / ".gitconfig")], read_only=True) with repo.config_writer() as git_config: if not global_git_config.has_option("user", "name"): From 4b01f20b73d8b5d43dd32df05deebb17a9a2d312 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 17 Jul 2023 08:32:32 -0300 Subject: [PATCH 15/16] print when greating gitignore --- aider/main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/aider/main.py b/aider/main.py index 568dd0d11..1be6cd63e 100644 --- a/aider/main.py +++ b/aider/main.py @@ -38,11 +38,11 @@ def setup_git(git_root, io): io.tool_output("Git repository created in the current working directory.") git_root = str(Path.cwd().resolve()) - check_gitignore(git_root, None) + check_gitignore(git_root, io, False) return git_root -def check_gitignore(git_root, io): +def check_gitignore(git_root, io, ask=True): if not git_root: return @@ -56,7 +56,7 @@ def check_gitignore(git_root, io): else: content = "" - if io and not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): + if ask and not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"): return if content and not content.endswith("\n"): @@ -64,6 +64,8 @@ def check_gitignore(git_root, io): content += pat + "\n" gitignore_file.write_text(content, encoding="utf-8") + io.tool_output(f"Added {pat} to .gitignore") + def main(args=None, input=None, output=None): if args is None: From 72646f9733f346a6bf2cd4002e19ba2ae8c4dec3 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 17 Jul 2023 10:53:49 -0300 Subject: [PATCH 16/16] use io.read/write text --- aider/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/main.py b/aider/main.py index 1be6cd63e..2162ec8a2 100644 --- a/aider/main.py +++ b/aider/main.py @@ -50,7 +50,7 @@ def check_gitignore(git_root, io, ask=True): gitignore_file = Path(git_root) / ".gitignore" if gitignore_file.exists(): - content = gitignore_file.read_text(encoding="utf-8") + content = io.read_text(gitignore_file) if pat in content.splitlines(): return else: @@ -62,7 +62,7 @@ def check_gitignore(git_root, io, ask=True): if content and not content.endswith("\n"): content += "\n" content += pat + "\n" - gitignore_file.write_text(content, encoding="utf-8") + io.write_text(gitignore_file, content) io.tool_output(f"Added {pat} to .gitignore")