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
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ require (
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a
github.com/golangci/go-printf-func-name v0.1.0
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d
github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95
github.com/golangci/misspell v0.6.0
github.com/golangci/plugin-module-register v0.1.1
github.com/golangci/revgrep v0.8.0
Expand Down Expand Up @@ -140,6 +141,7 @@ require (
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chavacava/garif v0.1.0 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ebitengine/purego v0.8.2 // indirect
github.com/ettle/strcase v0.2.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions pkg/config/formatters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ var defaultFormatterSettings = FormatterSettings{
Sections: []string{"standard", "default"},
SkipGenerated: true,
},
GoLines: GoLinesSettings{
MaxLen: 100,
TabLen: 4,
ReformatTags: true,
ChainSplitDots: true,
},
}

type FormatterSettings struct {
Gci GciSettings `mapstructure:"gci"`
GoFmt GoFmtSettings `mapstructure:"gofmt"`
GoFumpt GoFumptSettings `mapstructure:"gofumpt"`
GoImports GoImportsSettings `mapstructure:"goimports"`
GoLines GoLinesSettings `mapstructure:"golines"`
}

type GciSettings struct {
Expand Down Expand Up @@ -50,3 +57,11 @@ type GoFumptSettings struct {
type GoImportsSettings struct {
LocalPrefixes string `mapstructure:"local-prefixes"`
}

type GoLinesSettings struct {
MaxLen int `mapstructure:"max-len"`
TabLen int `mapstructure:"tab-len"`
ShortenComments bool `mapstructure:"shorten-comments"`
ReformatTags bool `mapstructure:"reformat-tags"`
ChainSplitDots bool `mapstructure:"chain-split-dots"`
}
41 changes: 41 additions & 0 deletions pkg/goformatters/golines/golines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package golines

import (
"github.com/golangci/golines"

"github.com/golangci/golangci-lint/pkg/config"
)

const Name = "golines"

type Formatter struct {
shortener *golines.Shortener
}

func New(settings *config.GoLinesSettings) *Formatter {
options := golines.ShortenerConfig{}

if settings != nil {
options = golines.ShortenerConfig{
MaxLen: settings.MaxLen,
TabLen: settings.TabLen,
KeepAnnotations: false, // debug
ShortenComments: settings.ShortenComments,
ReformatTags: settings.ReformatTags,
IgnoreGenerated: false, // handle globally
DotFile: "", // debug
ChainSplitDots: settings.ChainSplitDots,
BaseFormatterCmd: "fmt", // fake cmd
}
}

return &Formatter{shortener: golines.NewShortener(options)}
}

func (*Formatter) Name() string {
return Name
}

func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
return f.shortener.Shorten(src)
}
8 changes: 7 additions & 1 deletion pkg/goformatters/meta_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/golangci/golangci-lint/pkg/goformatters/gofmt"
"github.com/golangci/golangci-lint/pkg/goformatters/gofumpt"
"github.com/golangci/golangci-lint/pkg/goformatters/goimports"
"github.com/golangci/golangci-lint/pkg/goformatters/golines"
"github.com/golangci/golangci-lint/pkg/logutils"
)

Expand Down Expand Up @@ -50,6 +51,11 @@ func NewMetaFormatter(log logutils.Log, cfg *config.Formatters, runCfg *config.R
m.formatters = append(m.formatters, formatter)
}

// golines calls `format.Source()` internally so no need to format after it.
if slices.Contains(cfg.Enable, golines.Name) {
m.formatters = append(m.formatters, golines.New(&cfg.Settings.GoLines))
}

return m, nil
}

Expand Down Expand Up @@ -80,5 +86,5 @@ func (m *MetaFormatter) Format(filename string, src []byte) []byte {
}

func IsFormatter(name string) bool {
return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name}, name)
return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name}, name)
}
28 changes: 28 additions & 0 deletions pkg/golinters/golines/golines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package golines

import (
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/goanalysis"
"github.com/golangci/golangci-lint/pkg/goformatters"
golinesbase "github.com/golangci/golangci-lint/pkg/goformatters/golines"
"github.com/golangci/golangci-lint/pkg/golinters/internal"
)

