diff --git a/osc/core.py b/osc/core.py index 8f7d6333..0e8d027a 100644 --- a/osc/core.py +++ b/osc/core.py @@ -1277,13 +1277,24 @@ class Package: path_is_file = os.path.isfile(path) if path_is_file: path = os.path.dirname(path) or "." + package = cls(path, progress_obj) + try: + # re-use an existing package + seen_package_index = packages.index(package) + package = packages[seen_package_index] + if os.path.abspath(path) != package.absdir: + raise oscerr.PackageExists(package.prjname, package.name, "Duplicate package") + except ValueError: + # use a new package instance + packages.append(package) + if path_is_file: # XXX: modifying 'todo' is an unexpected side-effect - package.todo = [os.path.basename(orig_path)] - if package in packages: - raise oscerr.PackageExists(package.prjname, package.name, "Duplicate package") - packages.append(package) + todo_entry = os.path.basename(orig_path) + if todo_entry not in package.todo: + package.todo.append(todo_entry) + return packages @classmethod diff --git a/tests/fixtures/packages/osctest/projectA/pkgA-symlink b/tests/fixtures/packages/osctest/projectA/pkgA-symlink new file mode 120000 index 00000000..7bfb5b5a --- /dev/null +++ b/tests/fixtures/packages/osctest/projectA/pkgA-symlink @@ -0,0 +1 @@ +pkgA \ No newline at end of file diff --git a/tests/fixtures/packages/osctest/projectA/pkgA/pkgA.changes b/tests/fixtures/packages/osctest/projectA/pkgA/pkgA.changes new file mode 100644 index 00000000..e69de29b diff --git a/tests/fixtures/packages/osctest/projectA/pkgA/pkgA.spec b/tests/fixtures/packages/osctest/projectA/pkgA/pkgA.spec new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_core_package.py b/tests/test_core_package.py index d6f79f5f..d37cf5a8 100644 --- a/tests/test_core_package.py +++ b/tests/test_core_package.py @@ -81,10 +81,31 @@ class TestPackageFromPaths(OscTestCase): self.assertEqual(pac.apiurl, "http://localhost") def test_duplicates(self): + # passing a path twice is ok paths = ["projectA/pkgA", "projectA/pkgA"] paths = [os.path.join(self.tmpdir, 'osctest', i) for i in paths] + pacs = osc.core.Package.from_paths(paths) + pac = pacs[0] + self.assertEqual(pac.name, "pkgA") + self.assertEqual(pac.prjname, "projectA") + self.assertEqual(pac.apiurl, "http://localhost") + + # the same package in 2 paths is an error + paths = ["projectA/pkgA", "projectA/pkgA-symlink"] + paths = [os.path.join(self.tmpdir, 'osctest', i) for i in paths] self.assertRaises(osc.oscerr.PackageExists, osc.core.Package.from_paths, paths) + def test_one_package_two_files(self): + paths = ["projectA/pkgA/pkgA.spec", "projectA/pkgA/pkgA.changes"] + paths = [os.path.join(self.tmpdir, 'osctest', i) for i in paths] + pacs = osc.core.Package.from_paths(paths) + self.assertEqual(len(pacs), 1) + + pac = pacs[0] + self.assertEqual(pac.name, "pkgA") + self.assertEqual(pac.prjname, "projectA") + self.assertEqual(pac.apiurl, "http://localhost") + def test_two_packages(self): paths = ["projectA/pkgA", "projectA/pkgB"] paths = [os.path.join(self.tmpdir, 'osctest', i) for i in paths]