1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-02-03 10:06:17 +01:00

The repo list command now resolves and displays flags (build, publish, ...)

This commit is contained in:
Daniel Mach 2023-07-07 13:14:27 +02:00
parent e1e8128af9
commit 51052dafe0
3 changed files with 90 additions and 8 deletions

View File

@ -13,9 +13,10 @@ Scenario: Run `osc repo list` on a project
Then stdout is
"""
Repository : standard
Architectures : x86_64
i586
Architectures : x86_64, i586
Paths : openSUSE.org:openSUSE:Tumbleweed/standard
Flags
build : disable: x86_64, i586
"""
@ -26,15 +27,17 @@ Scenario: Run `osc repo add` on a project
Then stdout is
"""
Repository : standard
Architectures : x86_64
i586
Architectures : x86_64, i586
Paths : openSUSE.org:openSUSE:Tumbleweed/standard
Flags
build : disable: x86_64, i586
Repository : new-repo
Architectures : x86_64
aarch64
Architectures : x86_64, aarch64
Paths : test:factory/standard
test:devel/standard
Flags
build : disable: x86_64, aarch64
"""

View File

@ -1,11 +1,13 @@
from . import api
from .api import ET
from .. import core as osc_core
from .. import oscerr
class APIXMLBase:
def __init__(self, xml_root):
def __init__(self, xml_root, apiurl=None):
self.root = xml_root
self.apiurl = apiurl
def to_bytes(self):
ET.indent(self.root, space=" ", level=0)
@ -20,7 +22,7 @@ class ProjectMeta(APIXMLBase):
def from_api(cls, apiurl, project):
url_path = ["source", project, "_meta"]
root = api.get(apiurl, url_path)
obj = cls(root)
obj = cls(root, apiurl=apiurl)
return obj
def to_api(self, apiurl, project):
@ -93,3 +95,60 @@ class ProjectMeta(APIXMLBase):
if len(publish_node) == 0:
self.root.remove(publish_node)
REPOSITORY_FLAGS_TEMPLATE = {
"build": None,
"debuginfo": None,
"publish": None,
"useforbuild": None,
}
def _update_repository_flags(self, repository_flags, xml_root):
"""
Update `repository_flags` with data from the `xml_root`.
"""
for flag in self.REPOSITORY_FLAGS_TEMPLATE:
flag_node = xml_root.find(flag)
if flag_node is None:
continue
for node in flag_node:
action = node.tag
repo = node.get("repository")
arch = node.get("arch")
for (entry_repo, entry_arch), entry_data in repository_flags.items():
match = False
if (repo, arch) == (entry_repo, entry_arch):
# apply to matching repository and architecture
match = True
elif repo == entry_repo and not arch:
# apply to all matching repositories
match = True
elif not repo and arch == entry_arch:
# apply to all matching architectures
match = True
elif not repo and not arch:
# apply to everything
match = True
if match:
entry_data[flag] = True if action == "enable" else False
def resolve_repository_flags(self, package=None):
"""
Resolve the `build`, `debuginfo`, `publish` and `useforbuild` flags
and return their values for each repository and build arch.
:returns: {(repo_name, repo_buildarch): {flag_name: bool} for all available repos
"""
result = {}
# TODO: avoid calling get_repos_of_project(), use self.root instead
for repo in osc_core.get_repos_of_project(self.apiurl, self.root.attrib["name"]):
result[(repo.name, repo.arch)] = self.REPOSITORY_FLAGS_TEMPLATE.copy()
self._update_repository_flags(result, self.root)
if package:
m = osc_core.show_package_meta(self.apiurl, self.root.attrib["name"], package)
root = ET.fromstring(b''.join(m))
self._update_repository_flags(result, root)
return result

View File

@ -20,6 +20,16 @@ class RepoListCommand(osc.commandline.OscCommand):
def run(self, args):
meta = ProjectMeta.from_api(args.apiurl, args.project)
repo_flags = meta.resolve_repository_flags()
flag_map = {}
for (repo_name, arch), data in repo_flags.items():
for flag_name, flag_value in data.items():
if flag_value is None:
continue
action = "enable" if flag_value else "disable"
flag_map.setdefault(repo_name, {}).setdefault(flag_name, {}).setdefault(action, []).append(arch)
table = KeyValueTable()
for repo in meta.repository_list():
table.add("Repository", repo["name"], color="bold")
@ -27,5 +37,15 @@ class RepoListCommand(osc.commandline.OscCommand):
if repo["paths"]:
paths = [f"{path['project']}/{path['repository']}" for path in repo["paths"]]
table.add("Paths", paths)
if repo["name"] in flag_map:
table.add("Flags", None)
for flag_name in flag_map[repo["name"]]:
lines = []
for action, archs in flag_map[repo["name"]][flag_name].items():
lines.append(f"{action + ':':<8s} {', '.join(archs)}")
lines.sort()
table.add(flag_name, lines, indent=4)
table.newline()
print(str(table))