1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-23 13:31:48 +01:00

core.Action: Add src_pkg_object and tgt_pkg_object properties providing object wrappers to file lists

This commit is contained in:
Daniel Mach 2023-02-13 13:52:00 +01:00
parent f5da27ad24
commit 95be11130e
5 changed files with 93 additions and 0 deletions

View File

@ -13,4 +13,5 @@ from .api_source import release
from .common import print_msg
from .common import format_msg_project_package_options
from .package import ApiPackage
from .package import LocalPackage
from .request import forward_request

View File

@ -1,5 +1,6 @@
import functools
from .. import oscerr
from . import api
@ -18,6 +19,7 @@ class PackageBase:
self.files = []
directory_node = self._get_directory_node()
self._load_from_directory_node(directory_node)
self._meta_node = None
def __str__(self):
return f"{self.project}/{self.name}"
@ -60,6 +62,19 @@ class PackageBase:
# the name is omitted and we want it present for overall sanity
self.linkinfo.package = self.name
def _get_meta_node(self):
raise NotImplementedError()
def get_meta_value(self, option):
if not self._meta_node:
self._meta_node = self._get_meta_node()
if not self._meta_node:
return None
node = api.find_node(self._meta_node, "package", option)
if node is None or not node.text:
raise oscerr.APIError(f"Couldn't get '{option}' from package _meta")
return node.text
class ApiPackage(PackageBase):
def __init__(self, apiurl, project, package, rev=None):
@ -75,6 +90,11 @@ class ApiPackage(PackageBase):
url_query["rev"] = self.__rev
return api.get(self.apiurl, url_path, url_query)
def _get_meta_node(self):
url_path = ["source", self.project, self.name, "_meta"]
url_query = {}
return api.get(self.apiurl, url_path, url_query)
class LocalPackage(PackageBase):
def __init__(self, path):
@ -86,3 +106,6 @@ class LocalPackage(PackageBase):
def _get_directory_node(self):
return self.store.read_xml_node("_files", "directory").getroot()
def _get_meta_node(self):
return self.store._meta_node

View File

@ -2880,6 +2880,8 @@ class Action:
def __init__(self, type, **kwargs):
self.apiurl = kwargs.pop("apiurl", None)
self._src_pkg_object = None
self._tgt_pkg_object = None
if type not in Action.type_args.keys():
raise oscerr.WrongArgs('invalid action type: \'%s\'' % type)
self.type = type
@ -2890,6 +2892,40 @@ class Action:
for i in Action.type_args[type]:
setattr(self, i, kwargs.get(i))
@property
def src_pkg_object(self):
if not getattr(self, "src_project", None) or not getattr(self, "src_package", None):
return None
if not self._src_pkg_object:
src_rev = getattr(self, "src_rev", None)
self._src_pkg_object = _private.ApiPackage(self.apiurl, self.src_project, self.src_package, src_rev)
return self._src_pkg_object
@property
def tgt_pkg_object(self):
if not self._tgt_pkg_object:
if self.type == "maintenance_incident":
# the target project for maintenance incidents is virtual and cannot be queried
# the actual target project is in the "releaseproject" attribute
#
# tgt_releaseproject is always set for a maintenance_incident
# pylint: disable=no-member
tgt_project = self.tgt_releaseproject
# the target package is not specified
# we need to extract it from source package's _meta
src_package_meta_releasename = self.src_pkg_object.get_meta_value("releasename")
tgt_package = src_package_meta_releasename.split(".")[0]
else:
if not getattr(self, "tgt_project", None) or not getattr(self, "tgt_package", None):
return None
# tgt_project and tgt_package are checked above
# pylint: disable=no-member
tgt_project = self.tgt_project
tgt_package = self.tgt_package
self._tgt_pkg_object = _private.ApiPackage(self.apiurl, tgt_project, tgt_package)
return self._tgt_pkg_object
def to_xml(self):
"""
Serialize object to XML.

View File

@ -299,3 +299,13 @@ class Store:
if len(value) != 3:
raise ValueError("A list with exactly 3 items is expected: [repo, arch, vm_type]")
self.write_list("_last_buildroot", value)
@property
def _meta_node(self):
if not self.exists("_meta"):
return None
if self.is_package:
root = self.read_xml_node("_meta", "package").getroot()
else:
root = self.read_xml_node("_meta", "project").getroot()
return root

View File

@ -203,6 +203,29 @@ class TestStore(unittest.TestCase):
store2 = Store(self.tmpdir)
self.assertEqual(store2.last_buildroot, ["repo", "arch", "vm_type"])
def test_meta_node(self):
self.store.write_string(
"_meta",
"""<package name="test-pkgA" project="projectA">
<title>title</title>
<description>desc</description>
<releasename>name</releasename>
<build>
<enable repository="repo1"/>
<enable repository="repo2"/>
</build>
</package>""",
)
node = self.store._meta_node
self.assertNotEqual(node, None)
# try to read the _meta via a package class
from osc._private import LocalPackage
self.store.files = []
pkg = LocalPackage(self.tmpdir)
self.assertEqual(pkg.get_meta_value("releasename"), "name")
if __name__ == "__main__":
unittest.main()