Skip to content
Open
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
11 changes: 10 additions & 1 deletion rockcraft/extensions/go.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,23 @@ def project_name(self) -> str:
return self.yaml_data["name"]

def _check_project(self) -> None:
"""Check go.mod file exist in project."""
"""Check go.mod file and Go sources exist in project."""
if not (self.project_root / "go.mod").exists():
raise ExtensionError(
"missing go.mod file, it should be present in the project directory",
doc_slug="/reference/extensions/go-framework/#project-requirements",
logpath_report=False,
)

go_files = list(self.project_root.rglob("*.go"))
if not go_files:
raise ExtensionError(
"No Go source files found. The go-framework extension requires "
"at least one Go source file (typically with a main package).",
doc_slug="/reference/extensions/go-framework/#project-requirements",
logpath_report=False,
)

def _get_install_app_part(self) -> dict[str, Any]:
"""Generate install-app part with the Go plugin."""
install_app = self._get_nested(
Expand Down
39 changes: 39 additions & 0 deletions tests/unit/extensions/test_go.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def go_extension(mock_extensions):
@pytest.mark.usefixtures("go_extension")
def test_go_extension_default(tmp_path, go_input_yaml):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
applied = extensions.apply_extensions(tmp_path, go_input_yaml)

assert applied == {
Expand Down Expand Up @@ -91,6 +92,7 @@ def test_go_extension_default(tmp_path, go_input_yaml):
@pytest.mark.usefixtures("go_extension")
def test_go_extension_bare(tmp_path):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
go_input_yaml = {
"name": "foo-bar",
"extensions": ["go-framework"],
Expand Down Expand Up @@ -122,6 +124,36 @@ def test_go_extension_no_go_mod_file_error(tmp_path, go_input_yaml):
)


@pytest.mark.usefixtures("go_extension")
def test_go_extension_no_go_sources_error(tmp_path, go_input_yaml):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")

with pytest.raises(ExtensionError) as exc:
extensions.apply_extensions(tmp_path, go_input_yaml)

assert (
str(exc.value)
== "No Go source files found. The go-framework extension requires at least one "
"Go source file (typically with a main package)."
)
assert (
str(exc.value.doc_slug)
== "/reference/extensions/go-framework/#project-requirements"
)


@pytest.mark.usefixtures("go_extension")
def test_go_extension_detects_nested_go_sources(tmp_path, go_input_yaml):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
nested = tmp_path / "cmd" / "server"
nested.mkdir(parents=True)
(nested / "main.go").write_text("package main\n\nfunc main() {}\n")

applied = extensions.apply_extensions(tmp_path, go_input_yaml)

assert applied["services"]["go"]["command"] == "goprojectname"


@pytest.mark.usefixtures("go_extension")
@pytest.mark.parametrize("build_environment", [[], [{"OTHER_ENV_VAR": "val"}]])
def test_go_extension_base_bare(tmp_path, go_input_yaml, build_environment):
Expand All @@ -132,6 +164,7 @@ def test_go_extension_base_bare(tmp_path, go_input_yaml, build_environment):
"go-framework/install-app": {"build-environment": build_environment},
}
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
applied = extensions.apply_extensions(tmp_path, go_input_yaml)

assert "build-environment" in applied["parts"]["go-framework/install-app"]
Expand Down Expand Up @@ -171,6 +204,7 @@ def test_go_extension_overrides_organize(
tmp_path, go_input_yaml, organize, expected_organize
):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
if organize:
go_input_yaml["parts"] = {
"go-framework/install-app": {"organize": organize},
Expand All @@ -197,6 +231,7 @@ def test_go_extension_override_build_snaps(
tmp_path, go_input_yaml, build_packages, build_snaps, expected_build_snaps
):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
if build_snaps or build_packages:
go_input_yaml["parts"] = {
"go-framework/install-app": {
Expand All @@ -213,6 +248,7 @@ def test_go_extension_override_build_snaps(
@pytest.mark.usefixtures("go_extension")
def test_go_extension_override_service_go_command(tmp_path, go_input_yaml):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
go_input_yaml["parts"] = {
"go-framework/install-app": {
"organize": {
Expand All @@ -237,6 +273,7 @@ def test_go_extension_override_service_go_command(tmp_path, go_input_yaml):
@pytest.mark.usefixtures("go_extension")
def test_go_extension_extra_assets(tmp_path, go_input_yaml):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
(tmp_path / "static").mkdir()
(tmp_path / "templates").mkdir()
(tmp_path / "migrate").write_text("migrate")
Expand All @@ -260,6 +297,7 @@ def test_go_extension_extra_assets(tmp_path, go_input_yaml):
@pytest.mark.usefixtures("go_extension")
def test_go_extension_extra_assets_overridden(tmp_path, go_input_yaml):
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
(tmp_path / "static").mkdir()
go_input_yaml["parts"] = {
"go-framework/assets": {
Expand Down Expand Up @@ -324,6 +362,7 @@ def test_go_extension_26_04_experimental_no_env(tmp_path):
def test_go_extension_default_26_04(tmp_path, monkeypatch):
monkeypatch.setenv("ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS", "1")
(tmp_path / "go.mod").write_text("module projectname\n\ngo 1.22.4")
(tmp_path / "main.go").write_text("package main\n\nfunc main() {}\n")
go_input_yaml = {
"name": "goprojectname",
"base": "ubuntu@26.04",
Expand Down