mirror of
https://github.com/openSUSE/osc.git
synced 2025-02-09 12:35:48 +01:00
The repo list command now resolves and displays flags (build, publish, ...)
This commit is contained in:
parent
e1e8128af9
commit
51052dafe0
@ -13,9 +13,10 @@ Scenario: Run `osc repo list` on a project
|
|||||||
Then stdout is
|
Then stdout is
|
||||||
"""
|
"""
|
||||||
Repository : standard
|
Repository : standard
|
||||||
Architectures : x86_64
|
Architectures : x86_64, i586
|
||||||
i586
|
|
||||||
Paths : openSUSE.org:openSUSE:Tumbleweed/standard
|
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
|
Then stdout is
|
||||||
"""
|
"""
|
||||||
Repository : standard
|
Repository : standard
|
||||||
Architectures : x86_64
|
Architectures : x86_64, i586
|
||||||
i586
|
|
||||||
Paths : openSUSE.org:openSUSE:Tumbleweed/standard
|
Paths : openSUSE.org:openSUSE:Tumbleweed/standard
|
||||||
|
Flags
|
||||||
|
build : disable: x86_64, i586
|
||||||
|
|
||||||
Repository : new-repo
|
Repository : new-repo
|
||||||
Architectures : x86_64
|
Architectures : x86_64, aarch64
|
||||||
aarch64
|
|
||||||
Paths : test:factory/standard
|
Paths : test:factory/standard
|
||||||
test:devel/standard
|
test:devel/standard
|
||||||
|
Flags
|
||||||
|
build : disable: x86_64, aarch64
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
from . import api
|
from . import api
|
||||||
from .api import ET
|
from .api import ET
|
||||||
|
from .. import core as osc_core
|
||||||
from .. import oscerr
|
from .. import oscerr
|
||||||
|
|
||||||
|
|
||||||
class APIXMLBase:
|
class APIXMLBase:
|
||||||
def __init__(self, xml_root):
|
def __init__(self, xml_root, apiurl=None):
|
||||||
self.root = xml_root
|
self.root = xml_root
|
||||||
|
self.apiurl = apiurl
|
||||||
|
|
||||||
def to_bytes(self):
|
def to_bytes(self):
|
||||||
ET.indent(self.root, space=" ", level=0)
|
ET.indent(self.root, space=" ", level=0)
|
||||||
@ -20,7 +22,7 @@ class ProjectMeta(APIXMLBase):
|
|||||||
def from_api(cls, apiurl, project):
|
def from_api(cls, apiurl, project):
|
||||||
url_path = ["source", project, "_meta"]
|
url_path = ["source", project, "_meta"]
|
||||||
root = api.get(apiurl, url_path)
|
root = api.get(apiurl, url_path)
|
||||||
obj = cls(root)
|
obj = cls(root, apiurl=apiurl)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def to_api(self, apiurl, project):
|
def to_api(self, apiurl, project):
|
||||||
@ -93,3 +95,60 @@ class ProjectMeta(APIXMLBase):
|
|||||||
|
|
||||||
if len(publish_node) == 0:
|
if len(publish_node) == 0:
|
||||||
self.root.remove(publish_node)
|
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
|
||||||
|
@ -20,6 +20,16 @@ class RepoListCommand(osc.commandline.OscCommand):
|
|||||||
|
|
||||||
def run(self, args):
|
def run(self, args):
|
||||||
meta = ProjectMeta.from_api(args.apiurl, args.project)
|
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()
|
table = KeyValueTable()
|
||||||
for repo in meta.repository_list():
|
for repo in meta.repository_list():
|
||||||
table.add("Repository", repo["name"], color="bold")
|
table.add("Repository", repo["name"], color="bold")
|
||||||
@ -27,5 +37,15 @@ class RepoListCommand(osc.commandline.OscCommand):
|
|||||||
if repo["paths"]:
|
if repo["paths"]:
|
||||||
paths = [f"{path['project']}/{path['repository']}" for path in repo["paths"]]
|
paths = [f"{path['project']}/{path['repository']}" for path in repo["paths"]]
|
||||||
table.add("Paths", 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()
|
table.newline()
|
||||||
print(str(table))
|
print(str(table))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user