Jürg Billeter pushed to branch master at BuildStream / buildstream
Commits:
-
6fcfa452
by Jonathan Maw at 2018-12-03T13:21:05Z
-
d0f9c724
by James Ennis at 2018-12-03T13:21:05Z
-
f7581026
by Jürg Billeter at 2018-12-03T16:27:03Z
18 changed files:
- buildstream/_yamlcache.py
- tests/loader/junctions.py
- + tests/loader/junctions/inconsistent-names/elements/junction-A.bst
- + tests/loader/junctions/inconsistent-names/elements/junction-B-diff-name.bst
- + tests/loader/junctions/inconsistent-names/elements/target.bst
- + tests/loader/junctions/inconsistent-names/files/foo
- + tests/loader/junctions/inconsistent-names/junctionA/elements/app.bst
- + tests/loader/junctions/inconsistent-names/junctionA/elements/junction-B.bst
- + tests/loader/junctions/inconsistent-names/junctionA/elements/lib.bst
- + tests/loader/junctions/inconsistent-names/junctionA/files/app
- + tests/loader/junctions/inconsistent-names/junctionA/files/lib
- + tests/loader/junctions/inconsistent-names/junctionA/junctionB/base/baseimg
- + tests/loader/junctions/inconsistent-names/junctionA/junctionB/elements/base.bst
- + tests/loader/junctions/inconsistent-names/junctionA/junctionB/elements/lib2.bst
- + tests/loader/junctions/inconsistent-names/junctionA/junctionB/files/lib2
- + tests/loader/junctions/inconsistent-names/junctionA/junctionB/project.conf
- + tests/loader/junctions/inconsistent-names/junctionA/project.conf
- + tests/loader/junctions/inconsistent-names/project.conf
Changes:
| ... | ... | @@ -68,7 +68,7 @@ class YamlCache(): |
| 68 | 68 |
# (bool): Whether the file is cached.
|
| 69 | 69 |
def is_cached(self, project, filepath):
|
| 70 | 70 |
cache_path = self._get_filepath(project, filepath)
|
| 71 |
- project_name = project.name if project else ""
|
|
| 71 |
+ project_name = self.get_project_name(project)
|
|
| 72 | 72 |
try:
|
| 73 | 73 |
project_cache = self._project_caches[project_name]
|
| 74 | 74 |
if cache_path in project_cache.elements:
|
| ... | ... | @@ -167,7 +167,7 @@ class YamlCache(): |
| 167 | 167 |
# value (decorated dict): The data to put into the cache.
|
| 168 | 168 |
def put_from_key(self, project, filepath, key, value):
|
| 169 | 169 |
cache_path = self._get_filepath(project, filepath)
|
| 170 |
- project_name = project.name if project else ""
|
|
| 170 |
+ project_name = self.get_project_name(project)
|
|
| 171 | 171 |
try:
|
| 172 | 172 |
project_cache = self._project_caches[project_name]
|
| 173 | 173 |
except KeyError:
|
| ... | ... | @@ -237,7 +237,7 @@ class YamlCache(): |
| 237 | 237 |
# (decorated dict): The parsed yaml from the cache, or None if the file isn't in the cache.
|
| 238 | 238 |
def _get(self, project, filepath, key):
|
| 239 | 239 |
cache_path = self._get_filepath(project, filepath)
|
| 240 |
- project_name = project.name if project else ""
|
|
| 240 |
+ project_name = self.get_project_name(project)
|
|
| 241 | 241 |
try:
|
| 242 | 242 |
project_cache = self._project_caches[project_name]
|
| 243 | 243 |
try:
|
| ... | ... | @@ -253,6 +253,30 @@ class YamlCache(): |
| 253 | 253 |
pass
|
| 254 | 254 |
return None
|
| 255 | 255 |
|
| 256 |
+ # get_project_name():
|
|
| 257 |
+ #
|
|
| 258 |
+ # Gets a name appropriate for Project. Projects must use their junction's
|
|
| 259 |
+ # name if present, otherwise elements with the same contents under the
|
|
| 260 |
+ # same path with identically-named projects are considered the same yaml
|
|
| 261 |
+ # object, despite existing in different Projects.
|
|
| 262 |
+ #
|
|
| 263 |
+ # Args:
|
|
| 264 |
+ # project (Project): The project this file is in, or None.
|
|
| 265 |
+ #
|
|
| 266 |
+ # Returns:
|
|
| 267 |
+ # (str): The project's junction's name if present, the project's name,
|
|
| 268 |
+ # or an empty string if there is no project
|
|
| 269 |
+ @staticmethod
|
|
| 270 |
+ def get_project_name(project):
|
|
| 271 |
+ if project:
|
|
| 272 |
+ if project.junction:
|
|
| 273 |
+ project_name = project.junction.name
|
|
| 274 |
+ else:
|
|
| 275 |
+ project_name = project.name
|
|
| 276 |
+ else:
|
|
| 277 |
+ project_name = ""
|
|
| 278 |
+ return project_name
|
|
| 279 |
+ |
|
| 256 | 280 |
|
| 257 | 281 |
CachedProject = namedtuple('CachedProject', ['elements'])
|
| 258 | 282 |
|
| ... | ... | @@ -287,7 +311,7 @@ class BstPickler(pickle.Pickler): |
| 287 | 311 |
if isinstance(obj, _yaml.ProvenanceFile):
|
| 288 | 312 |
if obj.project:
|
| 289 | 313 |
# ProvenanceFile's project object cannot be stored as it is.
|
| 290 |
- project_tag = obj.project.name
|
|
| 314 |
+ project_tag = YamlCache.get_project_name(obj.project)
|
|
| 291 | 315 |
# ProvenanceFile's filename must be stored relative to the
|
| 292 | 316 |
# project, as the project dir may move.
|
| 293 | 317 |
name = os.path.relpath(obj.name, obj.project.directory)
|
| ... | ... | @@ -319,14 +343,14 @@ class BstUnpickler(pickle.Unpickler): |
| 319 | 343 |
|
| 320 | 344 |
if project_tag is not None:
|
| 321 | 345 |
for p in self._context.get_projects():
|
| 322 |
- if project_tag == p.name:
|
|
| 346 |
+ if YamlCache.get_project_name(p) == project_tag:
|
|
| 323 | 347 |
project = p
|
| 324 | 348 |
break
|
| 325 | 349 |
|
| 326 | 350 |
name = os.path.join(project.directory, tagged_name)
|
| 327 | 351 |
|
| 328 | 352 |
if not project:
|
| 329 |
- projects = [p.name for p in self._context.get_projects()]
|
|
| 353 |
+ projects = [YamlCache.get_project_name(p) for p in self._context.get_projects()]
|
|
| 330 | 354 |
raise pickle.UnpicklingError("No project with name {} found in {}"
|
| 331 | 355 |
.format(project_tag, projects))
|
| 332 | 356 |
else:
|
| ... | ... | @@ -47,6 +47,16 @@ def test_simple_build(cli, tmpdir, datafiles): |
| 47 | 47 |
assert(os.path.exists(os.path.join(checkoutdir, 'foo.txt')))
|
| 48 | 48 |
|
| 49 | 49 |
|
| 50 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 51 |
+def test_build_of_same_junction_used_twice(cli, tmpdir, datafiles):
|
|
| 52 |
+ project = os.path.join(str(datafiles), 'inconsistent-names')
|
|
| 53 |
+ |
|
| 54 |
+ # Check we can build a project that contains the same junction
|
|
| 55 |
+ # that is used twice, but named differently
|
|
| 56 |
+ result = cli.run(project=project, args=['build', 'target.bst'])
|
|
| 57 |
+ assert result.exit_code == 0
|
|
| 58 |
+ |
|
| 59 |
+ |
|
| 50 | 60 |
@pytest.mark.datafiles(DATA_DIR)
|
| 51 | 61 |
def test_nested_simple(cli, tmpdir, datafiles):
|
| 52 | 62 |
foo = os.path.join(str(datafiles), 'foo')
|
| 1 |
+kind: junction
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: junctionA
|
| 1 |
+kind: junction
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: junctionA/junctionB
|
| 1 |
+kind: import
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: files/foo
|
|
| 5 |
+depends:
|
|
| 6 |
+- filename: lib2.bst
|
|
| 7 |
+ junction: junction-B-diff-name.bst
|
|
| 8 |
+- filename: lib.bst
|
|
| 9 |
+ junction: junction-A.bst
|
| 1 |
+kind: import
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: files/app
|
|
| 5 |
+depends:
|
|
| 6 |
+- lib.bst
|
| 1 |
+kind: junction
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: junctionB
|
| 1 |
+kind: import
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: files/lib
|
|
| 5 |
+depends:
|
|
| 6 |
+- filename: base.bst
|
|
| 7 |
+ junction: junction-B.bst
|
| 1 |
+kind: import
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: base
|
| 1 |
+kind: import
|
|
| 2 |
+sources:
|
|
| 3 |
+- kind: local
|
|
| 4 |
+ path: files/lib2
|
|
| 5 |
+depends:
|
|
| 6 |
+- base.bst
|
| 1 |
+# Unique project name
|
|
| 2 |
+name: projectB
|
|
| 3 |
+ |
|
| 4 |
+# Subdirectory where elements are stored
|
|
| 5 |
+element-path: elements
|
| 1 |
+# Unique project name
|
|
| 2 |
+name: projectA
|
|
| 3 |
+ |
|
| 4 |
+# Subdirectory where elements are stored
|
|
| 5 |
+element-path: elements
|
| 1 |
+# Unique project name
|
|
| 2 |
+name: inconsistent-names
|
|
| 3 |
+ |
|
| 4 |
+# Subdirectory where elements are stored
|
|
| 5 |
+element-path: elements
|
