Skip to content
Closed
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
30 changes: 30 additions & 0 deletions pkg/buildpacks/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/buildpacks/pack/pkg/project/types"
"github.com/docker/docker/client"
"github.com/heroku/color"
"golang.org/x/mod/modfile"

"knative.dev/func/pkg/builders"
"knative.dev/func/pkg/docker"
Expand Down Expand Up @@ -186,6 +187,17 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
opts.Env["BPE_DEFAULT_LISTEN_ADDRESS"] = "[::]:8080"
}

// use "explicit default" go version in function's go.mod file via variable
// if not explicitly set via buildEnvs (in func.yaml). This ensures single
// go version in buildpacks. See https://github.com/knative/func/issues/3178
if f.Runtime == "go" {
if _, ok := opts.Env["BP_GO_VERSION"]; !ok {
if goVersion := parseGoModVersion(f.Root); goVersion != "" {
opts.Env["BP_GO_VERSION"] = goVersion
}
}
}

var bindings = make([]string, 0, len(f.Build.Mounts))
for _, m := range f.Build.Mounts {
bindings = append(bindings, fmt.Sprintf("%s:%s", m.Source, m.Destination))
Expand Down Expand Up @@ -297,6 +309,24 @@ func BuilderImage(f fn.Function, builderName string) (string, error) {
return builders.Image(f, builderName, DefaultBuilderImages)
}

// parseGoModVersion reads the go.mod file and returns the Go version directive.
// Returns empty string if go.mod doesn't exist or has no go directive.
func parseGoModVersion(root string) string {
goModPath := filepath.Join(root, "go.mod")
data, err := os.ReadFile(goModPath)
if err != nil {
return ""
}
f, err := modfile.Parse(goModPath, data, nil)
if err != nil {
return ""
}
if f.Go == nil {
return ""
}
return f.Go.Version
}

// Errors

type ErrRuntimeRequired struct{}
Expand Down
29 changes: 29 additions & 0 deletions pkg/buildpacks/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,35 @@ func TestBuild_Errors(t *testing.T) {
}
}

// TestParseGoModVersion tests parsing of Go version from go.mod
func TestParseGoModVersion(t *testing.T) {
tests := []struct {
name string
content string
writeFile bool
expected string
}{
{"valid go version", "module test\n\ngo 1.25", true, "1.25"},
{"go version with toolchain", "module test\n\ngo 1.25\ntoolchain go1.25.4", true, "1.25"},
{"no go directive", "module test", true, ""},
{"no go.mod file", "", false, ""},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tempDir := t.TempDir()
if tt.writeFile {
if err := os.WriteFile(filepath.Join(tempDir, "go.mod"), []byte(tt.content), 0644); err != nil {
t.Fatal(err)
}
}
if got := parseGoModVersion(tempDir); got != tt.expected {
t.Errorf("parseGoModVersion() = %q, want %q", got, tt.expected)
}
})
}
}

type mockImpl struct {
BuildFn func(context.Context, pack.BuildOptions) error
}
Expand Down
Loading