Skip to content

Commit

Permalink
fixup! input: add 'clean' dependency property
Browse files Browse the repository at this point in the history
  • Loading branch information
rhubert committed May 24, 2024
1 parent 2e1a20c commit f383aaf
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 44 deletions.
8 changes: 6 additions & 2 deletions doc/manual/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1291,10 +1291,14 @@ The following settings are supported:
| | | At the dependency both names will refer to the same |
| | | tool. |
+-------------+-----------------+-----------------------------------------------------+
| clean | Boolean | Drop all the environment and tools collected so far |
| | | for this dependency. This is mostly useful to make |
| inherit | Boolean | Inherit environment and tools available for this |
| | | dependency. |
| | | When set to "false" all the environment and tools |
| | | are dropped. This is mostly useful to make |
| | | an existing root-package become a dependency |
| | | of another root package. |
| | | |
| | | Default: "true" |
+-------------+-----------------+-----------------------------------------------------+

.. _configuration-recipes-env:
Expand Down
79 changes: 44 additions & 35 deletions pym/bob/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -1855,11 +1855,11 @@ class Recipe(object):
"""

class Dependency(object):
def __init__(self, recipe, env, fwd, use, cond, tools, checkoutDep, clean):
def __init__(self, recipe, env, fwd, use, cond, tools, checkoutDep, inherit):
self.recipe = recipe
self.envOverride = env
self.provideGlobal = fwd
self.clean = clean
self.inherit = inherit
self.use = use
self.useEnv = "environment" in self.use
self.useTools = "tools" in self.use
Expand All @@ -1871,9 +1871,9 @@ def __init__(self, recipe, env, fwd, use, cond, tools, checkoutDep, clean):
self.checkoutDep = checkoutDep

@staticmethod
def __parseEntry(dep, env, fwd, use, cond, tools, checkoutDep, clean):
def __parseEntry(dep, env, fwd, use, cond, tools, checkoutDep, inherit):
if isinstance(dep, str):
return [ Recipe.Dependency(dep, env, fwd, use, cond, tools, checkoutDep, clean) ]
return [ Recipe.Dependency(dep, env, fwd, use, cond, tools, checkoutDep, inherit) ]
else:
envOverride = dep.get("environment")
if envOverride:
Expand All @@ -1885,7 +1885,7 @@ def __parseEntry(dep, env, fwd, use, cond, tools, checkoutDep, clean):
tools.update(toolOverride)
fwd = dep.get("forward", fwd)
use = dep.get("use", use)
clean = dep.get("clean", clean)
inherit = dep.get("inherit", inherit)
newCond = dep.get("if")
if newCond is not None:
cond = cond + [newCond] if cond is not None else [ newCond ]
Expand All @@ -1894,22 +1894,22 @@ def __parseEntry(dep, env, fwd, use, cond, tools, checkoutDep, clean):
if name:
if "depends" in dep:
raise ParseError("A dependency must not use 'name' and 'depends' at the same time!")
return [ Recipe.Dependency(name, env, fwd, use, cond, tools, checkoutDep, clean) ]
return [ Recipe.Dependency(name, env, fwd, use, cond, tools, checkoutDep, inherit) ]
dependencies = dep.get("depends")
if dependencies is None:
raise ParseError("Either 'name' or 'depends' required for dependencies!")
return Recipe.Dependency.parseEntries(dependencies, env, fwd,
use, cond, tools,
checkoutDep, clean)
checkoutDep, inherit)

@staticmethod
def parseEntries(deps, env={}, fwd=False, use=["result", "deps"],
cond=None, tools={}, checkoutDep=False, clean=False):
cond=None, tools={}, checkoutDep=False, inherit=True):
"""Returns an iterator yielding all dependencies as flat list"""
# return flattened list of dependencies
return chain.from_iterable(
Recipe.Dependency.__parseEntry(dep, env, fwd, use, cond, tools,
checkoutDep, clean)
checkoutDep, inherit)
for dep in deps )

@staticmethod
Expand Down Expand Up @@ -2310,7 +2310,21 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
resolvedDeps = []

for dep in self.__deps:
env.setFunArgs({ "recipe" : self, "sandbox" : bool(sandbox) and sandboxEnabled,
thisDepEnv = depEnv
thisDepTools = depTools
thisDepDiffTools = depDiffTools
thisSandbox = sandbox
thisSandboxEnabled = sandboxEnabled
thisDepDiffSandbox = depDiffSandbox
if not dep.inherit:
thisDepEnv = self.getRecipeSet().getRootEnv()
thisDepTools = Env()
thisDepDiffTools = {}
thisDepDiffSandbox = ...
thisSandbox = None
thisSandboxEnabled = False

env.setFunArgs({ "recipe" : self, "sandbox" : bool(thisSandbox) and thisSandboxEnabled,
"__tools" : tools })

recipe = env.substitute(dep.recipe, "dependency::"+dep.recipe)
Expand All @@ -2319,41 +2333,36 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,
if dep.condition and not all(env.evaluate(cond, "dependency "+recipe)
for cond in dep.condition): continue

if dep.clean:
thisDepEnv = self.getRecipeSet().getRootEnv()
thisDepTools = Env()
thisDepDiffTools = Env()
if dep.toolOverride:
try:
thisDepTools = thisDepTools.derive({
k : depTools[v] for k,v in dep.toolOverride.items() })
except KeyError as e:
raise ParseError("Cannot remap unkown tool '{}' for dependency '{}'!"
.format(e.args[0], recipe))
thisDepDiffTools = thisDepDiffTools.copy()
thisDepDiffTools.update({
k : depDiffTools.get(v, v)
for k, v in dep.toolOverride.items() })
else:
if dep.toolOverride:
try:
thisDepTools = depTools.derive({
k : depTools[v] for k,v in dep.toolOverride.items() })
except KeyError as e:
raise ParseError("Cannot remap unkown tool '{}' for dependency '{}'!"
.format(e.args[0], recipe))
thisDepDiffTools = depDiffTools.copy()
thisDepDiffTools.update({
k : depDiffTools.get(v, v)
for k, v in dep.toolOverride.items() })
else:
thisDepTools = depTools
thisDepDiffTools = depDiffTools
thisDepTools = thisDepTools
thisDepDiffTools = thisDepDiffTools

thisDepEnv = depEnv.derive(
{ key : env.substitute(value, "depends["+recipe+"].environment["+key+"]")
for key, value in dep.envOverride.items() })
thisDepEnv = thisDepEnv.derive(
{ key : env.substitute(value, "depends["+recipe+"].environment["+key+"]")
for key, value in dep.envOverride.items() })

r = self.__recipeSet.getRecipe(recipe)
try:
if r.__packageName in stack:
raise ParseError("Recipes are cyclic (1st package in cylce)")
depStack = stack + [r.__packageName]
p, s = r.prepare(thisDepEnv, sandboxEnabled, depStates,
p, s = r.prepare(thisDepEnv, thisSandboxEnabled, depStates,
depSandbox, thisDepTools, depStack)
subTreePackages.add(p.getName())
subTreePackages.update(s)
depCoreStep = p.getCorePackageStep()
depRef = CoreRef(depCoreStep, [p.getName()], thisDepDiffTools, depDiffSandbox)
depRef = CoreRef(depCoreStep, [p.getName()], thisDepDiffTools, thisDepDiffSandbox)
except ParseError as e:
e.pushFrame(r.getPackageName())
raise e
Expand All @@ -2372,7 +2381,7 @@ def prepare(self, inputEnv, sandboxEnabled, inputStates, inputSandbox=None,

# Remember dependency diffs before changing them
origDepDiffTools = thisDepDiffTools
origDepDiffSandbox = depDiffSandbox
origDepDiffSandbox = thisDepDiffSandbox

# pick up various results of package
for (n, s) in states.items():
Expand Down Expand Up @@ -3574,7 +3583,7 @@ def __createSchemas(self):
schema.Optional('name') : str,
schema.Optional('use') : useClauses,
schema.Optional('forward') : bool,
schema.Optional('clean') : bool,
schema.Optional('inherit') : bool,
schema.Optional('environment') : VarDefineValidator("depends::environment"),
schema.Optional('if') : schema.Or(str, IfExpression),
schema.Optional('tools') : { toolNameSchema : toolNameSchema },
Expand Down
47 changes: 40 additions & 7 deletions test/unit/test_input_recipeset.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,8 @@ def testCheckoutDepVariants(self):

self.assertNotEqual(paVId, pbVId, "checkout steps are different")

def testCleanDep(self):
""" Test the `clean` property for dependencies """
def testDepInherit(self):
""" Test the `inherit` property for dependencies """

self.writeDefault(
{"environment" : {"DEFAULT" : "42" }})
Expand All @@ -665,11 +665,21 @@ def testCleanDep(self):
self.writeRecipe("a", """\
inherit: [foo]
depends:
- name: sandbox
use: [sandbox]
forward: True
- name: b-env
use: [environment]
forward: true
- name: b
clean: True
inherit: False
- name: c
inherit: False
environment:
C: "1"
tools:
c: foo
- d
packageScript: "true"
""")

Expand All @@ -684,24 +694,47 @@ def testCleanDep(self):
packageScript: "true"
""")

