Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: analyzer #222

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 4 additions & 22 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,20 @@ run:
concurrency: 4

# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 10m
timeout: 10m

# exit code when at least one issue was found, default is 1
issues-exit-code: 1

# include test files or not, default is true
tests: true

# list of build tags, all linters use it. Default is empty list.
build-tags:

# which dirs to skip: they won't be analyzed;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but next dirs are always skipped independently
# from this option's value:
# third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs:

# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files:

# output configuration options
output:
# colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number"
format: tab
formats:
- format: tab

# print lines of code with issue, default is true
print-issued-lines: true
Expand Down Expand Up @@ -73,13 +59,9 @@ linters-settings:
local-prefixes: github.com/daixiang0/gci

linters:
fast: false
disable-all: true
enable:
- gofmt
- gofumpt
- goimports
- gci
disable-all: true

issues:
exclude:
105 changes: 48 additions & 57 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package analyzer

import (
"fmt"
"go/token"
"strings"

Expand All @@ -21,39 +20,56 @@ const (
SkipGeneratedFlag = "skipGenerated"
SectionsFlag = "Sections"
SectionSeparatorsFlag = "SectionSeparators"
SectionDelimiter = ","
NoLexOrderFlag = "NoLexOrder"
CustomOrderFlag = "CustomOrder"
PrefixDelimiterFlag = "PrefixDelimiter"
)

const SectionDelimiter = ","

var (
noInlineComments bool
noPrefixComments bool
skipGenerated bool
sectionsStr string
sectionSeparatorsStr string
noLexOrder bool
customOrder bool
prefixDelimiter 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(&sectionsStr, SectionsFlag, "", "Specify the Sections format that should be used to check the file formatting")
Analyzer.Flags.StringVar(&sectionSeparatorsStr, SectionSeparatorsFlag, "", "Specify the Sections that are inserted as Separators between Sections")

func NewAnalyzer() *analysis.Analyzer {
log.InitLogger()
defer log.L().Sync()
}
_ = 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,
},
a := &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},
}

a.Flags.BoolVar(&noInlineComments, NoInlineCommentsFlag, false,
"If comments in the same line as the input should be present")
a.Flags.BoolVar(&noPrefixComments, NoPrefixCommentsFlag, false,
"If comments above an input should be present")
a.Flags.BoolVar(&skipGenerated, SkipGeneratedFlag, false,
"Skip generated files")
a.Flags.StringVar(&sectionsStr, SectionsFlag, "",
"Specify the Sections format that should be used to check the file formatting")
a.Flags.StringVar(&sectionSeparatorsStr, SectionSeparatorsFlag, "",
"Specify the Sections that are inserted as Separators between Sections")
a.Flags.BoolVar(&noLexOrder, NoLexOrderFlag, false,
"Drops lexical ordering for custom sections")
a.Flags.BoolVar(&customOrder, CustomOrderFlag, false,
"Enable custom order of sections")

a.Flags.StringVar(&prefixDelimiter, PrefixDelimiterFlag, SectionDelimiter, "")

return a
}

func runAnalysis(pass *analysis.Pass) (interface{}, error) {
func runAnalysis(pass *analysis.Pass) (any, error) {
var fileReferences []*token.File
// extract file references for all files in the analyzer pass
for _, pkgFile := range pass.Files {
Expand All @@ -79,25 +95,28 @@ func runAnalysis(pass *analysis.Pass) (interface{}, error) {
}

for _, file := range fileReferences {
filePath := file.Name()
unmodifiedFile, formattedFile, err := gci.LoadFormatGoFile(io.File{FilePath: filePath}, *gciCfg)
unmodifiedFile, formattedFile, err := gci.LoadFormatGoFile(io.File{FilePath: file.Name()}, *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),
Message: "File is not properly formatted",
SuggestedFixes: []analysis.SuggestedFix{*fix},
})
}

return nil, nil
}

Expand All @@ -107,50 +126,22 @@ func generateGciConfiguration(modPath string) *config.YamlConfig {
NoPrefixComments: noPrefixComments,
Debug: false,
SkipGenerated: skipGenerated,
CustomOrder: customOrder,
NoLexOrder: noLexOrder,
}

var sectionStrings []string
if sectionsStr != "" {
sectionStrings = strings.Split(sectionsStr, SectionDelimiter)
s := strings.Split(sectionsStr, SectionDelimiter)
for _, a := range s {
sectionStrings = append(sectionStrings, strings.ReplaceAll(a, prefixDelimiter, 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
}
Loading