Skip to content

Commit bc88c72

Browse files
committed
feat: allow to use settings for plugins
1 parent 239a850 commit bc88c72

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
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

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: 35 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,44 @@ 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+
println(errP.Error())
91+
// fallback to the old plugin interface.
92+
analyzers, err = lookupAnalyzerPlugin(plug)
93+
if err != nil {
94+
return nil, fmt.Errorf("lookup plugin %s: %w", path, errors.Join(errP, err))
95+
}
96+
}
97+
98+
return analyzers, nil
99+
}
100+
101+
func lookupPluginNew(plug *plugin.Plugin, settings any) ([]*analysis.Analyzer, error) {
102+
symbol, err := plug.Lookup("New")
103+
if err != nil {
104+
return nil, err
105+
}
106+
107+
// The type func cannot be used here, must be the explicit signature.
108+
constructor, ok := symbol.(func(any) ([]*analysis.Analyzer, error))
109+
if !ok {
110+
return nil, fmt.Errorf("plugin does not abide by 'New' function: %T", symbol)
111+
}
112+
113+
return constructor(settings)
114+
}
115+
116+
func lookupAnalyzerPlugin(plug *plugin.Plugin) ([]*analysis.Analyzer, error) {
87117
symbol, err := plug.Lookup("AnalyzerPlugin")
88118
if err != nil {
89119
return nil, err
90120
}
91121

92122
analyzerPlugin, ok := symbol.(AnalyzerPlugin)
93123
if !ok {
94-
return nil, fmt.Errorf("plugin %s does not abide by 'AnalyzerPlugin' interface", path)
124+
return nil, fmt.Errorf("plugin does not abide by 'AnalyzerPlugin' interface: %T", symbol)
95125
}
96126

97-
return analyzerPlugin, nil
127+
return analyzerPlugin.GetAnalyzers(), nil
98128
}

0 commit comments

Comments
 (0)