Skip to content

Commit 73231b0

Browse files
committed
input: support for variable depends
1 parent 4d00b85 commit 73231b0

File tree

2 files changed

+96
-18
lines changed

2 files changed

+96
-18
lines changed

pym/bob/input.py

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,16 +2220,6 @@ def coDet(r):
22202220
if self.__jobServer is None:
22212221
self.__jobServer = False
22222222

2223-
# check provided dependencies
2224-
availDeps = [ d.recipe for d in self.__deps ]
2225-
providedDeps = set()
2226-
for pattern in self.__provideDeps:
2227-
l = set(d for d in availDeps if fnmatch.fnmatchcase(d, pattern))
2228-
if not l:
2229-
raise ParseError("Unknown dependency '{}' in provideDeps".format(pattern))
2230-
providedDeps |= l
2231-
self.__provideDeps = providedDeps
2232-
22332223
# Evaluate root property
22342224
if isinstance(self.__root, str) or isinstance(self.__root, IfExpression):
22352225
self.__root = rootEnv.evaluate(self.__root, "root")
@@ -2346,6 +2336,7 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
23462336
directPackages = []
23472337
indirectPackages = []
23482338
provideDeps = UniquePackageList(stack, self.__raiseIncompatibleProvided)
2339+
maybeProvideDeps = {}
23492340
checkoutDeps = []
23502341
results = []
23512342
depEnv = env.derive()
@@ -2355,11 +2346,20 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
23552346
depDiffSandbox = diffSandbox
23562347
depDiffTools = diffTools.copy()
23572348
thisDeps = {}
2349+
depVars = set()
2350+
resolvedDeps = []
23582351

2359-
for dep in self.__deps:
2352+
for d in self.__deps:
2353+
dep = copy.deepcopy(d)
23602354
env.setFunArgs({ "recipe" : self, "sandbox" : bool(sandbox) and sandboxEnabled,
23612355
"__tools" : tools })
23622356

2357+
depsEnv = env.derive()
2358+
depsEnv.touchReset()
2359+
dep.recipe = depsEnv.substitute(dep.recipe, "dependency::"+dep.recipe)
2360+
resolvedDeps.append(dep.recipe)
2361+
depVars = set([e for e in depsEnv.touchedKeys()])
2362+
23632363
if dep.condition and not all(env.evaluate(cond, "dependency "+dep.recipe)
23642364
for cond in dep.condition): continue
23652365

@@ -2449,10 +2449,24 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
24492449
if sandboxEnabled:
24502450
env.update(sandbox.environment)
24512451
if dep.provideGlobal: depEnv.update(sandbox.environment)
2452-
if dep.recipe in self.__provideDeps:
2453-
provideDeps.append(depRef)
2454-
provideDeps.extend(CoreRef(d, [p.getName()], origDepDiffTools, origDepDiffSandbox)
2455-
for d in depCoreStep.providedDeps)
2452+
2453+
l = [depRef]
2454+
l.append([CoreRef(d, [p.getName()], origDepDiffTools, origDepDiffSandbox)
2455+
for d in depCoreStep.providedDeps])
2456+
maybeProvideDeps[dep.recipe] = l
2457+
2458+
# check provided dependencies
2459+
providedDeps = set()
2460+
for pattern in self.__provideDeps:
2461+
pattern = env.substitute(pattern, "providedDep::"+pattern)
2462+
l = set(d for d in resolvedDeps if fnmatch.fnmatchcase(d, pattern))
2463+
if not l:
2464+
raise ParseError("Unknown dependency '{}' in provideDeps".format(pattern))
2465+
providedDeps |= l
2466+
2467+
for recipe in providedDeps:
2468+
provideDeps.append(maybeProvideDeps[recipe][0])
2469+
provideDeps.extend(maybeProvideDeps[recipe][1])
24562470

24572471
# Filter indirect packages and add to result list if necessary. Most
24582472
# likely there are many duplicates that are dropped.
@@ -2544,7 +2558,7 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
25442558

