Skip to content

Commit a204a64

Browse files
committed
Rework variant sorting to more accurately follow versioning
Signed-off-by: Jonah Newton <jonah@jonahnewton.com.au>
1 parent 17ee8d5 commit a204a64

6 files changed

Lines changed: 70 additions & 22 deletions

File tree

src/rez/data/tests/solver/packages/missing_variant_requires/1/package.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ def commands():
55
pass
66

77
variants = [
8-
["noexist"],
9-
["nada"]
8+
["nada"],
9+
["noexist"]
1010
]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name = "test_prio_both_versions_equal_extra_package"
2+
version = "1.0"
3+
4+
variants = [["python-2.6.0", "nada"], ["python-2.6.0"]]

src/rez/solver.py

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -400,14 +400,19 @@ def sort(self):
400400
401401
version_priority:
402402
- sort by highest versions of packages shared with request;
403-
- THEN least number of additional packages added to solve;
404-
- THEN highest versions of additional packages;
405-
- THEN alphabetical on name of additional packages;
406-
- THEN variant index.
403+
- THEN highest versions of additional packages common to all variants;
404+
- THEN highest number of packages shared with request;
405+
- THEN lowest number of additional packages not common to all variants;
406+
- THEN alphabetical on name of any remaining additional packages.
407+
- THEN variant index;
407408
408409
intersection_priority:
409410
- sort by highest number of packages shared with request;
410-
- THEN sort according to version_priority
411+
- THEN highest versions of packages shared with request;
412+
- THEN highest versions of additional packages common to all variants;
413+
- THEN lowest number of additional packages not common to all variants;
414+
- THEN alphabetical on name of any remaining additional packages.
415+
- THEN variant index;
411416
412417
Note:
413418
In theory 'variant.index' should never factor into the sort unless
@@ -420,9 +425,28 @@ def sort(self):
420425
if self.sorted:
421426
return
422427

428+
requested_names = {
429+
request.name for request in self.solver.request_list
430+
if not request.conflict
431+
}
432+
433+
common_additional_names = None
434+
for variant in self.variants:
435+
variant_additional_names = {
436+
request.name
437+
for request in variant.requires_list
438+
if not request.conflict and request.name not in requested_names
439+
}
440+
441+
if common_additional_names is None:
442+
common_additional_names = variant_additional_names
443+
else:
444+
common_additional_names &= variant_additional_names
445+
446+
common_additional_names = common_additional_names or set()
447+
423448
def key(variant):
424449
requested_key = []
425-
names = set()
426450

427451
for i, request in enumerate(self.solver.request_list):
428452
if not request.conflict:
@@ -431,26 +455,32 @@ def key(variant):
431455
orderer = get_orderer(req.name, orderers=self.solver.package_orderers or {})
432456
range_key = orderer.sort_key(req.name, req.range)
433457
requested_key.append((-i, range_key))
434-
names.add(req.name)
435458

436-
additional_key = []
459+
common_additional_key = []
460+
non_common_additional_key = []
437461
for request in variant.requires_list:
438-
if not request.conflict and request.name not in names:
462+
if not request.conflict and request.name not in requested_names:
439463
orderer = get_orderer(request.name, orderers=self.solver.package_orderers)
440464
range_key = orderer.sort_key(request.name, request.range)
441-
additional_key.append((range_key, request.name))
465+
key_item = (range_key, request.name)
466+
if request.name in common_additional_names:
467+
common_additional_key.append(key_item)
468+
else:
469+
non_common_additional_key.append(key_item)
442470

471+
443472
if (VariantSelectMode[config.variant_select_mode] == VariantSelectMode.version_priority):
444473
k = (requested_key,
445-
additional_key,
474+
common_additional_key,
475+
len(requested_key),
476+
-len(non_common_additional_key),
446477
variant.index)
447478
else: # VariantSelectMode.intersection_priority
448479
k = (len(requested_key),
449-
requested_key,
450-
-len(additional_key),
451-
additional_key,
452-
variant.index)
453-
480+
requested_key,
481+
common_additional_key,
482+
-len(non_common_additional_key),
483+
variant.index)
454484
return k
455485

456486
self.variants.sort(key=key, reverse=True)

