From 70e05319e5a8790fd6dcc9d39c8cff4ae0cf9cef Mon Sep 17 00:00:00 2001 From: Jonatas Ferreira Date: Tue, 10 Sep 2024 10:07:59 -0300 Subject: [PATCH] feat: add rename profile option --- sshoot/main.py | 19 +++++++++++++++++++ sshoot/manager.py | 6 ++++++ tests/manager_test.py | 12 ++++++++++++ 3 files changed, 37 insertions(+) diff --git a/sshoot/main.py b/sshoot/main.py index 19940c5..ec5cb60 100644 --- a/sshoot/main.py +++ b/sshoot/main.py @@ -117,6 +117,11 @@ def action_get_command(self, manager: Manager, args: Namespace): ) self.print(" ".join(cmdline)) + def action_rename(self, manager: Manager, args: Namespace): + """Rename a sshoot profile.""" + manager.rename_profile(args.name, args.new_name) + self.print(_(f"Profile renamed to '{args.new_name}'.")) + def get_parser(self) -> ArgumentParser: """Return a configured argparse.ArgumentParse instance.""" parser = ArgumentParser( @@ -288,6 +293,20 @@ def get_parser(self) -> ArgumentParser: profile_completer, ) + # Rename a profile + rename_parser = subparsers.add_parser( + "rename", help=_("rename a profile") + ) + complete_argument( + rename_parser.add_argument( + "name", help=_("name of the profile to rename"), + ), + profile_completer + ) + rename_parser.add_argument( + "new_name", help=_("profile new name") + ) + # Get profile command get_command_parser = subparsers.add_parser( "get-command", help=_("return the sshuttle command for a profile") diff --git a/sshoot/manager.py b/sshoot/manager.py index c4fcb68..00659c3 100644 --- a/sshoot/manager.py +++ b/sshoot/manager.py @@ -174,6 +174,12 @@ def is_running(self, name: str) -> bool: return False return True + def rename_profile(self, old_name: str, new_name: str): + """Rename a profile.""" + profile = self.get_profile(old_name) + self._config.add_profile(new_name, profile) + self.remove_profile(old_name) + def get_cmdline( self, name: str, diff --git a/tests/manager_test.py b/tests/manager_test.py index 52eff82..60f3315 100644 --- a/tests/manager_test.py +++ b/tests/manager_test.py @@ -313,6 +313,18 @@ def test_is_running_pidfile_no_process(self, profile_manager, pid_file): # The stale pidfile is deleted. assert not pid_file.exists() + def test_rename_profile(self, profile_manager: Manager, profile): + """If the profile exists, rename it.""" + profile_manager.rename_profile("profile", "new_profile") + new_profile = profile_manager.get_profile("new_profile") + + assert new_profile is not None + + def test_rename_profile_unknown(self, profile_manager: Manager): + """Manager.rename_profile raises an error if name is unknown.""" + with pytest.raises(ManagerProfileError): + profile_manager.rename_profile("unknown", "new_profile") + def test_get_cmdline(self, profile_manager, pid_file): """Manager.get_cmdline returns the command line for the profile.""" assert profile_manager.get_cmdline("profile") == [