mirror of
https://github.com/scratchfoundation/golangci-lint.git
synced 2025-08-28 22:28:43 -04:00
plugin: allow to use settings for plugins (#3887)
This commit is contained in:
parent
2dcd82f331
commit
25c2b072af
4 changed files with 193 additions and 122 deletions
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue