Skip to content
This repository was archived by the owner on Aug 12, 2025. It is now read-only.

Commit 63b8ec0

Browse files
Explicitly forbid workspace vendoring
The ability to vendor dependencies in projects that make use of workspaces was introduced in Go 1.22. Cachito currently does not support the use of "go work vendor", so this commit introduces an explicit check for that scenario and a clearer error message. Note that by design, Go does not allow the use of "go mod vendor" if workspaces are present, so the check assumes that the existence of a vendor folder in a project with workspaces means that workspace vendoring is being used. For more info, see: - https://go.dev/doc/go1.22#tools - golang/go#60056 Signed-off-by: Bruno Pimentel <bpimente@redhat.com>
1 parent 95bdbdf commit 63b8ec0

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

cachito/workers/pkg_managers/gomod.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ def resolve_gomod(
382382
flags, app_source_path, worker_config.cachito_gomod_strict_vendor
383383
)
384384
if should_vendor:
385+
_vet_workspace_vendoring(go, run_params)
385386
downloaded_modules = _vendor_deps(go, run_params, can_make_changes, git_dir_path)
386387
else:
387388
log.info("Downloading the gomod dependencies")
@@ -506,6 +507,18 @@ def go_list_deps(pattern: Literal["./...", "all"]) -> Iterator[GoPackage]:
506507
}
507508

508509

510+
def _vet_workspace_vendoring(go: Go, run_params: dict[str, Any]) -> None:
511+
go_work_file = go(["env", "GOWORK"], run_params).rstrip()
512+
513+
if not go_work_file or go_work_file == "off":
514+
return
515+
516+
vendor_dir = Path(go_work_file).parent / "vendor"
517+
518+
if vendor_dir.is_dir():
519+
raise UnsupportedFeature("Workspace vendoring introduced in Go 1.22 is not supported")
520+
521+
509522
def _set_local_modules_versions(
510523
local_modules: LocalModules,
511524
git_dir_path: Path,

tests/test_workers/test_pkg_managers/test_gomod.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ def test_resolve_gomod(
211211
@mock.patch("cachito.workers.pkg_managers.gomod.GoCacheTemporaryDirectory")
212212
@mock.patch("subprocess.run")
213213
@mock.patch("cachito.workers.pkg_managers.gomod.RequestBundleDir")
214+
@mock.patch("cachito.workers.pkg_managers.gomod._vet_workspace_vendoring")
214215
def test_resolve_gomod_vendor_dependencies(
216+
mock_vet_workspace_vendoring: mock.Mock,
215217
mock_bundle_dir: mock.Mock,
216218
mock_run: mock.Mock,
217219
mock_temp_dir: mock.Mock,
@@ -881,6 +883,43 @@ def test_vet_local_file_dep_paths_outside_repo():
881883
gomod._vet_local_file_dep_paths(dependencies, app_dir, git_dir)
882884

883885

886+
@pytest.mark.parametrize(
887+
"go_work_env",
888+
[
889+
pytest.param("go.work", id="go_work_set"),
890+
pytest.param("off", id="go_work_off"),
891+
pytest.param("", id="go_work_empty"),
892+
],
893+
)
894+
def test_vet_workspace_vendoring(
895+
go_work_env: str,
896+
tmp_path: Path,
897+
):
898+
go = mock.Mock()
899+
900+
# workspaces are enabled, no vendoring exists
901+
if go_work_env == "go.work":
902+
go.return_value = str(tmp_path / "go.work")
903+
904+
# workspaces are not enabled, vendoring exists
905+
else:
906+
go.return_value = go_work_env
907+
(tmp_path / "vendor").mkdir()
908+
909+
gomod._vet_workspace_vendoring(go, {})
910+
go.assert_called_once_with(["env", "GOWORK"], {})
911+
912+
913+
def test_vet_workspace_vendoring_fails(tmp_path: Path):
914+
go = mock.Mock()
915+
go.return_value = str(tmp_path / "go.work")
916+
(tmp_path / "vendor").mkdir()
917+
918+
expect_error = "Workspace vendoring introduced in Go 1.22 is not supported"
919+
with pytest.raises(UnsupportedFeature, match=expect_error):
920+
gomod._vet_workspace_vendoring(go, {})
921+
922+
884923
@pytest.mark.parametrize(
885924
"main_module_deps, pkg_deps_pre, pkg_deps_post",
886925
[

0 commit comments

Comments
 (0)