From ce4cd4e4e9d3380e8538870aa3c0533158e1395c Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Tue, 20 Dec 2022 16:53:21 +0100 Subject: [PATCH] commandline: Add pop_project_package_targetproject_targetpackage_from_args() function --- osc/commandline.py | 39 +++++++++++ tests/test_commandline.py | 144 +++++++++++++++++++++++++++++++++++--- 2 files changed, 173 insertions(+), 10 deletions(-) diff --git a/osc/commandline.py b/osc/commandline.py index db6a1fe3..9032b805 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -204,6 +204,45 @@ def pop_project_package_repository_arch_from_args(args): return project, package, repository, arch +def pop_project_package_targetproject_targetpackage_from_args(args, target_package_is_optional=False): + """ + Get project, package, target_project and target_package from given `args`. + + :param args: List of command-line arguments. + WARNING: `args` gets modified in this function call! + :type args: list(str) + :param target_package_is_optional: Whether to error out when target package name cannot be retrieved. + :type target_package_is_optional: bool + :returns: Project name, package name, target project name and target package name. + :rtype: tuple(str) + """ + args_backup = args.copy() + #try_working_copy = True + + try_working_copy = True + try: + # try this sequence first: project package target_project target_package + project, package = pop_project_package_from_args(args, package_is_optional=False) + if args: + # we got more than 2 arguments -> we shouldn't try to retrieve project and package from a working copy + try_working_copy = False + target_project, target_package = pop_project_package_from_args( + args, package_is_optional=target_package_is_optional + ) + except oscerr.OscValueError as ex: + if not try_working_copy: + raise ex from None + # then read project and package from working copy and target_project target_package + args[:] = args_backup.copy() + project, package = pop_project_package_from_args( + [], default_project=".", default_package=".", package_is_optional=False + ) + target_project, target_package = pop_project_package_from_args( + args, package_is_optional=target_package_is_optional + ) + return project, package, target_project, target_package + + def ensure_no_remaining_args(args): if not args: return diff --git a/tests/test_commandline.py b/tests/test_commandline.py index 26021ccc..815a4bb8 100644 --- a/tests/test_commandline.py +++ b/tests/test_commandline.py @@ -5,6 +5,7 @@ import unittest from osc.commandline import pop_project_package_from_args from osc.commandline import pop_project_package_repository_arch_from_args +from osc.commandline import pop_project_package_targetproject_targetpackage_from_args from osc.commandline import pop_repository_arch_from_args from osc.oscerr import NoWorkingCopy, OscValueError from osc.store import Store @@ -40,7 +41,12 @@ class TestPopProjectPackageFromArgs(unittest.TestCase): def test_defaults(self): args = ["project"] - self.assertRaises(OscValueError, pop_project_package_from_args, args, default_package="default-package") + self.assertRaises( + OscValueError, + pop_project_package_from_args, + args, + default_package="default-package", + ) args = ["project"] project, package = pop_project_package_from_args( @@ -60,7 +66,10 @@ class TestPopProjectPackageFromArgs(unittest.TestCase): args = [] project, package = pop_project_package_from_args( - args, default_project="default-project", default_package="default-package", package_is_optional=True + args, + default_project="default-project", + default_package="default-package", + package_is_optional=True, ) self.assertEqual(project, "default-project") self.assertEqual(package, "default-package") @@ -102,7 +111,13 @@ class TestPopProjectPackageFromArgs(unittest.TestCase): self.assertEqual(args, []) args = [] - self.assertRaises(NoWorkingCopy, pop_project_package_from_args, args, default_project=".", default_package=".") + self.assertRaises( + NoWorkingCopy, + pop_project_package_from_args, + args, + default_project=".", + default_package=".", + ) args = [] project, package = pop_project_package_from_args( @@ -128,7 +143,9 @@ class TestPopProjectPackageFromArgs(unittest.TestCase): self.assertEqual(args, []) args = [] - project, package = pop_project_package_from_args(args, default_project=".", default_package=".") + project, package = pop_project_package_from_args( + args, default_project=".", default_package="." + ) self.assertEqual(project, "store_project") self.assertEqual(package, "store_package") self.assertEqual(args, []) @@ -189,7 +206,9 @@ class TestPopProjectPackageRepositoryArchFromArgs(unittest.TestCase): def test_individual_args(self): args = ["project", "package", "repo", "arch", "another-arg"] - project, package, repo, arch = pop_project_package_repository_arch_from_args(args) + project, package, repo, arch = pop_project_package_repository_arch_from_args( + args + ) self.assertEqual(project, "project") self.assertEqual(package, "package") self.assertEqual(repo, "repo") @@ -198,7 +217,9 @@ class TestPopProjectPackageRepositoryArchFromArgs(unittest.TestCase): def test_slash_separator(self): args = ["project/package", "repo/arch", "another-arg"] - project, package, repo, arch = pop_project_package_repository_arch_from_args(args) + project, package, repo, arch = pop_project_package_repository_arch_from_args( + args + ) self.assertEqual(project, "project") self.assertEqual(package, "package") self.assertEqual(repo, "repo") @@ -207,16 +228,22 @@ class TestPopProjectPackageRepositoryArchFromArgs(unittest.TestCase): def test_missing_arch(self): args = ["project", "package", "repo"] - self.assertRaises(OscValueError, pop_project_package_repository_arch_from_args, args) + self.assertRaises( + OscValueError, pop_project_package_repository_arch_from_args, args + ) def test_no_working_copy(self): args = ["repo", "arch"] - self.assertRaises(NoWorkingCopy, pop_project_package_repository_arch_from_args, args) + self.assertRaises( + NoWorkingCopy, pop_project_package_repository_arch_from_args, args + ) def test_working_copy(self): self._write_store("store_project", "store_package") args = ["repo", "arch"] - project, package, repo, arch = pop_project_package_repository_arch_from_args(args) + project, package, repo, arch = pop_project_package_repository_arch_from_args( + args + ) self.assertEqual(project, "store_project") self.assertEqual(package, "store_package") self.assertEqual(repo, "repo") @@ -226,7 +253,104 @@ class TestPopProjectPackageRepositoryArchFromArgs(unittest.TestCase): self._write_store("store_project", "store_package") args = ["repo", "arch", "another-arg"] # example of invalid usage, working copy is not used when there's 3+ args; [project, package, ...] are expected - self.assertRaises(OscValueError, pop_project_package_repository_arch_from_args, args) + self.assertRaises( + OscValueError, pop_project_package_repository_arch_from_args, args + ) + + +class TestPopProjectPackageTargetProjectTargetPackageFromArgs(unittest.TestCase): + def _write_store(self, project=None, package=None): + store = Store(self.tmpdir, check=False) + if project: + store.project = project + store.is_project = True + if package: + store.package = package + store.is_project = False + store.is_package = True + + def setUp(self): + self.tmpdir = tempfile.mkdtemp(prefix="osc_test") + os.chdir(self.tmpdir) + + def tearDown(self): + try: + shutil.rmtree(self.tmpdir) + except OSError: + pass + + def test_individual_args(self): + args = ["project", "package", "target-project", "target-package", "another-arg"] + project, package, target_project, target_package = pop_project_package_targetproject_targetpackage_from_args( + args + ) + self.assertEqual(project, "project") + self.assertEqual(package, "package") + self.assertEqual(target_project, "target-project") + self.assertEqual(target_package, "target-package") + self.assertEqual(args, ["another-arg"]) + + def test_slash_separator(self): + args = ["project/package", "target-project/target-package", "another-arg"] + project, package, target_project, target_package = pop_project_package_targetproject_targetpackage_from_args( + args + ) + self.assertEqual(project, "project") + self.assertEqual(package, "package") + self.assertEqual(target_project, "target-project") + self.assertEqual(target_package, "target-package") + self.assertEqual(args, ["another-arg"]) + + def test_missing_target_package(self): + args = ["project", "package", "target-project"] + project, package, target_project, target_package = pop_project_package_targetproject_targetpackage_from_args( + args, target_package_is_optional=True + ) + self.assertEqual(project, "project") + self.assertEqual(package, "package") + self.assertEqual(target_project, "target-project") + self.assertEqual(target_package, None) + self.assertEqual(args, []) + + def test_no_working_copy(self): + args = ["target-project", "target-package"] + self.assertRaises( + NoWorkingCopy, + pop_project_package_targetproject_targetpackage_from_args, + args, + ) + + def test_working_copy(self): + self._write_store("store_project", "store_package") + args = ["target-project", "target-package"] + project, package, target_project, target_package = pop_project_package_targetproject_targetpackage_from_args( + args + ) + self.assertEqual(project, "store_project") + self.assertEqual(package, "store_package") + self.assertEqual(target_project, "target-project") + self.assertEqual(target_package, "target-package") + + def test_working_copy_missing_target_package(self): + self._write_store("store_project", "store_package") + args = ["target-project"] + project, package, target_project, target_package = pop_project_package_targetproject_targetpackage_from_args( + args, target_package_is_optional=True + ) + self.assertEqual(project, "store_project") + self.assertEqual(package, "store_package") + self.assertEqual(target_project, "target-project") + self.assertEqual(target_package, None) + + def test_working_copy_extra_arg(self): + self._write_store("store_project", "store_package") + args = ["target-project", "target-package", "another-arg"] + # example of invalid usage, working copy is not used when there's 3+ args; [project, package, ...] are expected + self.assertRaises( + OscValueError, + pop_project_package_targetproject_targetpackage_from_args, + args, + ) if __name__ == "__main__":