From c9c49f2a33681c96786d37e82f6d528d145a0346 Mon Sep 17 00:00:00 2001 From: Thomas Mison Date: Thu, 21 Nov 2024 20:25:06 +0100 Subject: [PATCH] add /lock feature --- aider/commands.py | 18 ++++++++++++++ tests/basic/test_commands.py | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/aider/commands.py b/aider/commands.py index f846179e0e7..80d25238ed9 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..1df48783ad2 100644 --- a/tests/basic/test_commands.py +++ b/tests/basic/test_commands.py @@ -1600,3 +1600,49 @@ 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')