From 9bce3c5bacde32a717ad818cbf6465ca9197657e Mon Sep 17 00:00:00 2001 From: DRAKKKkk Date: Sat, 30 May 2026 13:54:36 +0530 Subject: [PATCH] fix(linters): pass build_base to linters and avoid hardcoded fallback in GpuLinter --- snapcraft/linters/base.py | 2 + snapcraft/linters/gpu_linter.py | 4 +- snapcraft/linters/linters.py | 4 +- tests/unit/linters/test_gpu_linter.py | 54 ++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/snapcraft/linters/base.py b/snapcraft/linters/base.py index 2c44f49d8b..00de3d9f99 100644 --- a/snapcraft/linters/base.py +++ b/snapcraft/linters/base.py @@ -93,10 +93,12 @@ def __init__( name: str, snap_metadata: "SnapMetadata", lint: models.Lint | None, + build_base: str | None = None, ): self._name = name self._snap_metadata = snap_metadata self._lint = lint or models.Lint(ignore=[]) + self._build_base = build_base @abc.abstractmethod def run(self) -> list[LinterIssue]: diff --git a/snapcraft/linters/gpu_linter.py b/snapcraft/linters/gpu_linter.py index 43ca28413b..a4b0e37fe8 100644 --- a/snapcraft/linters/gpu_linter.py +++ b/snapcraft/linters/gpu_linter.py @@ -83,9 +83,9 @@ def run(self) -> list[LinterIssue]: current_path = Path() issues: list[LinterIssue] = [] - base = self._snap_metadata.base or "core24" + base = self._snap_metadata.base or self._build_base or "core24" if base == "bare": - base = "core24" + base = self._build_base or "core24" elf_files = elf_utils.get_elf_files(current_path) diff --git a/snapcraft/linters/linters.py b/snapcraft/linters/linters.py index 22a7b3a86e..2f0773b7e3 100644 --- a/snapcraft/linters/linters.py +++ b/snapcraft/linters/linters.py @@ -136,7 +136,9 @@ def _update_status(status: LinterStatus, result: LinterResult) -> LinterStatus: return status -def run_linters(location: Path, *, lint: models.Lint | None) -> list[LinterIssue]: +def run_linters( + location: Path, *, lint: models.Lint | None, build_base: str | None = None +) -> list[LinterIssue]: """Run all the defined linters. :param location: The root of the snap payload subtree to run linters on. diff --git a/tests/unit/linters/test_gpu_linter.py b/tests/unit/linters/test_gpu_linter.py index 02a7ca20d1..be22fb2132 100644 --- a/tests/unit/linters/test_gpu_linter.py +++ b/tests/unit/linters/test_gpu_linter.py @@ -411,5 +411,57 @@ def test_gpu_linter_classic_confinement(mocker, new_dir, mock_elf_files, base, f issues = linters.run_linters(new_dir, lint=None) - # Classic confinement snaps should never trigger GPU linter warnings assert len(issues) == 0 + + +@pytest.mark.parametrize( + "base,build_base,expected_url", + [ + pytest.param( + "bare", + "core26", + "https://ubuntu.com/frame/docs/26/how-to/use-snap-graphics/", + id="bare-with-build-base", + ), + pytest.param( + None, + "core22", + "https://ubuntu.com/frame/docs/22/how-to/use-snap-graphics/", + id="none-with-build-base", + ), + pytest.param( + "bare", + None, + "https://ubuntu.com/frame/docs/24/how-to/use-snap-graphics/", + id="bare-no-build-base-fallback", + ), + ], +) +def test_gpu_linter_build_base(mocker, base, build_base, expected_url): + """Test that GPU linter respects build_base when base is bare or undefined.""" + # 1. Create a dummy file object + mock_elf = Mock() + mock_elf.path = "lib/x86_64-linux-gnu/libGL.so.1" + + # 2. Mock the file reader + mocker.patch( + "snapcraft.linters.gpu_linter.elf_utils.get_elf_files", return_value=[mock_elf] + ) + + # 3. Create a simple mock metadata object + mock_metadata = Mock() + mock_metadata.type = "app" + mock_metadata.confinement = "strict" + mock_metadata.base = base + + # 4. Instantiate the linter DIRECTLY + linter = GpuLinter( + name="gpu", snap_metadata=mock_metadata, lint=None, build_base=build_base + ) + + # 5. Run the linter + issues = linter.run() + + # 6. Verify the URL logic + assert len(issues) == 1 + assert issues[0].url == expected_url