Skip to content

Commit

Permalink
Merge pull request #603 from jkloetzke/fix-properties-crash
Browse files Browse the repository at this point in the history
Fix potential crash with additional properties and multiple layers
  • Loading branch information
jkloetzke authored Dec 21, 2024
2 parents e794980 + bc8b9d8 commit d990c9c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 29 deletions.
5 changes: 5 additions & 0 deletions doc/manual/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2050,6 +2050,11 @@ Bob will either invoke ``bash`` or ``pwsh``/``powershell`` as script
interpreter. In either case the command must be present in
``$PATH``/``%PATH%``.

.. important::
Each layer configures the default language individually. That is, layers
with higher precedence will not override the setting of layers with lower
precedence.

.. _configuration-config-usr:

User configuration (default.yaml)
Expand Down
63 changes: 34 additions & 29 deletions pym/bob/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -3524,7 +3524,35 @@ def __parse(self, envOverrides, platform, recipesRoot=""):
os.path.join(os.path.expanduser("~"), '.config')), 'bob', 'default.yaml'))

# Begin with root layer
self.__parseLayer(LayerSpec(""), "9999", recipesRoot, None)
allLayers = self.__parseLayer(LayerSpec(""), "9999", recipesRoot, None)

# Parse all recipes and classes of all layers. Need to be done last
# because only by now we have loaded all plugins.
for layer, rootDir, scriptLanguage in allLayers:
classesDir = os.path.join(rootDir, 'classes')
for root, dirnames, filenames in os.walk(classesDir):
for path in fnmatch.filter(filenames, "[!.]*.yaml"):
try:
[r] = Recipe.loadFromFile(self, layer, classesDir,
os.path.relpath(os.path.join(root, path), classesDir),
self.__properties, self.__classSchema, False)
self.__addClass(r)
except ParseError as e:
e.pushFrame(path)
raise

recipesDir = os.path.join(rootDir, 'recipes')
for root, dirnames, filenames in os.walk(recipesDir):
for path in fnmatch.filter(filenames, "[!.]*.yaml"):
try:
recipes = Recipe.loadFromFile(self, layer, recipesDir,
os.path.relpath(os.path.join(root, path), recipesDir),
self.__properties, self.__recipeSchema, True, scriptLanguage)
for r in recipes:
self.__addRecipe(r)
except ParseError as e:
e.pushFrame(path)
raise

# Out-of-tree builds may have a dedicated default.yaml
if recipesRoot:
Expand Down Expand Up @@ -3614,7 +3642,7 @@ def __parseLayer(self, layerSpec, maxVer, recipesRoot, upperLayer):
layer = upperLayer + "/" + layer

if layer in self.__layers:
return
return []

if managedLayers:
# SCM backed layers are in build dir, regular layers are in
Expand Down Expand Up @@ -3656,8 +3684,9 @@ def __parseLayer(self, layerSpec, maxVer, recipesRoot, upperLayer):

# First parse any sub-layers. Their settings have a lower precedence
# and may be overwritten by higher layers.
allLayers = []
for l in config.get("layers", []):
self.__parseLayer(l, maxVer, recipesRoot, layer)
allLayers.extend(self.__parseLayer(l, maxVer, recipesRoot, layer))

# Load plugins and re-create schemas as new keys may have been added
self.__loadPlugins(rootDir, layer, config.get("plugins", []))
Expand All @@ -3671,32 +3700,8 @@ def __parseLayer(self, layerSpec, maxVer, recipesRoot, upperLayer):
setColorMode(self._colorModeConfig or self.__uiConfig.get('color', 'auto'))
setParallelTUIThreshold(self.__uiConfig.get('parallelTUIThreshold', 16))

# finally parse recipes
classesDir = os.path.join(rootDir, 'classes')
for root, dirnames, filenames in os.walk(classesDir):
for path in fnmatch.filter(filenames, "[!.]*.yaml"):
try:
[r] = Recipe.loadFromFile(self, layer, classesDir,
os.path.relpath(os.path.join(root, path), classesDir),
self.__properties, self.__classSchema, False)
self.__addClass(r)
except ParseError as e:
e.pushFrame(path)
raise

scriptLanguage = config["scriptLanguage"]
recipesDir = os.path.join(rootDir, 'recipes')
for root, dirnames, filenames in os.walk(recipesDir):
for path in fnmatch.filter(filenames, "[!.]*.yaml"):
try:
recipes = Recipe.loadFromFile(self, layer, recipesDir,
os.path.relpath(os.path.join(root, path), recipesDir),
self.__properties, self.__recipeSchema, True, scriptLanguage)
for r in recipes:
self.__addRecipe(r)
except ParseError as e:
e.pushFrame(path)
raise
allLayers.append((layer, rootDir, config["scriptLanguage"]))
return allLayers

def __parseUserConfig(self, fileName):
cfg = self.loadYaml(fileName, self.__userConfigSchema)
Expand Down

0 comments on commit d990c9c

Please sign in to comment.