github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/rule/blank-imports.go (about) 1 package rule 2 3 import ( 4 "go/ast" 5 "strings" 6 7 "github.com/mgechev/revive/lint" 8 ) 9 10 // BlankImportsRule lints given else constructs. 11 type BlankImportsRule struct{} 12 13 // Name returns the rule name. 14 func (r *BlankImportsRule) Name() string { 15 return "blank-imports" 16 } 17 18 // Apply applies the rule to given file. 19 func (r *BlankImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { 20 if file.Pkg.IsMain() || file.IsTest() { 21 return nil 22 } 23 24 const ( 25 message = "a blank import should be only in a main or test package, or have a comment justifying it" 26 category = "imports" 27 28 embedImportPath = `"embed"` 29 ) 30 31 var failures []lint.Failure 32 33 // The first element of each contiguous group of blank imports should have 34 // an explanatory comment of some kind. 35 for i, imp := range file.AST.Imports { 36 pos := file.ToPosition(imp.Pos()) 37 38 if !isBlank(imp.Name) { 39 continue // Ignore non-blank imports. 40 } 41 42 if i > 0 { 43 prev := file.AST.Imports[i-1] 44 prevPos := file.ToPosition(prev.Pos()) 45 46 isSubsequentBlancInAGroup := isBlank(prev.Name) && prevPos.Line+1 == pos.Line && prev.Path.Value != embedImportPath 47 if isSubsequentBlancInAGroup { 48 continue 49 } 50 } 51 52 if imp.Path.Value == embedImportPath && r.fileHasValidEmbedComment(file.AST) { 53 continue 54 } 55 56 // This is the first blank import of a group. 57 if imp.Doc == nil && imp.Comment == nil { 58 failures = append(failures, lint.Failure{Failure: message, Category: category, Node: imp, Confidence: 1}) 59 } 60 } 61 62 return failures 63 } 64 65 func (r *BlankImportsRule) fileHasValidEmbedComment(fileAst *ast.File) bool { 66 for _, commentGroup := range fileAst.Comments { 67 for _, comment := range commentGroup.List { 68 if strings.HasPrefix(comment.Text, "//go:embed ") { 69 return true 70 } 71 } 72 } 73 74 return false 75 }