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:
parent
f5da27ad24
commit
95be11130e
@ -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
|
||||
|
@ -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
|
||||
|
36
osc/core.py
36
osc/core.py
@ -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.
|
||||
|
10
osc/store.py
10
osc/store.py
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user