docs: update code snippets in Architecture (#4409)
This commit is contained in:
parent
2a2eebdbea
commit
bb6d7115fd
@ -28,7 +28,7 @@ The execution starts here:
|
|||||||
|
|
||||||
```go title=cmd/golangci-lint/main.go
|
```go title=cmd/golangci-lint/main.go
|
||||||
func main() {
|
func main() {
|
||||||
e := commands.NewExecutor(version, commit, date)
|
e := commands.NewExecutor(info)
|
||||||
|
|
||||||
if err := e.Execute(); err != nil {
|
if err := e.Execute(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed executing command with error %v\n", err)
|
fmt.Fprintf(os.Stderr, "failed executing command with error %v\n", err)
|
||||||
@ -46,6 +46,7 @@ type Executor struct {
|
|||||||
lintersCmd *cobra.Command
|
lintersCmd *cobra.Command
|
||||||
|
|
||||||
exitCode int
|
exitCode int
|
||||||
|
buildInfo BuildInfo
|
||||||
|
|
||||||
cfg *config.Config
|
cfg *config.Config
|
||||||
log logutils.Log
|
log logutils.Log
|
||||||
@ -69,9 +70,9 @@ We use dependency injection and all root dependencies are stored in this executo
|
|||||||
|
|
||||||
In the function `NewExecutor` we do the following:
|
In the function `NewExecutor` we do the following:
|
||||||
|
|
||||||
1. init dependencies
|
1. Initialize dependencies.
|
||||||
2. init [cobra](https://github.com/spf13/cobra) commands
|
2. Initialize [cobra](https://github.com/spf13/cobra) commands.
|
||||||
3. parse config file using [viper](https://github.com/spf13/viper) and merge it with command line args.
|
3. Parse the config file using [viper](https://github.com/spf13/viper) and merge it with command line arguments.
|
||||||
|
|
||||||
The following execution is controlled by `cobra`. If a user executes `golangci-lint run`
|
The following execution is controlled by `cobra`. If a user executes `golangci-lint run`
|
||||||
then `cobra` executes `e.runCmd`.
|
then `cobra` executes `e.runCmd`.
|
||||||
@ -82,19 +83,23 @@ Different `cobra` commands have different runners, e.g. a `run` command is confi
|
|||||||
func (e *Executor) initRun() {
|
func (e *Executor) initRun() {
|
||||||
e.runCmd = &cobra.Command{
|
e.runCmd = &cobra.Command{
|
||||||
Use: "run",
|
Use: "run",
|
||||||
Short: welcomeMessage,
|
Short: "Run the linters",
|
||||||
Run: e.executeRun,
|
Run: e.executeRun,
|
||||||
PreRun: func(_ *cobra.Command, _ []string) {
|
PreRunE: func(_ *cobra.Command, _ []string) error {
|
||||||
if ok := e.acquireFileLock(); !ok {
|
if ok := e.acquireFileLock(); !ok {
|
||||||
e.log.Fatalf("Parallel golangci-lint is running")
|
return errors.New("parallel golangci-lint is running")
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
PostRun: func(_ *cobra.Command, _ []string) {
|
PostRun: func(_ *cobra.Command, _ []string) {
|
||||||
e.releaseFileLock()
|
e.releaseFileLock()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
e.rootCmd.AddCommand(e.runCmd)
|
e.rootCmd.AddCommand(e.runCmd)
|
||||||
e.runCmd.SetOutput(logutils.StdOut) // use custom output to properly color it in Windows terminals
|
|
||||||
|
e.runCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals
|
||||||
|
e.runCmd.SetErr(logutils.StdErr)
|
||||||
|
|
||||||
e.initRunConfiguration(e.runCmd)
|
e.initRunConfiguration(e.runCmd)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -114,7 +119,7 @@ func (cl *ContextLoader) Load(ctx context.Context, linters []*linter.Config) (*l
|
|||||||
loadMode := cl.findLoadMode(linters)
|
loadMode := cl.findLoadMode(linters)
|
||||||
pkgs, err := cl.loadPackages(ctx, loadMode)
|
pkgs, err := cl.loadPackages(ctx, loadMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to load packages: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
@ -142,10 +147,11 @@ func (lc *Config) WithLoadFiles() *Config {
|
|||||||
|
|
||||||
If a linter uses `go/analysis` and needs type information, we need to extract more data by `go/packages`:
|
If a linter uses `go/analysis` and needs type information, we need to extract more data by `go/packages`:
|
||||||
|
|
||||||
```go title=/pkg/lint/linter/config.go
|
```go title=pkg/lint/linter/config.go
|
||||||
func (lc *Config) WithLoadForGoAnalysis() *Config {
|
func (lc *Config) WithLoadForGoAnalysis() *Config {
|
||||||
lc = lc.WithLoadFiles()
|
lc = lc.WithLoadFiles()
|
||||||
lc.LoadMode |= packages.NeedImports | packages.NeedDeps | packages.NeedExportsFile | packages.NeedTypesSizes
|
lc.LoadMode |= packages.NeedImports | packages.NeedDeps | packages.NeedExportFile | packages.NeedTypesSizes
|
||||||
|
lc.IsSlow = true
|
||||||
return lc
|
return lc
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -160,17 +166,21 @@ First, we need to find all enabled linters. All linters are registered here:
|
|||||||
```go title=pkg/lint/lintersdb/manager.go
|
```go title=pkg/lint/lintersdb/manager.go
|
||||||
func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||||
// ...
|
// ...
|
||||||
lcs := []*linter.Config{
|
linters = append(linters,
|
||||||
linter.NewConfig(golinters.NewGovet(govetCfg)).
|
// ...
|
||||||
WithLoadForGoAnalysis().
|
|
||||||
WithPresets(linter.PresetBugs).
|
|
||||||
WithAlternativeNames("vet", "vetshadow").
|
|
||||||
WithURL("https://pkg.go.dev/cmd/vet"),
|
|
||||||
linter.NewConfig(golinters.NewBodyclose()).
|
linter.NewConfig(golinters.NewBodyclose()).
|
||||||
|
WithSince("v1.18.0").
|
||||||
WithLoadForGoAnalysis().
|
WithLoadForGoAnalysis().
|
||||||
WithPresets(linter.PresetPerformance, linter.PresetBugs).
|
WithPresets(linter.PresetPerformance, linter.PresetBugs).
|
||||||
WithURL("https://github.com/timakin/bodyclose"),
|
WithURL("https://github.com/timakin/bodyclose"),
|
||||||
// ...
|
// ...
|
||||||
|
linter.NewConfig(golinters.NewGovet(govetCfg)).
|
||||||
|
WithEnabledByDefault().
|
||||||
|
WithSince("v1.0.0").
|
||||||
|
WithLoadForGoAnalysis().
|
||||||
|
WithPresets(linter.PresetBugs, linter.PresetMetaLinter).
|
||||||
|
WithAlternativeNames("vet", "vetshadow").
|
||||||
|
WithURL("https://pkg.go.dev/cmd/vet"),
|
||||||
}
|
}
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
@ -221,6 +231,8 @@ type Issue struct {
|
|||||||
FromLinter string
|
FromLinter string
|
||||||
Text string
|
Text string
|
||||||
|
|
||||||
|
Severity string
|
||||||
|
|
||||||
// Source lines of a code with the issue to show
|
// Source lines of a code with the issue to show
|
||||||
SourceLines []string
|
SourceLines []string
|
||||||
|
|
||||||
@ -250,8 +262,10 @@ We have an abstraction of `result.Processor` to postprocess found issues:
|
|||||||
```sh
|
```sh
|
||||||
$ tree -L 1 ./pkg/result/processors/
|
$ tree -L 1 ./pkg/result/processors/
|
||||||
./pkg/result/processors/
|
./pkg/result/processors/
|
||||||
|
./pkg/result/processors/
|
||||||
├── autogenerated_exclude.go
|
├── autogenerated_exclude.go
|
||||||
├── autogenerated_exclude_test.go
|
├── autogenerated_exclude_test.go
|
||||||
|
├── base_rule.go
|
||||||
├── cgo.go
|
├── cgo.go
|
||||||
├── diff.go
|
├── diff.go
|
||||||
├── exclude.go
|
├── exclude.go
|
||||||
@ -262,6 +276,7 @@ $ tree -L 1 ./pkg/result/processors/
|
|||||||
├── fixer.go
|
├── fixer.go
|
||||||
├── identifier_marker.go
|
├── identifier_marker.go
|
||||||
├── identifier_marker_test.go
|
├── identifier_marker_test.go
|
||||||
|
├── issues.go
|
||||||
├── max_from_linter.go
|
├── max_from_linter.go
|
||||||
├── max_from_linter_test.go
|
├── max_from_linter_test.go
|
||||||
├── max_per_file_from_linter.go
|
├── max_per_file_from_linter.go
|
||||||
@ -270,17 +285,23 @@ $ tree -L 1 ./pkg/result/processors/
|
|||||||
├── max_same_issues_test.go
|
├── max_same_issues_test.go
|
||||||
├── nolint.go
|
├── nolint.go
|
||||||
├── nolint_test.go
|
├── nolint_test.go
|
||||||
|
├── path_prefixer.go
|
||||||
|
├── path_prefixer_test.go
|
||||||
├── path_prettifier.go
|
├── path_prettifier.go
|
||||||
├── path_shortener.go
|
├── path_shortener.go
|
||||||
├── processor.go
|
├── processor.go
|
||||||
|
├── processor_test.go
|
||||||
|
├── severity_rules.go
|
||||||
|
├── severity_rules_test.go
|
||||||
├── skip_dirs.go
|
├── skip_dirs.go
|
||||||
├── skip_files.go
|
├── skip_files.go
|
||||||
├── skip_files_test.go
|
├── skip_files_test.go
|
||||||
|
├── sort_results.go
|
||||||
|
├── sort_results_test.go
|
||||||
├── source_code.go
|
├── source_code.go
|
||||||
├── testdata
|
├── testdata
|
||||||
├── uniq_by_line.go
|
├── uniq_by_line.go
|
||||||
├── uniq_by_line_test.go
|
└── uniq_by_line_test.go
|
||||||
└── utils.go
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The abstraction is simple:
|
The abstraction is simple:
|
||||||
@ -303,14 +324,24 @@ We have an abstraction for printing found issues.
|
|||||||
$ tree -L 1 ./pkg/printers/
|
$ tree -L 1 ./pkg/printers/
|
||||||
./pkg/printers/
|
./pkg/printers/
|
||||||
├── checkstyle.go
|
├── checkstyle.go
|
||||||
|
├── checkstyle_test.go
|
||||||
├── codeclimate.go
|
├── codeclimate.go
|
||||||
|
├── codeclimate_test.go
|
||||||
├── github.go
|
├── github.go
|
||||||
├── github_test.go
|
├── github_test.go
|
||||||
|
├── html.go
|
||||||
|
├── html_test.go
|
||||||
├── json.go
|
├── json.go
|
||||||
|
├── json_test.go
|
||||||
├── junitxml.go
|
├── junitxml.go
|
||||||
|
├── junitxml_test.go
|
||||||
├── printer.go
|
├── printer.go
|
||||||
├── tab.go
|
├── tab.go
|
||||||
└── text.go
|
├── tab_test.go
|
||||||
|
├── teamcity.go
|
||||||
|
├── teamcity_test.go
|
||||||
|
├── text.go
|
||||||
|
└── text_test.go
|
||||||
```
|
```
|
||||||
|
|
||||||
Needed printer is selected by command line option `--out-format`.
|
Needed printer is selected by command line option `--out-format`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user