Skip to content

Commit bd36265

Browse files
committed
feat: allow to use settings for plugins
1 parent 292fa5b commit bd36265

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/golangci/golangci-lint
22

3-
go 1.19
3+
go 1.20
44

55
require (
66
4d63.com/gocheckcompilerdirectives v1.2.1

netlify.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
[context.production.environment]
2-
GO_VERSION = "1.19"
2+
GO_VERSION = "1.20"
33
NODE_VERSION = "17"
44
# TODO https://github.com/golangci/golangci-lint/pull/2904#issuecomment-1146870535
55
# NPM_FLAGS = "--legacy-peer-deps"
66
# NPM_FLAGS = "--force"
77
NPM_VERSION = "8.5.5"
88

99
[context.deploy-preview.environment]
10-
GO_VERSION = "1.19"
10+
GO_VERSION = "1.20"
1111
NODE_VERSION = "17"
1212
# TODO https://github.com/golangci/golangci-lint/pull/2904#issuecomment-1146870535
1313
# NPM_FLAGS = "--legacy-peer-deps"
1414
# NPM_FLAGS = "--force"
1515
NPM_VERSION = "8.5.5"
1616

1717
[context.branch-deploy.environment]
18-
GO_VERSION = "1.19"
18+
GO_VERSION = "1.20"
1919
NODE_VERSION = "17"
2020
# TODO https://github.com/golangci/golangci-lint/pull/2904#issuecomment-1146870535
2121
# NPM_FLAGS = "--legacy-peer-deps"

pkg/config/linters_settings.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,9 @@ type CustomLinterSettings struct {
828828
Path string
829829
// Description describes the purpose of the private linter.
830830
Description string
831-
// The URL containing the source code for the private linter.
831+
// OriginalURL The URL containing the source code for the private linter.
832832
OriginalURL string `mapstructure:"original-url"`
833+
834+
// Settings plugin settings only work with linterdb.PluginConstructor symbol.
835+
Settings any
833836
}

pkg/lint/lintersdb/custom_linters.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package lintersdb
22

33
import (
4+
"errors"
45
"fmt"
56
"path/filepath"
67
"plugin"
@@ -45,14 +46,14 @@ func (m *Manager) WithCustomLinters() *Manager {
4546
// loadCustomLinterConfig loads the configuration of private linters.
4647
// Private linters are dynamically loaded from .so plugin files.
4748
func (m *Manager) loadCustomLinterConfig(name string, settings config.CustomLinterSettings) (*linter.Config, error) {
48-
analyzer, err := m.getAnalyzerPlugin(settings.Path)
49+
analyzers, err := m.getAnalyzerPlugin(settings.Path, settings.Settings)
4950
if err != nil {
5051
return nil, err
5152
}
5253

5354
m.log.Infof("Loaded %s: %s", settings.Path, name)
5455

55-
customLinter := goanalysis.NewLinter(name, settings.Description, analyzer.GetAnalyzers(), nil).
56+
customLinter := goanalysis.NewLinter(name, settings.Description, analyzers, nil).
5657
WithLoadMode(goanalysis.LoadModeTypesInfo)
5758

5859
linterConfig := linter.NewConfig(customLinter)
@@ -68,7 +69,7 @@ func (m *Manager) loadCustomLinterConfig(name string, settings config.CustomLint
6869
// and returns the 'AnalyzerPlugin' interface implemented by the private plugin.
6970
// An error is returned if the private linter cannot be loaded
7071
// or the linter does not implement the AnalyzerPlugin interface.
71-
func (m *Manager) getAnalyzerPlugin(path string) (AnalyzerPlugin, error) {
72+
func (m *Manager) getAnalyzerPlugin(path string, settings any) ([]*analysis.Analyzer, error) {
7273
if !filepath.IsAbs(path) {
7374
// resolve non-absolute paths relative to config file's directory
7475
configFilePath := viper.ConfigFileUsed()
@@ -84,15 +85,43 @@ func (m *Manager) getAnalyzerPlugin(path string) (AnalyzerPlugin, error) {
8485
return nil, err
8586
}
8687

88+
analyzers, errP := lookupPluginNew(plug, settings)
89+
if errP != nil {
90+
// fallback to the old plugin interface.
91+
analyzers, err = lookupAnalyzerPlugin(plug)
92+
if err != nil {
93+
return nil, fmt.Errorf("lookup plugin %s: %w", path, errors.Join(errP, err))
94+
}
95+
}
96+
97+
return analyzers, nil
98+
}
99+
100+
func lookupPluginNew(plug *plugin.Plugin, settings any) ([]*analysis.Analyzer, error) {
101+
symbol, err := plug.Lookup("New")
102+
if err != nil {
103+
return nil, err
104+
}
105+
106+
// The type func cannot be used here, must be the explicit signature.
107+
constructor, ok := symbol.(func(any) ([]*analysis.Analyzer, error))
108+
if !ok {
109+
return nil, fmt.Errorf("plugin does not abide by 'New' function: %T", symbol)
110+
}
111+
112+
return constructor(settings)
113+
}
114+
115+
func lookupAnalyzerPlugin(plug *plugin.Plugin) ([]*analysis.Analyzer, error) {
87116
symbol, err := plug.Lookup("AnalyzerPlugin")
88117
if err != nil {
89118
return nil, err
90119
}
91120

92121
analyzerPlugin, ok := symbol.(AnalyzerPlugin)
93122
if !ok {
94-
return nil, fmt.Errorf("plugin %s does not abide by 'AnalyzerPlugin' interface", path)
123+
return nil, fmt.Errorf("plugin does not abide by 'AnalyzerPlugin' interface: %T", symbol)
95124
}
96125

97-
return analyzerPlugin, nil
126+
return analyzerPlugin.GetAnalyzers(), nil
98127
}

0 commit comments

Comments
 (0)