From 55748a8dbab374852d2a86c6c57d39330c245e73 Mon Sep 17 00:00:00 2001 From: Norman Gehrsitz <norman.gehrsitz@gmx.de> Date: Mon, 31 Jan 2022 13:58:30 +0100 Subject: [PATCH 1/5] Add support for gci sections Signed-off-by: Norman Gehrsitz <norman.gehrsitz@gmx.de> --- .golangci.example.yml | 16 ++++-- .golangci.yml | 2 - go.mod | 2 +- go.sum | 8 +-- pkg/config/linters_settings.go | 5 +- pkg/golinters/gci.go | 99 +++++++--------------------------- pkg/golinters/gofmt_common.go | 14 +++-- pkg/lint/lintersdb/manager.go | 4 +- test/linters_test.go | 16 +++--- test/testdata/configs/gci.yml | 6 +++ test/testdata/gci.go | 2 + test/testdata/gci/gci.go | 3 +- 12 files changed, 67 insertions(+), 110 deletions(-) create mode 100644 test/testdata/configs/gci.yml diff --git a/.golangci.example.yml b/.golangci.example.yml index 0e17ee939807..15022f2ec31d 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -295,10 +295,18 @@ linters-settings: statements: -1 gci: - # Put imports beginning with prefix after 3rd-party packages. - # Only support one prefix. - # If not set, use `goimports.local-prefixes`. - local-prefixes: github.com/org/project + # Checks that no inline Comments are present + no-inlineComments: false + # Checks that no prefix Comments(comment lines above an import) are present + no-prefixComments: false + # Section configuration to compare against. + # Run gci print -h for a detailed explanation + sections: + - Standard + - Default + # Separators that should be present between sections + sectionSeparators: + - Newline gocognit: # Minimal code complexity to report diff --git a/.golangci.yml b/.golangci.yml index 3cc116d03bf8..a17d2b119bad 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -12,8 +12,6 @@ linters-settings: funlen: lines: 100 statements: 50 - gci: - local-prefixes: github.com/golangci/golangci-lint goconst: min-len: 2 min-occurrences: 3 diff --git a/go.mod b/go.mod index 01a1286bffd4..c12c4df76c05 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/breml/errchkjson v0.2.1 github.com/butuzov/ireturn v0.1.1 github.com/charithe/durationcheck v0.0.9 - github.com/daixiang0/gci v0.2.9 + github.com/daixiang0/gci v0.3.0 github.com/denis-tingajkin/go-header v0.4.2 github.com/esimonov/ifshort v1.0.4 github.com/fatih/color v1.13.0 diff --git a/go.sum b/go.sum index fadae35e04d9..0922ec987386 100644 --- a/go.sum +++ b/go.sum @@ -158,8 +158,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/daixiang0/gci v0.2.9 h1:iwJvwQpBZmMg31w+QQ6jsyZ54KEATn6/nfARbBNW294= -github.com/daixiang0/gci v0.2.9/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= +github.com/daixiang0/gci v0.3.0 h1:6x2xp99la0TfGmdDJ6T2VrLtCoZwYUVp4/5zT8J7+Go= +github.com/daixiang0/gci v0.3.0/go.mod h1:jaASoJmv/ykO9dAAPy31iJnreV19248qKDdVWf3QgC4= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -419,6 +419,8 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -985,6 +987,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1171,7 +1174,6 @@ golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 7e97ad3c5575..e538142a514d 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -253,7 +253,10 @@ type FunlenSettings struct { } type GciSettings struct { - LocalPrefixes string `mapstructure:"local-prefixes"` + NoInlineComments bool `mapstructure:"no-inlineComments"` + NoPrefixComments bool `mapstructure:"no-prefixComments"` + Sections []string `mapstructure:"sections"` + SectionSeparator []string `mapstructure:"sectionSeparators"` } type GocognitSettings struct { diff --git a/pkg/golinters/gci.go b/pkg/golinters/gci.go index 9886fc5f2587..a54502af8624 100644 --- a/pkg/golinters/gci.go +++ b/pkg/golinters/gci.go @@ -1,96 +1,35 @@ package golinters import ( - "bytes" - "fmt" - "sync" + "strings" - "github.com/daixiang0/gci/pkg/gci" - "github.com/pkg/errors" - "github.com/shazow/go-diff/difflib" + gciAnalyzer "github.com/daixiang0/gci/pkg/analyzer" "golang.org/x/tools/go/analysis" + "github.com/golangci/golangci-lint/pkg/config" "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" ) const gciName = "gci" -func NewGci() *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - differ := difflib.New() - - analyzer := &analysis.Analyzer{ - Name: gciName, - Doc: goanalysis.TheOnlyanalyzerDoc, +func NewGci(settings *config.GciSettings) *goanalysis.Linter { + analyzer := gciAnalyzer.Analyzer + var cfg map[string]map[string]interface{} + if settings != nil { + cfg = map[string]map[string]interface{}{ + analyzer.Name: { + gciAnalyzer.NoInlineCommentsFlag: settings.NoInlineComments, + gciAnalyzer.NoPrefixCommentsFlag: settings.NoPrefixComments, + gciAnalyzer.SectionsFlag: strings.Join(settings.Sections, gciAnalyzer.SectionDelimiter), + gciAnalyzer.SectionSeparatorsFlag: strings.Join(settings.SectionSeparator, gciAnalyzer.SectionDelimiter), + }, + } } + return goanalysis.NewLinter( gciName, - "Gci control golang package import order and make it always deterministic.", + "Gci controls golang package import order and makes it always deterministic.", []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - localFlag := lintCtx.Settings().Gci.LocalPrefixes - goimportsFlag := lintCtx.Settings().Goimports.LocalPrefixes - if localFlag == "" && goimportsFlag != "" { - localFlag = goimportsFlag - } - - analyzer.Run = func(pass *analysis.Pass) (interface{}, error) { - var fileNames []string - for _, f := range pass.Files { - pos := pass.Fset.PositionFor(f.Pos(), false) - fileNames = append(fileNames, pos.Filename) - } - - var issues []goanalysis.Issue - - flagSet := gci.FlagSet{ - LocalFlag: gci.ParseLocalFlag(localFlag), - } - - for _, f := range fileNames { - source, result, err := gci.Run(f, &flagSet) - if err != nil { - return nil, err - } - if result == nil { - continue - } - - diff := bytes.Buffer{} - _, err = diff.WriteString(fmt.Sprintf("--- %[1]s\n+++ %[1]s\n", f)) - if err != nil { - return nil, fmt.Errorf("can't write diff header: %v", err) - } - - err = differ.Diff(&diff, bytes.NewReader(source), bytes.NewReader(result)) - if err != nil { - return nil, fmt.Errorf("can't get gci diff output: %v", err) - } - - is, err := extractIssuesFromPatch(diff.String(), lintCtx.Log, lintCtx, gciName) - if err != nil { - return nil, errors.Wrapf(err, "can't extract issues from gci diff output %q", diff.String()) - } - - for i := range is { - issues = append(issues, goanalysis.NewIssue(&is[i], pass)) - } - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - } - }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) + cfg, + ).WithLoadMode(goanalysis.LoadModeSyntax) } diff --git a/pkg/golinters/gofmt_common.go b/pkg/golinters/gofmt_common.go index 39e8092e9735..42dc1768bc60 100644 --- a/pkg/golinters/gofmt_common.go +++ b/pkg/golinters/gofmt_common.go @@ -226,16 +226,14 @@ func getErrorTextForLinter(lintCtx *linter.Context, linterName string) string { text += " with -local " + lintCtx.Settings().Goimports.LocalPrefixes } case gciName: - text = "File is not `gci`-ed" - localPrefixes := lintCtx.Settings().Gci.LocalPrefixes - goimportsFlag := lintCtx.Settings().Goimports.LocalPrefixes - if localPrefixes == "" && goimportsFlag != "" { - localPrefixes = goimportsFlag + optionsText := []string{} + if lintCtx.Settings().Gci.NoInlineComments { + optionsText = append(optionsText, "NoInlineComments") } - - if localPrefixes != "" { - text += " with -local " + localPrefixes + if lintCtx.Settings().Gci.NoPrefixComments { + optionsText = append(optionsText, "NoPrefixComments") } + text = fmt.Sprintf("File does not conform to the import format configured for `Gci`(%s)", strings.Join(optionsText, ",")) } return text } diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index cf6a0f8d4b6f..b72049ba7881 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -107,6 +107,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { var errorlintCfg *config.ErrorLintSettings var exhaustiveCfg *config.ExhaustiveSettings var exhaustiveStructCfg *config.ExhaustiveStructSettings + var gciCfg *config.GciSettings var goModDirectivesCfg *config.GoModDirectivesSettings var goMndCfg *config.GoMndSettings var gosecCfg *config.GoSecSettings @@ -139,6 +140,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { errorlintCfg = &m.cfg.LintersSettings.ErrorLint exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct + gciCfg = &m.cfg.LintersSettings.Gci goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives goMndCfg = &m.cfg.LintersSettings.Gomnd gosecCfg = &m.cfg.LintersSettings.Gosec @@ -292,7 +294,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithPresets(linter.PresetComplexity). WithURL("https://github.com/ultraware/funlen"), - linter.NewConfig(golinters.NewGci()). + linter.NewConfig(golinters.NewGci(gciCfg)). WithSince("v1.30.0"). WithPresets(linter.PresetFormatting, linter.PresetImport). WithAutoFix(). diff --git a/test/linters_test.go b/test/linters_test.go index bb19e212a52c..a80baa6a511c 100644 --- a/test/linters_test.go +++ b/test/linters_test.go @@ -92,11 +92,11 @@ func TestGciLocal(t *testing.T) { rc := extractRunContextFromComments(t, sourcePath) args = append(args, rc.args...) - cfg, err := yaml.Marshal(rc.config) + cfg, err := os.ReadFile(rc.configPath) require.NoError(t, err) testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...). - ExpectHasIssue("testdata/gci/gci.go:7: File is not `gci`-ed") + ExpectHasIssue("testdata/gci/gci.go:9:1: Expected '\\n', Found '\\t'") } func TestMultipleOutputs(t *testing.T) { @@ -108,11 +108,11 @@ func TestMultipleOutputs(t *testing.T) { rc := extractRunContextFromComments(t, sourcePath) args = append(args, rc.args...) - cfg, err := yaml.Marshal(rc.config) + cfg, err := os.ReadFile(rc.configPath) require.NoError(t, err) testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...). - ExpectHasIssue("testdata/gci/gci.go:7: File is not `gci`-ed"). + ExpectHasIssue("testdata/gci/gci.go:9:1: Expected '\\n', Found '\\t'"). ExpectOutputContains(`"Issues":[`) } @@ -125,11 +125,11 @@ func TestStderrOutput(t *testing.T) { rc := extractRunContextFromComments(t, sourcePath) args = append(args, rc.args...) - cfg, err := yaml.Marshal(rc.config) + cfg, err := os.ReadFile(rc.configPath) require.NoError(t, err) testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...). - ExpectHasIssue("testdata/gci/gci.go:7: File is not `gci`-ed"). + ExpectHasIssue("testdata/gci/gci.go:9:1: Expected '\\n', Found '\\t'"). ExpectOutputContains(`"Issues":[`) } @@ -145,11 +145,11 @@ func TestFileOutput(t *testing.T) { rc := extractRunContextFromComments(t, sourcePath) args = append(args, rc.args...) - cfg, err := yaml.Marshal(rc.config) + cfg, err := os.ReadFile(rc.configPath) require.NoError(t, err) testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...). - ExpectHasIssue("testdata/gci/gci.go:7: File is not `gci`-ed"). + ExpectHasIssue("testdata/gci/gci.go:9:1: Expected '\\n', Found '\\t'"). ExpectOutputNotContains(`"Issues":[`) b, err := os.ReadFile(resultPath) diff --git a/test/testdata/configs/gci.yml b/test/testdata/configs/gci.yml new file mode 100644 index 000000000000..71f36c4c9e83 --- /dev/null +++ b/test/testdata/configs/gci.yml @@ -0,0 +1,6 @@ +linters-settings: + gci: + sections: + - Standard + - Prefix(github.com/golangci/golangci-lint) + - Default \ No newline at end of file diff --git a/test/testdata/gci.go b/test/testdata/gci.go index 4cda6e6156da..8f4190a20fe2 100644 --- a/test/testdata/gci.go +++ b/test/testdata/gci.go @@ -1,10 +1,12 @@ //args: -Egci +//config_path: testdata/configs/gci.yml package testdata import ( "fmt" "github.com/golangci/golangci-lint/pkg/config" + "github.com/pkg/errors" ) diff --git a/test/testdata/gci/gci.go b/test/testdata/gci/gci.go index a3ab571e852b..2875032513e1 100644 --- a/test/testdata/gci/gci.go +++ b/test/testdata/gci/gci.go @@ -1,12 +1,11 @@ //args: -Egci -//config: linters-settings.gci.local-prefixes=github.com/golangci/golangci-lint +//config_path: testdata/configs/gci.yml package gci import ( "fmt" "github.com/golangci/golangci-lint/pkg/config" - "github.com/pkg/errors" ) From deb352c60dce0b9b9f8f6c43eaee06d4df1d13b6 Mon Sep 17 00:00:00 2001 From: Norman Gehrsitz <norman.gehrsitz@gmx.de> Date: Mon, 31 Jan 2022 19:21:09 +0100 Subject: [PATCH 2/5] Run gci as part of the CI Signed-off-by: Norman Gehrsitz <norman.gehrsitz@gmx.de> --- .golangci.yml | 6 ++++++ pkg/golinters/ireturn.go | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a17d2b119bad..e7a5e05d41e6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -12,6 +12,11 @@ linters-settings: funlen: lines: 100 statements: 50 + gci: + sections: + - Standard + - Default + - Prefix(github.com/golangci/golangci-lint) goconst: min-len: 2 min-occurrences: 3 @@ -71,6 +76,7 @@ linters: - errcheck - exportloopref - funlen + - gci - gochecknoinits - goconst - gocritic diff --git a/pkg/golinters/ireturn.go b/pkg/golinters/ireturn.go index 3b5df66dae81..f2d4aec92fef 100644 --- a/pkg/golinters/ireturn.go +++ b/pkg/golinters/ireturn.go @@ -3,11 +3,11 @@ package golinters import ( "strings" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" - "github.com/butuzov/ireturn/analyzer" "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/config" + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" ) func NewIreturn(settings *config.IreturnSettings) *goanalysis.Linter { From d3a4e126e8be5c1f97efa515a4d5ce6cc2e299b2 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic <ldez@users.noreply.github.com> Date: Mon, 31 Jan 2022 23:11:05 +0100 Subject: [PATCH 3/5] first review --- .golangci.example.yml | 31 ++++++++++++++++++++++--------- .golangci.yml | 6 ------ pkg/config/linters_settings.go | 5 +++++ pkg/golinters/gci.go | 30 +++++++++++++++++++----------- pkg/golinters/gofmt_common.go | 9 --------- 5 files changed, 46 insertions(+), 35 deletions(-) diff --git a/.golangci.example.yml b/.golangci.example.yml index 15022f2ec31d..48be8fe4f374 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -295,18 +295,31 @@ linters-settings: statements: -1 gci: - # Checks that no inline Comments are present - no-inlineComments: false - # Checks that no prefix Comments(comment lines above an import) are present - no-prefixComments: false + # DEPRECATED: use `sections` and `prefix(github.com/org/project)` instead. + local-prefixes: github.com/org/project + + # Checks that no inline Comments are present. + # Default: false + no-inlineComments: true + + # Checks that no prefix Comments(comment lines above an import) are present. + # Default: false + no-prefixComments: true + # Section configuration to compare against. - # Run gci print -h for a detailed explanation + # Section names are case-insensitive and may contain parameters in (). + # Default: ["standard", "default"] sections: - - Standard - - Default - # Separators that should be present between sections + - standard # Captures all standard packages if they do not match another section. + - default # Contains all imports that could not be matched to another section type. + - comment(your text here) # Prints the specified indented comment. + - newLine # Prints an empty line + - prefix(github.com/org/project) # Groups all imports with the specified Prefix. + + # Separators that should be present between sections. + # Default: ["newLine"] sectionSeparators: - - Newline + - newLine gocognit: # Minimal code complexity to report diff --git a/.golangci.yml b/.golangci.yml index e7a5e05d41e6..a17d2b119bad 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -12,11 +12,6 @@ linters-settings: funlen: lines: 100 statements: 50 - gci: - sections: - - Standard - - Default - - Prefix(github.com/golangci/golangci-lint) goconst: min-len: 2 min-occurrences: 3 @@ -76,7 +71,6 @@ linters: - errcheck - exportloopref - funlen - - gci - gochecknoinits - goconst - gocritic diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index e538142a514d..da7237da66d6 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -26,6 +26,10 @@ var defaultLintersSettings = LintersSettings{ Forbidigo: ForbidigoSettings{ ExcludeGodocExamples: true, }, + Gci: GciSettings{ + Sections: []string{"default", "standard"}, + SectionSeparator: []string{"newline"}, + }, Gocognit: GocognitSettings{ MinComplexity: 30, }, @@ -253,6 +257,7 @@ type FunlenSettings struct { } type GciSettings struct { + LocalPrefixes string `mapstructure:"local-prefixes"` // Deprecated NoInlineComments bool `mapstructure:"no-inlineComments"` NoPrefixComments bool `mapstructure:"no-prefixComments"` Sections []string `mapstructure:"sections"` diff --git a/pkg/golinters/gci.go b/pkg/golinters/gci.go index a54502af8624..07b4c3d68ee1 100644 --- a/pkg/golinters/gci.go +++ b/pkg/golinters/gci.go @@ -1,6 +1,7 @@ package golinters import ( + "fmt" "strings" gciAnalyzer "github.com/daixiang0/gci/pkg/analyzer" @@ -13,23 +14,30 @@ import ( const gciName = "gci" func NewGci(settings *config.GciSettings) *goanalysis.Linter { - analyzer := gciAnalyzer.Analyzer - var cfg map[string]map[string]interface{} + var linterCfg map[string]map[string]interface{} + if settings != nil { - cfg = map[string]map[string]interface{}{ - analyzer.Name: { - gciAnalyzer.NoInlineCommentsFlag: settings.NoInlineComments, - gciAnalyzer.NoPrefixCommentsFlag: settings.NoPrefixComments, - gciAnalyzer.SectionsFlag: strings.Join(settings.Sections, gciAnalyzer.SectionDelimiter), - gciAnalyzer.SectionSeparatorsFlag: strings.Join(settings.SectionSeparator, gciAnalyzer.SectionDelimiter), - }, + cfg := map[string]interface{}{ + gciAnalyzer.NoInlineCommentsFlag: settings.NoInlineComments, + gciAnalyzer.NoPrefixCommentsFlag: settings.NoPrefixComments, + gciAnalyzer.SectionsFlag: strings.Join(settings.Sections, gciAnalyzer.SectionDelimiter), + gciAnalyzer.SectionSeparatorsFlag: strings.Join(settings.SectionSeparator, gciAnalyzer.SectionDelimiter), + } + + if settings.LocalPrefixes != "" { + prefix := []string{"Standard", "Default", fmt.Sprintf("Prefix(%s)", settings.LocalPrefixes)} + cfg[gciAnalyzer.SectionsFlag] = strings.Join(prefix, gciAnalyzer.SectionDelimiter) + } + + linterCfg = map[string]map[string]interface{}{ + gciAnalyzer.Analyzer.Name: cfg, } } return goanalysis.NewLinter( gciName, "Gci controls golang package import order and makes it always deterministic.", - []*analysis.Analyzer{analyzer}, - cfg, + []*analysis.Analyzer{gciAnalyzer.Analyzer}, + linterCfg, ).WithLoadMode(goanalysis.LoadModeSyntax) } diff --git a/pkg/golinters/gofmt_common.go b/pkg/golinters/gofmt_common.go index 42dc1768bc60..4f63e7bed853 100644 --- a/pkg/golinters/gofmt_common.go +++ b/pkg/golinters/gofmt_common.go @@ -225,15 +225,6 @@ func getErrorTextForLinter(lintCtx *linter.Context, linterName string) string { if lintCtx.Settings().Goimports.LocalPrefixes != "" { text += " with -local " + lintCtx.Settings().Goimports.LocalPrefixes } - case gciName: - optionsText := []string{} - if lintCtx.Settings().Gci.NoInlineComments { - optionsText = append(optionsText, "NoInlineComments") - } - if lintCtx.Settings().Gci.NoPrefixComments { - optionsText = append(optionsText, "NoPrefixComments") - } - text = fmt.Sprintf("File does not conform to the import format configured for `Gci`(%s)", strings.Join(optionsText, ",")) } return text } From 770506b1da848bf53d6951f2e2cd6afbefef8ffb Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic <ldez@users.noreply.github.com> Date: Mon, 31 Jan 2022 23:16:28 +0100 Subject: [PATCH 4/5] review --- pkg/golinters/gci.go | 18 +++++++++--------- test/testdata/configs/gci.yml | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/golinters/gci.go b/pkg/golinters/gci.go index 07b4c3d68ee1..75c9e1eba166 100644 --- a/pkg/golinters/gci.go +++ b/pkg/golinters/gci.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - gciAnalyzer "github.com/daixiang0/gci/pkg/analyzer" + gci "github.com/daixiang0/gci/pkg/analyzer" "golang.org/x/tools/go/analysis" "github.com/golangci/golangci-lint/pkg/config" @@ -18,26 +18,26 @@ func NewGci(settings *config.GciSettings) *goanalysis.Linter { if settings != nil { cfg := map[string]interface{}{ - gciAnalyzer.NoInlineCommentsFlag: settings.NoInlineComments, - gciAnalyzer.NoPrefixCommentsFlag: settings.NoPrefixComments, - gciAnalyzer.SectionsFlag: strings.Join(settings.Sections, gciAnalyzer.SectionDelimiter), - gciAnalyzer.SectionSeparatorsFlag: strings.Join(settings.SectionSeparator, gciAnalyzer.SectionDelimiter), + gci.NoInlineCommentsFlag: settings.NoInlineComments, + gci.NoPrefixCommentsFlag: settings.NoPrefixComments, + gci.SectionsFlag: strings.Join(settings.Sections, gci.SectionDelimiter), + gci.SectionSeparatorsFlag: strings.Join(settings.SectionSeparator, gci.SectionDelimiter), } if settings.LocalPrefixes != "" { - prefix := []string{"Standard", "Default", fmt.Sprintf("Prefix(%s)", settings.LocalPrefixes)} - cfg[gciAnalyzer.SectionsFlag] = strings.Join(prefix, gciAnalyzer.SectionDelimiter) + prefix := []string{"standard", "default", fmt.Sprintf("prefix(%s)", settings.LocalPrefixes)} + cfg[gci.SectionsFlag] = strings.Join(prefix, gci.SectionDelimiter) } linterCfg = map[string]map[string]interface{}{ - gciAnalyzer.Analyzer.Name: cfg, + gci.Analyzer.Name: cfg, } } return goanalysis.NewLinter( gciName, "Gci controls golang package import order and makes it always deterministic.", - []*analysis.Analyzer{gciAnalyzer.Analyzer}, + []*analysis.Analyzer{gci.Analyzer}, linterCfg, ).WithLoadMode(goanalysis.LoadModeSyntax) } diff --git a/test/testdata/configs/gci.yml b/test/testdata/configs/gci.yml index 71f36c4c9e83..487e26383697 100644 --- a/test/testdata/configs/gci.yml +++ b/test/testdata/configs/gci.yml @@ -1,6 +1,6 @@ linters-settings: gci: sections: - - Standard - - Prefix(github.com/golangci/golangci-lint) - - Default \ No newline at end of file + - standard + - prefix(github.com/golangci/golangci-lint) + - default From d7a5f3b1849c6585063746be98a5ea1992b3de18 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic <ldez@users.noreply.github.com> Date: Wed, 2 Feb 2022 00:23:50 +0100 Subject: [PATCH 5/5] review: add log for local-prefixes --- pkg/golinters/gci.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/golinters/gci.go b/pkg/golinters/gci.go index 75c9e1eba166..c0c606a7b89d 100644 --- a/pkg/golinters/gci.go +++ b/pkg/golinters/gci.go @@ -9,6 +9,7 @@ import ( "github.com/golangci/golangci-lint/pkg/config" "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" + "github.com/golangci/golangci-lint/pkg/lint/linter" ) const gciName = "gci" @@ -39,5 +40,9 @@ func NewGci(settings *config.GciSettings) *goanalysis.Linter { "Gci controls golang package import order and makes it always deterministic.", []*analysis.Analyzer{gci.Analyzer}, linterCfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) + ).WithContextSetter(func(lintCtx *linter.Context) { + if settings.LocalPrefixes != "" { + lintCtx.Log.Warnf("gci: `local-prefixes` is deprecated, use `sections` and `prefix(%s)` instead.", settings.LocalPrefixes) + } + }).WithLoadMode(goanalysis.LoadModeSyntax) }