25452559
# optional checkout step
25462560
if self.__checkout != (None, None, None) or self.__checkoutSCMs or self.__checkoutAsserts:
2547-
checkoutDigestEnv = env.prune(self.__checkoutVars)
2561+
checkoutDigestEnv = env.prune(self.__checkoutVars | depVars)
25482562
checkoutEnv = ( env.prune(self.__checkoutVars | self.__checkoutVarsWeak)
25492563
if self.__checkoutVarsWeak else checkoutDigestEnv )
25502564
checkoutUpdateIf = [
@@ -2570,7 +2584,7 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
25702584

25712585
# optional build step
25722586
if self.__build != (None, None, None):
2573-
buildDigestEnv = env.prune(self.__buildVars)
2587+
buildDigestEnv = env.prune(self.__buildVars | depVars)
25742588
buildEnv = ( env.prune(self.__buildVars | self.__buildVarsWeak)
25752589
if self.__buildVarsWeak else buildDigestEnv )
25762590
buildCoreStep = p.createCoreBuildStep(self.__build, buildDigestEnv, buildEnv,
@@ -2579,7 +2593,7 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
25792593
buildCoreStep = p.createInvalidCoreBuildStep([CoreRef(srcCoreStep)] + results)
25802594

25812595
# mandatory package step
2582-
packageDigestEnv = env.prune(self.__packageVars)
2596+
packageDigestEnv = env.prune(self.__packageVars | depVars)
25832597
packageEnv = ( env.prune(self.__packageVars | self.__packageVarsWeak)
25842598
if self.__packageVarsWeak else packageDigestEnv )
25852599
packageCoreStep = p.createCorePackageStep(self.__package, packageDigestEnv, packageEnv,

test/unit/test_input_recipeset.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,70 @@ def testInvalidMinVerStr(self):
251251

252252

253253
class TestDependencies(RecipesTmp, TestCase):
254+
def testVariableDeps(self):
255+
"""Test resolve of dependecies by environment substitution"""
256+
self.writeRecipe("root", """\
257+
root: True
258+
depends: [a]
259+
environment:
260+
A : "b"
261+
D : "c"
262+
buildScript: "true"
263+
packageScript: "true"
264+
""")
265+
self.writeRecipe("root2", """\
266+
root: True
267+
depends: [a, d]
268+
environment:
269+
A : "c"
270+
buildScript: "true"
271+
packageScript: "true"
272+
""")
273+
274+
self.writeRecipe("a", """\
275+
depends: [ "$A-foo" ]
276+
buildScript: "true"
277+
packageScript: "true"
278+
provideDeps: [ "$A-f*" ]
279+
provideVars:
280+
D: "e"
281+
""")
282+
283+
self.writeRecipe("b-foo", """\
284+
buildScript: "true"
285+
packageScript: "true"
286+
""")
287+
self.writeRecipe("c-foo", """\
288+
buildScript: "true"
289+
packageScript: "true"
290+
""")
291+
self.writeRecipe("d", """\
292+
depends:
293+
- name: a
294+
use: [environment, deps]
295+
- "$D"
296+
buildScript: "true"
297+
packageScript: "true"
298+
""")
299+
self.writeRecipe("e", """\
300+
buildScript: "true"
301+
packageScript: "true"
302+
""")
303+
304+
recipes = RecipeSet()
305+
recipes.parse()
306+
packages = recipes.generatePackages(lambda x,y: "unused")
307+
308+
p = packages.walkPackagePath("root/a/b-foo")
309+
self.assertEqual(p.getName(), "b-foo")
310+
p = packages.walkPackagePath("root2/a/c-foo")
311+
self.assertEqual(p.getName(), "c-foo")
312+
p = packages.walkPackagePath("root2/d/e")
313+
self.assertEqual(p.getName(), "e")
314+
#access via providedDeps
315+
p = packages.walkPackagePath("root/b-foo")
316+
self.assertEqual(p.getName(), "b-foo")
317+
254318
def testDuplicateRemoval(self):
255319
"""Test that provided dependencies do not replace real dependencies"""
256320
self.writeRecipe("root", """\

0 commit comments

Comments
 (0)