const linterName = "golines"

func New(settings *config.GoLinesSettings) *goanalysis.Linter {
a := goformatters.NewAnalyzer(
internal.LinterLogger.Child(linterName),
"Checks if code is formatted, and fixes long lines",
golinesbase.New(settings),
)

return goanalysis.NewLinter(
a.Name,
a.Doc,
[]*analysis.Analyzer{a},
nil,
).WithLoadMode(goanalysis.LoadModeSyntax)
}
19 changes: 19 additions & 0 deletions pkg/golinters/golines/golines_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package golines

import (
"testing"

"github.com/golangci/golangci-lint/test/testshared/integration"
)

func TestFromTestdata(t *testing.T) {
integration.RunTestdata(t)
}

func TestFix(t *testing.T) {
integration.RunFix(t)
}

func TestFixPathPrefix(t *testing.T) {
integration.RunFixPathPrefix(t)
}
83 changes: 83 additions & 0 deletions pkg/golinters/golines/testdata/fix/in/golines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//golangcitest:args -Egolines
//golangcitest:expected_exitcode 0
package testdata

import "fmt"

var (
abc = []string{"a really long string", "another really long string", "a third really long string", "a fourth really long string", fmt.Sprintf("%s %s %s %s >>>>> %s %s", "first argument", "second argument", "third argument", "fourth argument", "fifth argument", "sixth argument")}
)

type MyStruct struct {
aLongProperty int `help:"This is a really long string for this property"`
anotherLongProperty int `help:"This is a really long string for this property, part 2"`
athirdLongProperty int `help:"This is a really long string for this property, part 3...."`
}

type MyInterface interface {
aReallyLongFunctionName(argument1 string, argument2 string, argument3 string, argument4 string, argument5 string, argument6 string) (string, error)
}

// Something here

// Another comment
// A third comment
// This is a really really long comment that needs to be split up into multiple lines. I don't know how easy it will be to do, but I think we can do it!
func longLine(aReallyLongName string, anotherLongName string, aThirdLongName string) (string, error) {
argument1 := "argument1"
argument2 := "argument2"
argument3 := "argument3"
argument4 := "argument4"

fmt.Printf("This is a really long string with a bunch of arguments: %s %s %s %s >>>>>>>>>>>>>>>>>>>>>>", argument1, argument2, argument3, argument4)
fmt.Printf("This is a short statement: %d %d %d", 1, 2, 3)

z := argument1 + argument2 + fmt.Sprintf("This is a really long statement that should be broken up %s %s %s", argument1, argument2, argument3)

fmt.Printf("This is a really long line that can be broken up twice %s %s", fmt.Sprintf("This is a really long sub-line that should be broken up more because %s %s", argument1, argument2), fmt.Sprintf("A short one %d", 3))

fmt.Print("This is a function with a really long single argument. We want to see if it's properly split")

fmt.Println(z)

// This is a really long comment on an indented line. Do you think we can split it up or should we just leave it as is?
if argument4 == "5" {
return "", fmt.Errorf("a very long query with ID %d failed. Check Query History in AWS UI", 12341251)
}

go func() {
fmt.Printf("This is a really long line inside of a go routine call. It should be split if at all possible.")
}()

if "hello this is a big string" == "this is a small string" && "this is another big string" == "this is an even bigger string >>>" {
fmt.Print("inside if statement")
}

fmt.Println(map[string]string{"key1": "a very long value", "key2": "a very long value", "key3": "another very long value"})

return "", nil
}

func shortFunc(a int, b int) error {
c := make(chan int)

for {
select {
case <-c:
switch a {
case 1:
return fmt.Errorf("This is a really long line that can be broken up twice %s %s", fmt.Sprintf("This is a really long sub-line that should be broken up more because %s %s", "xxxx", "yyyy"), fmt.Sprintf("A short one %d", 3))
case 2:
}
}

break
}

if a > 5 {
panic(fmt.Sprintf(">>>>>>>>>>>>>>>>>>> %s %s %s %s", "really long argument", "another really long argument", "a third really long arguement", abc[1:2]))
}

return nil
// This is an end decoration
}
Loading
Loading