Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion vinca/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@ def conda_index_shadowed_packages(distro, vinca_conf):
return names


def expected_build_number(default_build_number, pkg_name, vinca_conf):
"""The build number a package of this configuration gets: the mutex has its own
(mutex_package.build_number, e.g. a new build at the same version), the others
the distribution's unless pkg_additional_info.yaml overrides it."""
mutex_config = parse_mutex_package_config(vinca_conf)
if mutex_config and pkg_name == mutex_config["name"]:
return mutex_config["build_number"]
return get_pkg_build_number(default_build_number, pkg_name, vinca_conf)


def get_selected_packages(distro, vinca_conf):
selected_packages = set()
skipped_packages = set()
Expand Down Expand Up @@ -742,7 +752,7 @@ def main():
for _, pkg in all_pkgs.items():
is_built = False
if selected_bn is not None:
pkg_build_number = get_pkg_build_number(
pkg_build_number = expected_build_number(
selected_bn, pkg["name"], vinca_conf
)
if pkg["build_number"] == pkg_build_number:
Expand Down
9 changes: 7 additions & 2 deletions vinca/mutex.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

from vinca.distro import Distro

_REQUIRED_FIELDS = ("name", "version", "upper_bound", "run_constraints")
# run_constraints is optional: a mutex only has to keep one distribution per environment
_REQUIRED_FIELDS = ("name", "version", "upper_bound")


def parse_mutex_package_config(vinca_conf: dict[str, Any]) -> dict[str, Any] | None:
Expand Down Expand Up @@ -102,7 +103,11 @@ def generate_mutex_package_recipe(
"script": "",
},
"requirements": {
"run_constraints": mutex_config["run_constraints"],
**(
{"run_constraints": mutex_config["run_constraints"]}
if mutex_config.get("run_constraints")
else {}
),
"run_exports": {
"weak": [
f"${{{{ pin_subpackage('{name}', upper_bound='{mutex_config['upper_bound']}') }}}}"
Expand Down
6 changes: 5 additions & 1 deletion vinca/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,12 @@ def write_recipe(source, outputs, vinca_conf, distro, single_file=True):
o, distro, vinca_conf
)

# an output's own build number (e.g. mutex_package.build_number) wins
# over the distribution's; pkg_additional_info.yaml overrides both
meta["build"]["number"] = get_pkg_build_number(
vinca_conf.get("build_number", 0), package_name, vinca_conf
o.get("build", {}).get("number", vinca_conf.get("build_number", 0)),
package_name,
vinca_conf,
)
meta["build"]["post_process"] = post_process_items

Expand Down
67 changes: 67 additions & 0 deletions vinca/test_mutex_build_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""mutex_package.build_number: a new build of the mutex at the same version."""

from unittest.mock import Mock

import yaml

from vinca.main import expected_build_number
from vinca.mutex import generate_mutex_package_recipe
from vinca.template import write_recipe


def _conf(**extra):
conf = {
"ros_distro": "lyrical",
"build_number": 27,
"mutex_package": {
"name": "ros2-distro-mutex",
"version": "0.21.0",
"upper_bound": "x.x",
"build_number": 28,
},
"_pkg_additional_info": {"rclcpp": {"build_number": 30}},
"_tests": {},
}
conf.update(extra)
return conf


def test_expected_build_number_of_the_mutex_is_its_own():
assert expected_build_number(27, "ros2-distro-mutex", _conf()) == 28


def test_expected_build_number_of_other_packages():
conf = _conf()
assert expected_build_number(27, "ros2-rclcpp", conf) == 30
assert expected_build_number(27, "ros2-std-msgs", conf) == 27


def test_mutex_without_own_build_number_uses_the_distribution_one():
conf = _conf()
del conf["mutex_package"]["build_number"]
assert expected_build_number(27, "ros2-distro-mutex", conf) == 27


def test_mutex_recipe_keeps_its_build_number(tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
conf = _conf()
distro = Mock()
distro.name = "lyrical"
recipe = generate_mutex_package_recipe(conf, distro)
write_recipe({}, [recipe], conf, distro, single_file=False)
meta = yaml.safe_load(
(tmp_path / "recipes" / "ros2-distro-mutex" / "recipe.yaml").read_text()
)
assert meta["build"]["number"] == 28
assert meta["build"]["string"] == "lyrical_28"
# no (empty) run_constraints in the recipe
assert "run_constraints" not in meta["requirements"]


def test_mutex_with_run_constraints_keeps_them():
conf = _conf()
conf["mutex_package"]["run_constraints"] = ["libfoo 1.*"]
distro = Mock()
distro.name = "lyrical"
recipe = generate_mutex_package_recipe(conf, distro)
assert recipe["requirements"]["run_constraints"] == ["libfoo 1.*"]
Loading