repos.recursive_buid_report: Try breaking cycles

Instead of falling back to alphabetical order when
cycle is detected, we try to break it and form
the topological order again. Even if cycles are
broken at the wrong edge, this order might still
be more useful.

All the cycles found are included into the report.
This commit is contained in:
Ivan A. Melnikov 2021-09-16 12:04:15 +04:00
parent 09f9a563f0
commit 02b3453509

View File

@ -393,11 +393,18 @@ def recursive_build_report(from_repo, to_repo, *source_names,
dep_sources.add(b.source_name)
full_req[source] = dep_sources
try:
order = list(graphlib.TopologicalSorter(full_req).static_order())
except graphlib.CycleError as ex:
LOG.error("Cycle detected: %s", ex)
order = sorted(build_source_deps)
cycles = []
while True:
try:
order = list(graphlib.TopologicalSorter(full_req).static_order())
except graphlib.CycleError as ex:
LOG.warning("Cycle detected: %s", ex)
cycle = ex.args[1]
cycles.append(cycle)
# break the cycle and retry
full_req[cycle[1]].remove(cycle[0])
else:
break
reports.append('\n== SUMMARY ==\n')
for source in order:
@ -409,9 +416,14 @@ def recursive_build_report(from_repo, to_repo, *source_names,
if self_dependent:
reports.append('\nSelf-dependant packages:')
reports.extend('\t %s' % source.decode()
reports.extend('\t%s' % source.decode()
for source in sorted(self_dependent))
if cycles:
reports.append('\nCycles:')
reports.extend('\t%s' % ' '.join(source.decode() for source in c)
for c in cycles)
special = set()
for source_name in order:
source = to_repo.sources.get(source_name)
@ -422,7 +434,7 @@ def recursive_build_report(from_repo, to_repo, *source_names,
if special:
reports.append('\nThe followng packages are special:')
reports.extend('\t %s' % source.decode()
reports.extend('\t%s' % source.decode()
for source in sorted(special))
return '\n'.join(reports)