Clear up "already provided" message

I got quite confused what this was trying to tell me at first.  It's
saying that you requested an element but another element already
provides that element, so we don't know which one to choose.

To help clarify the situation to the user, keep track of what is
providing elements so we can describe where the conflict came from.

Change-Id: Ie7471ac900a8cbee5684c928badd1b8ce6d3e3cf
This commit is contained in:
Ian Wienand 2016-03-10 14:52:02 +11:00
parent 5a5529fb84
commit 452f7b8d5a
2 changed files with 18 additions and 8 deletions

View File

@ -91,6 +91,7 @@ def expand_dependencies(user_elements, elements_dir=None):
final_elements = set(user_elements) final_elements = set(user_elements)
check_queue = collections.deque(user_elements) check_queue = collections.deque(user_elements)
provided = set() provided = set()
provided_by = collections.defaultdict(list)
while check_queue: while check_queue:
# bug #1303911 - run through the provided elements first to avoid # bug #1303911 - run through the provided elements first to avoid
@ -98,10 +99,15 @@ def expand_dependencies(user_elements, elements_dir=None):
element = check_queue.popleft() element = check_queue.popleft()
if element in provided: if element in provided:
continue continue
deps = dependencies(element, elements_dir) element_deps = dependencies(element, elements_dir)
provided.update(provides(element, elements_dir)) element_provides = provides(element, elements_dir)
check_queue.extend(deps - (final_elements | provided)) # save which elements provide another element for potential
final_elements.update(deps) # error message
for provide in element_provides:
provided_by[provide].append(element)
provided.update(element_provides)
check_queue.extend(element_deps - (final_elements | provided))
final_elements.update(element_deps)
if "operating-system" not in provided: if "operating-system" not in provided:
logger.error( logger.error(
@ -110,9 +116,11 @@ def expand_dependencies(user_elements, elements_dir=None):
conflicts = set(user_elements) & provided conflicts = set(user_elements) & provided
if conflicts: if conflicts:
logger.error("Following elements were explicitly required " logger.error(
"but are provided by other included elements: %s" % "The following elements are already provided by another element")
", ".join(conflicts)) for element in conflicts:
logger.error("%s : already provided by %s" %
(element, provided_by[element]))
sys.exit(-1) sys.exit(-1)
return final_elements - provided return final_elements - provided

View File

@ -141,7 +141,9 @@ class TestElementDeps(testtools.TestCase):
element_dependencies.expand_dependencies, element_dependencies.expand_dependencies,
['circular1', 'operating-system'], ['circular1', 'operating-system'],
elements_dir=self.element_dir) elements_dir=self.element_dir)
self.assertIn("provided by other included elements: operating-system", # ensure we get the error message about what's providing the
# conflicting package
self.assertIn("operating-system : already provided by ['circular1']",
self.log_fixture.output) self.log_fixture.output)