Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions pkg/autodetect/autodetect.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func detectors(path string) []detector.Detector {
return []detector.Detector{
&detector.PythonDetector{Root: path},
&detector.PoetryDetector{Root: path},
&detector.GoDetector{Root: path},
}
}

Expand Down
53 changes: 53 additions & 0 deletions pkg/autodetect/detector/go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package detector

import (
"context"
"os"
"path/filepath"
"regexp"
)

type GoDetector struct {
Root string
}

var _ Detector = &GoDetector{}

func (d *GoDetector) Relevance(path string) (float64, error) {
goModPath := filepath.Join(d.Root, "go.mod")
_, err := os.Stat(goModPath)
if err == nil {
return 1.0, nil
}
if os.IsNotExist(err) {
return 0, nil
}
return 0, err
}

func (d *GoDetector) Packages(ctx context.Context) ([]string, error) {
goModPath := filepath.Join(d.Root, "go.mod")
goModContent, err := os.ReadFile(goModPath)
if err != nil {
return nil, err
}

// Parse the Go version from go.mod
goVersion := parseGoVersion(string(goModContent))
if goVersion != "" {
return []string{"go@" + goVersion}, nil
}
return []string{"go@latest"}, nil
}

func parseGoVersion(goModContent string) string {
// Use a regular expression to find the Go version directive
re := regexp.MustCompile(`(?m)^go\s+(\d+\.\d+(\.\d+)?)`)
match := re.FindStringSubmatch(goModContent)

if len(match) >= 2 {
return match[1]
}

return ""
}
103 changes: 103 additions & 0 deletions pkg/autodetect/detector/go_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package detector

import (
"context"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestGoDetectorRelevance(t *testing.T) {
tempDir := t.TempDir()
detector := &GoDetector{Root: tempDir}

t.Run("No go.mod file", func(t *testing.T) {
relevance, err := detector.Relevance(tempDir)
assert.NoError(t, err)
assert.Equal(t, 0.0, relevance)
})

t.Run("With go.mod file", func(t *testing.T) {
err := os.WriteFile(filepath.Join(tempDir, "go.mod"), []byte("module example.com"), 0644)
assert.NoError(t, err)

relevance, err := detector.Relevance(tempDir)
assert.NoError(t, err)
assert.Equal(t, 1.0, relevance)
})
}

func TestGoDetectorPackages(t *testing.T) {
tempDir := t.TempDir()
detector := &GoDetector{Root: tempDir}

t.Run("No go.mod file", func(t *testing.T) {
packages, err := detector.Packages(context.Background())
assert.Error(t, err)
assert.Nil(t, packages)
})

t.Run("With go.mod file and no version", func(t *testing.T) {
err := os.WriteFile(filepath.Join(tempDir, "go.mod"), []byte("module example.com"), 0644)
assert.NoError(t, err)

packages, err := detector.Packages(context.Background())
assert.NoError(t, err)
assert.Equal(t, []string{"go@latest"}, packages)
})

t.Run("With go.mod file and specific version", func(t *testing.T) {
goModContent := `
module example.com

go 1.18
`
err := os.WriteFile(filepath.Join(tempDir, "go.mod"), []byte(goModContent), 0644)
assert.NoError(t, err)

packages, err := detector.Packages(context.Background())
assert.NoError(t, err)
assert.Equal(t, []string{"[email protected]"}, packages)
})
}

func TestParseGoVersion(t *testing.T) {
testCases := []struct {
name string
content string
expected string
}{
{
name: "No version",
content: "module example.com",
expected: "",
},
{
name: "With version",
content: `
module example.com

go 1.18
`,
expected: "1.18",
},
{
name: "With patch version",
content: `
module example.com

go 1.18.3
`,
expected: "1.18.3",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
version := parseGoVersion(tc.content)
assert.Equal(t, tc.expected, version)
})
}
}
Loading