self.writeRecipe("c", """\
packageVars: [C]
packageTools: [c]
packageScript: "true"
""")

self.writeRecipe("d", """\
packageVars: [B]
packageTools: [foo]
packageScript: "true"
""")

self.writeRecipe("foo", """\
packageTools: [foo]
packageScript: "true"
provideTools:
foo: .
""")

self.writeRecipe("sandbox", """\
provideSandbox:
paths: ["."]
""")

recipes = RecipeSet()
recipes.parse()
packages = recipes.generatePackages(lambda x,y: "unused")
packages = recipes.generatePackages(lambda s,m: "unused", True)

pa_b = packages.walkPackagePath("a/b")
pb = packages.walkPackagePath("b")
pb_e = packages.walkPackagePath("a/b-env")
pc = packages.walkPackagePath("a/c")
pd = packages.walkPackagePath("a/d")
self.assertEqual(pa_b.getPackageStep().getVariantId(),
pb.getPackageStep().getVariantId())
self.assertEqual(
{"DEFAULT" : "42"},
pb.getPackageStep().getEnv())
self.assertEqual({"DEFAULT" : "42"}, pb.getPackageStep().getEnv())
self.assertEqual({"C" : "1"}, pc.getPackageStep().getEnv())
self.assertEqual(list(pc.getPackageStep().getTools()), ["c"])
self.assertEqual(pc.getPackageStep().getSandbox(), None)
self.assertNotEqual(pb_e.getPackageStep().getSandbox(), None)
self.assertNotEqual(pd.getPackageStep().getSandbox(), None)

class TestDependencyEnv(RecipesTmp, TestCase):
"""Tests related to "environment" block in dependencies"""
Expand Down

0 comments on commit f383aaf

Please sign in to comment.