-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathanalyzer.go
156 lines (133 loc) · 4.22 KB
/
analyzer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package analyzer
import (
"fmt"
"go/token"
"strings"
"github.com/golangci/modinfo"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"github.com/daixiang0/gci/pkg/config"
"github.com/daixiang0/gci/pkg/gci"
"github.com/daixiang0/gci/pkg/io"
"github.com/daixiang0/gci/pkg/log"
)
const (
NoInlineCommentsFlag = "noInlineComments"
NoPrefixCommentsFlag = "noPrefixComments"
SkipGeneratedFlag = "skipGenerated"
SectionsFlag = "Sections"
SectionSeparatorsFlag = "SectionSeparators"
SectionDelimiter = ","
)
var (
noInlineComments bool
noPrefixComments bool
skipGenerated bool
sectionsStr string
sectionSeparatorsStr string
)
func init() {
Analyzer.Flags.BoolVar(&noInlineComments, NoInlineCommentsFlag, false, "If comments in the same line as the input should be present")
Analyzer.Flags.BoolVar(&noPrefixComments, NoPrefixCommentsFlag, false, "If comments above an input should be present")
Analyzer.Flags.BoolVar(&skipGenerated, SkipGeneratedFlag, false, "Skip generated files")
Analyzer.Flags.StringVar(§ionsStr, SectionsFlag, "", "Specify the Sections format that should be used to check the file formatting")
Analyzer.Flags.StringVar(§ionSeparatorsStr, SectionSeparatorsFlag, "", "Specify the Sections that are inserted as Separators between Sections")
log.InitLogger()
defer log.L().Sync()
}
var Analyzer = &analysis.Analyzer{
Name: "gci",
Doc: "A tool that control Go package import order and make it always deterministic.",
Run: runAnalysis,
Requires: []*analysis.Analyzer{
inspect.Analyzer,
modinfo.Analyzer,
},
}
func runAnalysis(pass *analysis.Pass) (interface{}, error) {
var fileReferences []*token.File
// extract file references for all files in the analyzer pass
for _, pkgFile := range pass.Files {
fileForPos := pass.Fset.File(pkgFile.Package)
if fileForPos != nil {
fileReferences = append(fileReferences, fileForPos)
}
}
expectedNumFiles := len(pass.Files)
foundNumFiles := len(fileReferences)
if expectedNumFiles != foundNumFiles {
return nil, InvalidNumberOfFilesInAnalysis{expectedNumFiles, foundNumFiles}
}
file, err := modinfo.FindModuleFromPass(pass)
if err != nil {
return nil, err
}
gciCfg, err := generateGciConfiguration(file.Path).Parse()
if err != nil {
return nil, err
}
for _, file := range fileReferences {
filePath := file.Name()
unmodifiedFile, formattedFile, err := gci.LoadFormatGoFile(io.File{FilePath: filePath}, *gciCfg)
if err != nil {
return nil, err
}
fix, err := GetSuggestedFix(file, unmodifiedFile, formattedFile)
if err != nil {
return nil, err
}
if fix == nil {
// no difference
continue
}
pass.Report(analysis.Diagnostic{
Pos: fix.TextEdits[0].Pos,
Message: fmt.Sprintf("fix by `%s %s`", generateCmdLine(*gciCfg), filePath),
SuggestedFixes: []analysis.SuggestedFix{*fix},
})
}
return nil, nil
}
func generateGciConfiguration(modPath string) *config.YamlConfig {
fmtCfg := config.BoolConfig{
NoInlineComments: noInlineComments,
NoPrefixComments: noPrefixComments,
Debug: false,
SkipGenerated: skipGenerated,
}
var sectionStrings []string
if sectionsStr != "" {
sectionStrings = strings.Split(sectionsStr, SectionDelimiter)
}
var sectionSeparatorStrings []string
if sectionSeparatorsStr != "" {
sectionSeparatorStrings = strings.Split(sectionSeparatorsStr, SectionDelimiter)
fmt.Println(sectionSeparatorsStr)
}
return &config.YamlConfig{Cfg: fmtCfg, SectionStrings: sectionStrings, SectionSeparatorStrings: sectionSeparatorStrings, ModPath: modPath}
}
func generateCmdLine(cfg config.Config) string {
result := "gci write"
if cfg.BoolConfig.NoInlineComments {
result += " --NoInlineComments "
}
if cfg.BoolConfig.NoPrefixComments {
result += " --NoPrefixComments "
}
if cfg.BoolConfig.SkipGenerated {
result += " --skip-generated "
}
if cfg.BoolConfig.CustomOrder {
result += " --custom-order "
}
if cfg.BoolConfig.NoLexOrder {
result += " --no-lex-order"
}
for _, s := range cfg.Sections.String() {
result += fmt.Sprintf(" --Section \"%s\" ", s)
}
for _, s := range cfg.SectionSeparators.String() {
result += fmt.Sprintf(" --SectionSeparator %s ", s)
}
return result
}