|
1 | 1 | import json |
| 2 | +import logging |
2 | 3 | import os |
3 | 4 | import shutil |
4 | 5 | import textwrap |
@@ -2329,3 +2330,82 @@ def test_version_takes_precedence_over_release_branch(self, tmp_path): |
2329 | 2330 | def test_extract_calver_minor_rejects_trailing_garbage(self): |
2330 | 2331 | with pytest.raises(ValueError, match="not a valid CalVer"): |
2331 | 2332 | _extract_calver_minor("2026.06.0-daily+143 trailing garbage") |
| 2333 | + |
| 2334 | + |
| 2335 | +class TestApplyDevSpecDependency: |
| 2336 | + """--dev-spec pins dependency-sourced dev versions, matched by channel.""" |
| 2337 | + |
| 2338 | + def _make_image(self, tmp_path, *, channel="daily", extra_dev_versions=None): |
| 2339 | + """Return a minimal Image with one positron daily dependency dev version.""" |
| 2340 | + dev_version = { |
| 2341 | + "sourceType": "dependency", |
| 2342 | + "dependency": "positron", |
| 2343 | + "prerelease": True, |
| 2344 | + "channel": channel, |
| 2345 | + "os": [{"name": "Ubuntu 24.04", "primary": True}], |
| 2346 | + } |
| 2347 | + doc = BakeryConfigDocument( |
| 2348 | + base_path=tmp_path, |
| 2349 | + **{ |
| 2350 | + "repository": {"url": "https://github.com/posit-dev/test"}, |
| 2351 | + "images": [ |
| 2352 | + { |
| 2353 | + "name": "test-positron-init", |
| 2354 | + "devVersions": [dev_version, *(extra_dev_versions or [])], |
| 2355 | + } |
| 2356 | + ], |
| 2357 | + }, |
| 2358 | + ) |
| 2359 | + return doc.images[0] |
| 2360 | + |
| 2361 | + def test_version_pins_dependency_dev_version(self, tmp_path): |
| 2362 | + """version in DevBuildSpec sets version_override on the matching dependency dev version.""" |
| 2363 | + image = self._make_image(tmp_path) |
| 2364 | + spec = DevBuildSpec(version="2026.06.0-99", channel="daily") |
| 2365 | + settings = BakerySettings(dev_versions=DevVersionInclusionEnum.ONLY, dev_spec=spec) |
| 2366 | + _apply_dev_spec(image, settings) |
| 2367 | + assert image.devVersions[0].version_override == "2026.06.0-99" |
| 2368 | + |
| 2369 | + def test_channel_mismatch_is_noop(self, tmp_path): |
| 2370 | + """A dev-spec channel that matches no dev version leaves version_override unset.""" |
| 2371 | + image = self._make_image(tmp_path, channel="daily") |
| 2372 | + spec = DevBuildSpec(version="2026.06.0-99", channel="preview") |
| 2373 | + settings = BakerySettings(dev_versions=DevVersionInclusionEnum.ONLY, dev_spec=spec) |
| 2374 | + _apply_dev_spec(image, settings) |
| 2375 | + assert image.devVersions[0].version_override is None |
| 2376 | + |
| 2377 | + def test_release_branch_ignored_for_dependency(self, tmp_path): |
| 2378 | + """release_branch is not applicable to dependency dev versions and is not set.""" |
| 2379 | + image = self._make_image(tmp_path) |
| 2380 | + spec = DevBuildSpec(version="2026.06.0-99", channel="daily", release_branch="apple-blossom") |
| 2381 | + settings = BakerySettings(dev_versions=DevVersionInclusionEnum.ONLY, dev_spec=spec) |
| 2382 | + _apply_dev_spec(image, settings) |
| 2383 | + dv = image.devVersions[0] |
| 2384 | + assert dv.version_override == "2026.06.0-99" |
| 2385 | + assert not hasattr(dv, "release_branch") |
| 2386 | + |
| 2387 | + def test_branch_only_spec_skips_dependency_with_warning(self, tmp_path, caplog): |
| 2388 | + """A branch-only spec cannot pin a dependency dev version: warns, leaves override None.""" |
| 2389 | + image = self._make_image(tmp_path) |
| 2390 | + spec = DevBuildSpec(release_branch="apple-blossom") |
| 2391 | + settings = BakerySettings(dev_versions=DevVersionInclusionEnum.ONLY, dev_spec=spec) |
| 2392 | + with caplog.at_level(logging.WARNING): |
| 2393 | + _apply_dev_spec(image, settings) |
| 2394 | + assert image.devVersions[0].version_override is None |
| 2395 | + warnings = [r for r in caplog.records if r.levelno == logging.WARNING] |
| 2396 | + assert len(warnings) == 1 |
| 2397 | + assert "cannot pin a dependency-sourced dev version" in warnings[0].message |
| 2398 | + |
| 2399 | + def test_ambiguous_candidates_raise(self, tmp_path): |
| 2400 | + """Two dev versions matching the same channel raise a disambiguation error.""" |
| 2401 | + extra = { |
| 2402 | + "sourceType": "stream", |
| 2403 | + "product": "workbench", |
| 2404 | + "channel": "daily", |
| 2405 | + "os": [{"name": "Ubuntu 24.04", "primary": True}], |
| 2406 | + } |
| 2407 | + image = self._make_image(tmp_path, channel="daily", extra_dev_versions=[extra]) |
| 2408 | + spec = DevBuildSpec(version="2026.06.0-99", channel="daily") |
| 2409 | + settings = BakerySettings(dev_versions=DevVersionInclusionEnum.ONLY, dev_spec=spec) |
| 2410 | + with pytest.raises(ValueError, match="dev versions matching"): |
| 2411 | + _apply_dev_spec(image, settings) |
0 commit comments