Skip to content
Snippets Groups Projects
Commit 8ad42102 authored by Jonathan Maw's avatar Jonathan Maw
Browse files

_yamlcache.py: Use a project's junction name if present

This is required because if there are projects with the same name
loaded, that have elements in the same path, with the same contents,
they are considered the same, despite actually belonging to different
Projects.

This fixes buildstream issue #795
parent f6c184f5
No related branches found
No related tags found
Loading
Pipeline #38401947 failed
......@@ -68,7 +68,7 @@ class YamlCache():
# (bool): Whether the file is cached.
def is_cached(self, project, filepath):
cache_path = self._get_filepath(project, filepath)
project_name = project.name if project else ""
project_name = self._get_project_name(project)
try:
project_cache = self._project_caches[project_name]
if cache_path in project_cache.elements:
......@@ -167,7 +167,7 @@ class YamlCache():
# value (decorated dict): The data to put into the cache.
def put_from_key(self, project, filepath, key, value):
cache_path = self._get_filepath(project, filepath)
project_name = project.name if project else ""
project_name = self._get_project_name(project)
try:
project_cache = self._project_caches[project_name]
except KeyError:
......@@ -237,7 +237,7 @@ class YamlCache():
# (decorated dict): The parsed yaml from the cache, or None if the file isn't in the cache.
def _get(self, project, filepath, key):
cache_path = self._get_filepath(project, filepath)
project_name = project.name if project else ""
project_name = self._get_project_name(project)
try:
project_cache = self._project_caches[project_name]
try:
......@@ -253,6 +253,30 @@ class YamlCache():
pass
return None
# _get_project_name():
#
# Gets a name appropriate for Project. Projects must use their junction's
# name if present, otherwise elements with the same contents under the
# same path with identically-named projects are considered the same yaml
# object, despite existing in different Projects.
#
# Args:
# project (Project): The project this file is in, or None.
#
# Returns:
# (str): The project's junction's name if present, the project's name,
# or an empty string if there is no project
@staticmethod
def _get_project_name(project):
if project:
if project.junction:
project_name = project.junction.name
else:
project_name = project.name
else:
project_name = ""
return project_name
CachedProject = namedtuple('CachedProject', ['elements'])
......@@ -287,7 +311,7 @@ class BstPickler(pickle.Pickler):
if isinstance(obj, _yaml.ProvenanceFile):
if obj.project:
# ProvenanceFile's project object cannot be stored as it is.
project_tag = obj.project.name
project_tag = YamlCache._get_project_name(obj.project)
# ProvenanceFile's filename must be stored relative to the
# project, as the project dir may move.
name = os.path.relpath(obj.name, obj.project.directory)
......@@ -319,14 +343,17 @@ class BstUnpickler(pickle.Unpickler):
if project_tag is not None:
for p in self._context.get_projects():
if project_tag == p.name:
if p.junction and project_tag == p.junction.name:
project = p
break
elif project_tag == p.name:
project = p
break
name = os.path.join(project.directory, tagged_name)
if not project:
projects = [p.name for p in self._context.get_projects()]
projects = [YamlCache._get_project_name(p) for p in self._context.get_projects()]
raise pickle.UnpicklingError("No project with name {} found in {}"
.format(project_tag, projects))
else:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment