You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

blank-imports.go 1.7KB

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