Skip to content

Commit

Permalink
feat: go directive
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Dec 1, 2024
1 parent 267ca9d commit f378fe9
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 3 deletions.
17 changes: 15 additions & 2 deletions cmd/gomoddirectives/gomoddirectives.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"os"
"regexp"
"strings"

"github.com/ldez/gomoddirectives"
Expand All @@ -30,6 +31,7 @@ type config struct {
ToolchainForbidden bool
ToolForbidden bool
GoDebugForbidden bool
GoVersionPattern string
}

func main() {
Expand All @@ -42,6 +44,7 @@ func main() {
flag.BoolVar(&cfg.ToolchainForbidden, "toolchain", false, "Forbid the use of toolchain directive")
flag.BoolVar(&cfg.ToolForbidden, "tool", false, "Forbid the use of tool directives")
flag.BoolVar(&cfg.GoDebugForbidden, "godebug", false, "Forbid the use of godebug directives")
flag.StringVar(&cfg.GoVersionPattern, "goversion", "", "Pattern to validate go min version directive")

help := flag.Bool("h", false, "Show this help.")

Expand All @@ -52,15 +55,25 @@ func main() {
usage()
}

results, err := gomoddirectives.Analyze(gomoddirectives.Options{
opts := gomoddirectives.Options{
ReplaceAllowList: cfg.ReplaceAllowList,
ReplaceAllowLocal: cfg.ReplaceAllowLocal,
ExcludeForbidden: cfg.ExcludeForbidden,
RetractAllowNoExplanation: cfg.RetractAllowNoExplanation,
ToolchainForbidden: cfg.ToolchainForbidden,
ToolForbidden: cfg.ToolForbidden,
GoDebugForbidden: cfg.GoDebugForbidden,
})
}

if cfg.GoVersionPattern != "" {
var err error
opts.GoVersionPattern, err = regexp.Compile(cfg.GoVersionPattern)
if err != nil {
log.Fatal(err)
}
}

results, err := gomoddirectives.Analyze(opts)
if err != nil {
log.Fatal(err)
}
Expand Down
14 changes: 14 additions & 0 deletions gomoddirectives.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package gomoddirectives
import (
"fmt"
"go/token"
"regexp"
"strings"

"github.com/ldez/grignotin/gomod"
Expand All @@ -17,6 +18,7 @@ const (
reasonToolchain = "toolchain directive is not allowed"
reasonTool = "tool directive is not allowed"
reasonGoDebug = "godebug directive is not allowed"
reasonGoVersion = "go directive (%s) doesn't match the pattern '%s'"
reasonReplaceLocal = "local replacement are not allowed"
reasonReplace = "replacement are not allowed"
reasonReplaceIdentical = "the original module and the replacement are identical"
Expand Down Expand Up @@ -52,6 +54,7 @@ type Options struct {
ToolchainForbidden bool
ToolForbidden bool
GoDebugForbidden bool
GoVersionPattern *regexp.Regexp
}

// AnalyzePass analyzes a pass.
Expand Down Expand Up @@ -98,6 +101,7 @@ func AnalyzeFile(file *modfile.File, opts Options) []Result {
checkReplaceDirectives,
checkToolchainDirective,
checkGoDebugDirectives,
checkGoVersionDirectives,
}

var results []Result
Expand All @@ -108,6 +112,16 @@ func AnalyzeFile(file *modfile.File, opts Options) []Result {
return results
}

func checkGoVersionDirectives(file *modfile.File, opts Options) []Result {
var results []Result

if file.Go != nil && opts.GoVersionPattern != nil && !opts.GoVersionPattern.MatchString(file.Go.Version) {
results = append(results, NewResult(file, file.Go.Syntax, fmt.Sprintf(reasonGoVersion, file.Go.Version, opts.GoVersionPattern.String())))
}

return results
}

func checkRetractDirectives(file *modfile.File, opts Options) []Result {
var results []Result

Expand Down
27 changes: 27 additions & 0 deletions gomoddirectives_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"go/token"
"os"
"path/filepath"
"regexp"
"slices"
"testing"

Expand Down Expand Up @@ -300,6 +301,32 @@ func TestAnalyzeFile(t *testing.T) {
GoDebugForbidden: false,
},
},
{
desc: "goversion: don't check",
modulePath: "goversion_family/go.mod",
opts: Options{
GoVersionPattern: nil,
},
},
{
desc: "goversion: pattern match",
modulePath: "goversion_family/go.mod",
opts: Options{
GoVersionPattern: regexp.MustCompile(`\d\.\d+(\.0)?`),
},
},
{
desc: "goversion: pattern not matched",
modulePath: "goversion_family/go.mod",
opts: Options{
GoVersionPattern: regexp.MustCompile(`\d\.\d+\.0`),
},
expected: []Result{{
Reason: "go directive (1.22) doesn't match the pattern '\\d\\.\\d+\\.0'",
Start: token.Position{Filename: "go.mod", Offset: 0, Line: 3, Column: 1},
End: token.Position{Filename: "go.mod", Offset: 0, Line: 3, Column: 8},
}},
},
}

for _, test := range testCases {
Expand Down
12 changes: 11 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ tool (
)
```

## [`toolchain`](https://golang.org/ref/mod#go-mod-file-toolchain) directives
## [`toolchain`](https://golang.org/ref/mod#go-mod-file-toolchain) directive

- Ban `toolchain` directive.

Expand All @@ -104,3 +104,13 @@ godebug (
asynctimerchan=0
)
```

## [`go`](https://go.dev/ref/mod#go-mod-file-go) directive

- Use a regular expression to constraint the Go minimum version.

```go
module example.com/foo

go 1.22.0
```
3 changes: 3 additions & 0 deletions testdata/goversion_family/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/ldez/gomoddirectives/testdata/toolchain

go 1.22

0 comments on commit f378fe9

Please sign in to comment.