Skip to content

Commit 2362b25

Browse files
committed
bugs: query for existing open bugs
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
1 parent 0a65605 commit 2362b25

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

src/pkgdev/scripts/pkgdev_bugs.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from collections import defaultdict
66
from functools import partial
77
from itertools import chain
8+
from urllib.parse import urlencode
89

910
from pkgcheck import const as pkgcheck_const
1011
from pkgcheck.addons import ArchesAddon, init_addon
@@ -13,6 +14,7 @@
1314
from pkgcheck.scripts import argparse_actions
1415
from pkgcore.ebuild.atom import atom
1516
from pkgcore.ebuild.ebuild_src import package
17+
from pkgcore.ebuild.errors import MalformedAtom
1618
from pkgcore.ebuild.misc import sort_keywords
1719
from pkgcore.repository import multiplex
1820
from pkgcore.restrictions import boolean, packages, values
@@ -127,6 +129,16 @@ def _get_suggested_keywords(repo, pkg: package):
127129
return frozenset({x for x in match_keywords if "-" not in x})
128130

129131

132+
def parse_atom(pkg: str):
133+
try:
134+
return atom(pkg)
135+
except MalformedAtom as exc:
136+
try:
137+
return atom(f"={pkg}")
138+
except MalformedAtom:
139+
raise exc
140+
141+
130142
class GraphNode:
131143
__slots__ = ("pkgs", "edges", "bugno")
132144

@@ -267,7 +279,7 @@ def _find_dependencies(self, pkg: package, keywords: set[str]):
267279
combined = boolean.AndRestriction(*set().union(*problems.values()))
268280
match = self.find_best_match(combined, pkgset)
269281
yield match, set(problems.keys())
270-
except ValueError:
282+
except (ValueError, IndexError):
271283
results: dict[package, set[str]] = defaultdict(set)
272284
for keyword, deps in problems.items():
273285
match = self.find_best_match(deps, pkgset)
@@ -310,6 +322,8 @@ def output_dot(self, dot_file):
310322
dot.write("\trankdir=LR;\n")
311323
for node in self.nodes:
312324
node_text = "\\n".join(node.lines())
325+
if node.bugno is not None:
326+
node_text += f"\\nbug #{node.bugno}"
313327
dot.write(f'\t{node.dot_edge}[label="{node_text}"];\n')
314328
for other in node.edges:
315329
dot.write(f"\t{node.dot_edge} -> {other.dot_edge};\n")
@@ -385,6 +399,46 @@ def merge_new_keywords_children(self):
385399
found_someone = True
386400
break
387401

402+
def scan_existing_bugs(self, api_key: str):
403+
params = urlencode(
404+
{
405+
"Bugzilla_api_key": api_key,
406+
"include_fields": "id,cf_stabilisation_atoms",
407+
"component": "Stabilization",
408+
"resolution": "---",
409+
"f1": "cf_stabilisation_atoms",
410+
"o1": "anywords",
411+
"v1": {pkg[0].unversioned_atom for node in self.nodes for pkg in node.pkgs},
412+
},
413+
doseq=True,
414+
)
415+
request = urllib.Request(
416+
url="https://bugs.gentoo.org/rest/bug?" + params,
417+
method="GET",
418+
headers={
419+
"Content-Type": "application/json",
420+
"Accept": "application/json",
421+
},
422+
)
423+
with urllib.urlopen(request, timeout=30) as response:
424+
reply = json.loads(response.read().decode("utf-8"))
425+
for bug in reply["bugs"]:
426+
bug_atoms = (
427+
parse_atom(line.split(" ", 1)[0]).unversioned_atom
428+
for line in map(str.strip, bug["cf_stabilisation_atoms"].splitlines())
429+
if line
430+
)
431+
bug_match = boolean.OrRestriction(*bug_atoms)
432+
for node in self.nodes:
433+
if node.bugno is None and all(bug_match.match(pkg[0]) for pkg in node.pkgs):
434+
node.bugno = bug["id"]
435+
self.out.write(
436+
self.out.fg("yellow"),
437+
f"Found https://bugs.gentoo.org/{node.bugno} for node {node}",
438+
self.out.reset,
439+
)
440+
break
441+
388442
def file_bugs(self, api_key: str, auto_cc_arches: frozenset[str]):
389443
def observe(node: GraphNode):
390444
self.out.write(
@@ -411,6 +465,9 @@ def main(options, out: Formatter, err: Formatter):
411465
for node in d.nodes:
412466
node.cleanup_keywords(search_repo)
413467

468+
if userquery("Check for open bugs matching current graph?", out, err, default_answer=False):
469+
d.scan_existing_bugs(options.api_key)
470+
414471
if options.dot is not None:
415472
d.output_dot(options.dot)
416473
out.write(out.fg("green"), f"Dot file written to {options.dot}", out.reset)

0 commit comments

Comments
 (0)