From 02b89f704acecb9993eccd94e8b93b406919e679 Mon Sep 17 00:00:00 2001 From: Thomas Mison Date: Thu, 21 Nov 2024 20:32:50 +0100 Subject: [PATCH] add /lock feature --- aider/commands.py | 18 ++++++++++++++ tests/basic/test_commands.py | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/aider/commands.py b/aider/commands.py index f846179e0e7..70027097e26 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -130,6 +130,24 @@ def completions_model(self): models = litellm.model_cost.keys() return models + def cmd_lock(self, args=None): + "Move all editable files to read-only status" + if not self.coder: + self.io.tool_error("No active coder") + return + + editable_files = self.coder.abs_fnames or [] + if not editable_files: + self.io.tool_error("No editable files to lock") + return + + read_only_files = self.coder.abs_read_only_fnames or set() + read_only_files.update(editable_files) + self.coder.abs_read_only_fnames = read_only_files + self.coder.abs_fnames = set() + + self.io.tool_output(f"Moved {len(editable_files)} files to read-only status") + def cmd_models(self, args): "Search the list of available models" diff --git a/tests/basic/test_commands.py b/tests/basic/test_commands.py index b4b0e304d45..d951ced8d68 100644 --- a/tests/basic/test_commands.py +++ b/tests/basic/test_commands.py @@ -1600,3 +1600,51 @@ def test_cmd_reset(self): del coder del commands + + def test_cmd_lock(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Set up test files + editable_files = { + os.path.join(self.tempdir, "file1.py"), + os.path.join(self.tempdir, "file2.py"), + } + read_only_files = {os.path.join(self.tempdir, "readonly.py")} + + coder.abs_fnames = editable_files + coder.abs_read_only_fnames = read_only_files + + # Execute lock command + commands.cmd_lock() + + # Verify files were moved to read-only + self.assertEqual(coder.abs_fnames, set()) + self.assertEqual(coder.abs_read_only_fnames, editable_files | read_only_files) + + def test_cmd_lock_no_files(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Set up with no editable files + coder.abs_fnames = set() + read_only_files = {os.path.join(self.tempdir, "readonly.py")} + coder.abs_read_only_fnames = read_only_files + + with mock.patch.object(io, "tool_error") as mock_error: + commands.cmd_lock() + mock_error.assert_called_once_with("No editable files to lock") + + # Verify nothing changed + self.assertEqual(coder.abs_fnames, set()) + self.assertEqual(coder.abs_read_only_fnames, read_only_files) + + def test_cmd_lock_no_coder(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + commands = Commands(io, coder=None) + + with mock.patch.object(io, "tool_error") as mock_error: + commands.cmd_lock() + mock_error.assert_called_once_with("No active coder")