Skip to content

Commit

Permalink
Explicitly forbid workspace vendoring
Browse files Browse the repository at this point in the history
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.

¹ golang/go#60056

Signed-off-by: Bruno Pimentel <[email protected]>
  • Loading branch information
brunoapimentel committed Jul 12, 2024
1 parent 95bdbdf commit 8f50224
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
13 changes: 13 additions & 0 deletions cachito/workers/pkg_managers/gomod.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ def resolve_gomod(
flags, app_source_path, worker_config.cachito_gomod_strict_vendor
)
if should_vendor:
_vet_workspace_vendoring(go, run_params)
downloaded_modules = _vendor_deps(go, run_params, can_make_changes, git_dir_path)
else:
log.info("Downloading the gomod dependencies")
Expand Down Expand Up @@ -506,6 +507,18 @@ def go_list_deps(pattern: Literal["./...", "all"]) -> Iterator[GoPackage]:
}


def _vet_workspace_vendoring(go: Go, run_params: dict[str, Any]) -> None:
go_work_file = go(["env", "GOWORK"], run_params).rstrip()

if not go_work_file or go_work_file == "off":
return

vendor_dir = Path(go_work_file).parent / "vendor"

if vendor_dir.is_dir():
raise UnsupportedFeature("Workspace vendoring introduced in Go 1.22 is not supported")


def _set_local_modules_versions(
local_modules: LocalModules,
git_dir_path: Path,
Expand Down
38 changes: 38 additions & 0 deletions tests/test_workers/test_pkg_managers/test_gomod.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ def test_resolve_gomod(
@mock.patch("cachito.workers.pkg_managers.gomod.GoCacheTemporaryDirectory")
@mock.patch("subprocess.run")
@mock.patch("cachito.workers.pkg_managers.gomod.RequestBundleDir")
@mock.patch("cachito.workers.pkg_managers.gomod._vet_workspace_vendoring")
def test_resolve_gomod_vendor_dependencies(
mock_vet_workspace_vendoring: mock.Mock,
mock_bundle_dir: mock.Mock,
mock_run: mock.Mock,
mock_temp_dir: mock.Mock,
Expand Down Expand Up @@ -881,6 +883,42 @@ def test_vet_local_file_dep_paths_outside_repo():
gomod._vet_local_file_dep_paths(dependencies, app_dir, git_dir)


@pytest.mark.parametrize(
"go_work_env, vendor_folder_exists, raise_error",
[
pytest.param("go.work", True, True, id="workspace_vendoring"),
pytest.param("go.work", False, False, id="workspaces_no_vendoring"),
pytest.param("off", True, False, id="go_work_off"),
pytest.param("", True, False, id="go_work_empty"),
],
)
def test_vet_workspace_vendoring(
go_work_env: str,
vendor_folder_exists: bool,
raise_error: bool,
tmp_path: Path,
):
go = mock.Mock()

if go_work_env == "go.work":
go.return_value = str(tmp_path / "go.work")
else:
go.return_value = go_work_env

if vendor_folder_exists:
(tmp_path / "vendor").mkdir()

expect_error = "Workspace vendoring introduced in Go 1.22 is not supported"

if raise_error:
with pytest.raises(UnsupportedFeature, match=expect_error):
gomod._vet_workspace_vendoring(go, {})
else:
gomod._vet_workspace_vendoring(go, {})

go.assert_called_once_with(["env", "GOWORK"], {})


@pytest.mark.parametrize(
"main_module_deps, pkg_deps_pre, pkg_deps_post",
[
Expand Down

0 comments on commit 8f50224

Please sign in to comment.