@@ -1977,10 +1977,11 @@ def result(self):
19771977
19781978class DepTracker :
19791979
1980- __slots__ = ('item' , 'isNew' , 'usedResult' )
1980+ __slots__ = ('item' , 'isNew' , 'usedResult' , 'depEntry' )
19811981
1982- def __init__ (self , item ):
1982+ def __init__ (self , item , depEntry ):
19831983 self .item = item
1984+ self .depEntry = depEntry
19841985 self .isNew = True
19851986 self .usedResult = False
19861987
@@ -2084,9 +2085,10 @@ class Dependency(object):
20842085 __slots__ = ('recipe' , 'envOverride' , 'provideGlobal' , 'inherit' ,
20852086 'use' , 'useEnv' , 'useTools' , 'useBuildResult' , 'useDeps' ,
20862087 'useSandbox' , 'condition' , 'toolOverride' , 'checkoutDep' ,
2087- 'alias' )
2088+ 'alias' , 'origin' )
20882089
2089- def __init__ (self , recipe , env , fwd , use , cond , tools , checkoutDep , inherit , alias ):
2090+ def __init__ (self , origin , recipe , env , fwd , use , cond , tools , checkoutDep , inherit , alias ):
2091+ self .origin = origin
20902092 self .recipe = recipe
20912093 self .envOverride = env
20922094 self .provideGlobal = fwd
@@ -2103,9 +2105,9 @@ def __init__(self, recipe, env, fwd, use, cond, tools, checkoutDep, inherit, ali
21032105 self .alias = alias
21042106
21052107 @staticmethod
2106- def __parseEntry (dep , env , fwd , use , cond , tools , checkoutDep , inherit ):
2108+ def __parseEntry (origin , dep , env , fwd , use , cond , tools , checkoutDep , inherit ):
21072109 if isinstance (dep , str ):
2108- return [ Recipe .Dependency (dep , env , fwd , use , cond , tools , checkoutDep ,
2110+ return [ Recipe .Dependency (origin , dep , env , fwd , use , cond , tools , checkoutDep ,
21092111 inherit , None ) ]
21102112 else :
21112113 envOverride = dep .get ("environment" )
@@ -2126,23 +2128,24 @@ def __parseEntry(dep, env, fwd, use, cond, tools, checkoutDep, inherit):
21262128 name = dep .get ("name" )
21272129 if name :
21282130 if "depends" in dep :
2129- raise ParseError ("A dependency must not use 'name' and 'depends' at the same time!" )
2130- return [ Recipe .Dependency (name , env , fwd , use , cond , tools ,
2131+ raise ParseError ("A dependency must not use 'name' and 'depends' at the same time!" ,
2132+ help = f"The offending entries 'name' attribute is '{ name } '" )
2133+ return [ Recipe .Dependency (origin , name , env , fwd , use , cond , tools ,
21312134 checkoutDep , inherit , dep .get ("alias" )) ]
21322135 dependencies = dep .get ("depends" )
21332136 if dependencies is None :
21342137 raise ParseError ("Either 'name' or 'depends' required for dependencies!" )
2135- return Recipe .Dependency .parseEntries (dependencies , env , fwd ,
2138+ return Recipe .Dependency .parseEntries (origin , dependencies , env , fwd ,
21362139 use , cond , tools ,
21372140 checkoutDep , inherit )
21382141
21392142 @staticmethod
2140- def parseEntries (deps , env = {}, fwd = False , use = ["result" , "deps" ],
2143+ def parseEntries (origin , deps , env = {}, fwd = False , use = ["result" , "deps" ],
21412144 cond = None , tools = {}, checkoutDep = False , inherit = True ):
21422145 """Returns an iterator yielding all dependencies as flat list"""
21432146 # return flattened list of dependencies
21442147 return chain .from_iterable (
2145- Recipe .Dependency .__parseEntry (dep , env , fwd , use , cond , tools ,
2148+ Recipe .Dependency .__parseEntry (origin , dep , env , fwd , use , cond , tools ,
21462149 checkoutDep , inherit )
21472150 for dep in deps )
21482151
@@ -2205,7 +2208,7 @@ def __init__(self, recipeSet, recipe, layer, sourceFile, baseDir, packageName, b
22052208 self .__inherit = recipe .get ("inherit" , [])
22062209 self .__anonBaseClass = anonBaseClass
22072210 self .__defaultScriptLanguage = scriptLanguage
2208- self .__deps = list (Recipe .Dependency .parseEntries (recipe .get ("depends" , [])))
2211+ self .__deps = list (Recipe .Dependency .parseEntries (self , recipe .get ("depends" , [])))
22092212 self .__packageName = packageName
22102213 self .__baseName = baseName
22112214 self .__root = recipe .get ("root" )
@@ -2628,14 +2631,16 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
26282631 # A dependency should be named only once. Hence we can
26292632 # optimistically create the DepTracker object. If the dependency is
26302633 # named more than one we make sure that it is the same variant.
2631- depTrack = thisDeps .setdefault (p .getName (), DepTracker (depRef ))
2634+ depTrack = thisDeps .setdefault (p .getName (), DepTracker (depRef , dep ))
26322635 if depTrack .prime ():
26332636 directPackages .append (depRef )
26342637 elif depCoreStep .variantId != depTrack .item .refGetDestination ().variantId :
26352638 self .__raiseIncompatibleLocal (depCoreStep )
26362639 else :
2640+ sources = " and " .join (set ([dep .origin .getPrimarySource (), depTrack .depEntry .origin .getPrimarySource ()]))
26372641 raise ParseError ("Duplicate dependency '{}'. Each dependency must only be named once!"
2638- .format (p .getName ()))
2642+ .format (p .getName ()),
2643+ help = f"The dependencies were declared in { sources } ." )
26392644
26402645 # Remember dependency diffs before changing them
26412646 origDepDiffTools = thisDepDiffTools
@@ -2704,7 +2709,7 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
27042709 name = depCoreStep .corePackage .getName ()
27052710 depTrack = thisDeps .get (name )
27062711 if depTrack is None :
2707- thisDeps [name ] = depTrack = DepTracker (depRef )
2712+ thisDeps [name ] = depTrack = DepTracker (depRef , None )
27082713
27092714 if depTrack .prime ():
27102715 indirectPackages .append (depRef )
0 commit comments