src/rez/tests/test_completion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def _eq(prefix, expected_completions):
5454
"test_variant_split_start", "test_variant_split_mid1",
5555
"test_variant_split_mid2", "test_variant_split_end", "missing_variant_requires",
5656
"test_weakly_reference_requires", "test_weakly_reference_variant",
57-
"test_prio_both_base", "test_prio_both_extra_package", "test_prio_lower_extra_package", "test_prio_higher_extra_package", "test_prio_both_base_reverse", "test_prio_both_extra_package_reverse", "test_prio_lower_extra_package_reverse", "test_prio_higher_extra_package_reverse"])
57+
"test_prio_both_base", "test_prio_both_extra_package", "test_prio_lower_extra_package", "test_prio_higher_extra_package", "test_prio_both_base_reverse", "test_prio_both_extra_package_reverse", "test_prio_lower_extra_package_reverse", "test_prio_higher_extra_package_reverse", "test_prio_both_versions_equal_extra_package"])
5858
_eq("py", ["pybah", "pydad", "pyfoo", "pymum", "pyodd", "pyson",
5959
"pysplit", "python", "pyvariants"])
6060
_eq("pys", ["pyson", "pysplit"])

src/rez/tests/test_packages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
'test_weakly_reference_variant-2.0',
6464
'test_prio_both_extra_package-1.0',
6565
'test_prio_both_base-1.0',
66+
'test_prio_both_versions_equal_extra_package-1.0',
6667
'test_prio_lower_extra_package-1.0',
6768
'test_prio_higher_extra_package-1.0',
6869
'test_prio_both_extra_package_reverse-1.0',

src/rez/tests/test_solver.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def test_12_missing_variant_requires(self):
260260
self._solve(["missing_variant_requires"], [])
261261

262262
config.override("error_on_missing_variant_requires", False)
263-
self._solve(["missing_variant_requires"], ["nada[]", "missing_variant_requires-1[1]"])
263+
self._solve(["missing_variant_requires"], ["nada[]", "missing_variant_requires-1[0]"])
264264

265265
def test_13_resolve_weakly_reference_requires(self):
266266
"""Test resolving a package with a weakly referenced requirement."""
@@ -334,6 +334,19 @@ def test_15_version_priority_extra_packages(self):
334334
["python-2.7.0[]", "test_prio_both_base-1.0[1]", "nada[]"],
335335
perms_same_packages=True)
336336

337+
self._solve(["test_prio_both_versions_equal_extra_package"],
338+
["python-2.6.0[]", "test_prio_both_versions_equal_extra_package-1.0[1]"],
339+
perms_same_packages=True)
340+
self._solve(["test_prio_both_versions_equal_extra_package", "python"],
341+
["python-2.6.0[]", "test_prio_both_versions_equal_extra_package-1.0[1]"],
342+
perms_same_packages=True)
343+
self._solve(["test_prio_both_versions_equal_extra_package", "python", "nada"],
344+
["python-2.6.0[]", "nada[]", "test_prio_both_versions_equal_extra_package-1.0[0]"],
345+
perms_same_packages=True)
346+
self._solve(["test_prio_both_versions_equal_extra_package", "nada"],
347+
["nada[]", "python-2.6.0[]", "test_prio_both_versions_equal_extra_package-1.0[0]"],
348+
perms_same_packages=True)
349+
337350
self._solve(["test_prio_lower_extra_package_reverse"],
338351
["python-2.7.0[]", "test_prio_lower_extra_package_reverse-1.0[0]"],
339352
perms_same_packages=True)
@@ -405,7 +418,7 @@ def test_16_intersection_priority_extra_packages(self):
405418
perms_same_packages=True)
406419

407420
self._solve(["test_prio_higher_extra_package"],
408-
["python-2.6.0[]", "test_prio_higher_extra_package-1.0[0]"],
421+
["nada[]", "python-2.7.0[]", "test_prio_higher_extra_package-1.0[1]"],
409422
perms_same_packages=True)
410423
self._solve(["test_prio_higher_extra_package", "python"],
411424
["python-2.7.0[]", "nada[]", "test_prio_higher_extra_package-1.0[1]"])
@@ -465,7 +478,7 @@ def test_16_intersection_priority_extra_packages(self):
465478
perms_same_packages=True)
466479

467480
self._solve(["test_prio_higher_extra_package_reverse"],
468-
["python-2.6.0[]", "test_prio_higher_extra_package_reverse-1.0[1]"],
481+
["nada[]", "python-2.7.0[]", "test_prio_higher_extra_package_reverse-1.0[0]"],
469482
perms_same_packages=True)
470483
self._solve(["test_prio_higher_extra_package_reverse", "python"],
471484
["python-2.7.0[]", "nada[]", "test_prio_higher_extra_package_reverse-1.0[0]"])

0 commit comments

Comments
 (0)