plugin: allow to use settings for plugins (#3887)

This commit is contained in:
Ludovic Fernandez 2023-06-15 14:38:58 +02:00 committed by GitHub
parent 2dcd82f331
commit 25c2b072af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 193 additions and 122 deletions

View file

@ -1,19 +1,10 @@
package lintersdb
import (
"fmt"
"path/filepath"
"plugin"
"github.com/spf13/viper"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/logutils"
"github.com/golangci/golangci-lint/pkg/report"
)
type Manager struct {
@ -37,28 +28,6 @@ func NewManager(cfg *config.Config, log logutils.Log) *Manager {
return m
}
// WithCustomLinters loads private linters that are specified in the golangci config file.
func (m *Manager) WithCustomLinters() *Manager {
if m.log == nil {
m.log = report.NewLogWrapper(logutils.NewStderrLog(logutils.DebugKeyEmpty), &report.Data{})
}
if m.cfg != nil {
for name, settings := range m.cfg.LintersSettings.Custom {
lc, err := m.loadCustomLinterConfig(name, settings)
if err != nil {
m.log.Errorf("Unable to load custom analyzer %s:%s, %v",
name,
settings.Path,
err)
} else {
m.nameToLCs[name] = append(m.nameToLCs[name], lc)
}
}
}
return m
}
func (Manager) AllPresets() []string {
return []string{
linter.PresetBugs,
@ -950,63 +919,3 @@ func (m Manager) GetAllLinterConfigsForPreset(p string) []*linter.Config {
return ret
}
// loadCustomLinterConfig loads the configuration of private linters.
// Private linters are dynamically loaded from .so plugin files.
func (m Manager) loadCustomLinterConfig(name string, settings config.CustomLinterSettings) (*linter.Config, error) {
analyzer, err := m.getAnalyzerPlugin(settings.Path)
if err != nil {
return nil, err
}
m.log.Infof("Loaded %s: %s", settings.Path, name)
customLinter := goanalysis.NewLinter(
name,
settings.Description,
analyzer.GetAnalyzers(),
nil).WithLoadMode(goanalysis.LoadModeTypesInfo)
linterConfig := linter.NewConfig(customLinter).
WithEnabledByDefault().
WithLoadForGoAnalysis().
WithURL(settings.OriginalURL)
return linterConfig, nil
}
type AnalyzerPlugin interface {
GetAnalyzers() []*analysis.Analyzer
}
// getAnalyzerPlugin loads a private linter as specified in the config file,
// loads the plugin from a .so file, and returns the 'AnalyzerPlugin' interface
// implemented by the private plugin.
// An error is returned if the private linter cannot be loaded or the linter
// does not implement the AnalyzerPlugin interface.
func (m Manager) getAnalyzerPlugin(path string) (AnalyzerPlugin, error) {
if !filepath.IsAbs(path) {
// resolve non-absolute paths relative to config file's directory
configFilePath := viper.ConfigFileUsed()
absConfigFilePath, err := filepath.Abs(configFilePath)
if err != nil {
return nil, fmt.Errorf("could not get absolute representation of config file path %q: %v", configFilePath, err)
}
path = filepath.Join(filepath.Dir(absConfigFilePath), path)
}
plug, err := plugin.Open(path)
if err != nil {
return nil, err
}
symbol, err := plug.Lookup("AnalyzerPlugin")
if err != nil {
return nil, err
}
analyzerPlugin, ok := symbol.(AnalyzerPlugin)
if !ok {
return nil, fmt.Errorf("plugin %s does not abide by 'AnalyzerPlugin' interface", path)
}
return analyzerPlugin, nil
}