-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathanalyzer.go
More file actions
116 lines (96 loc) · 2.87 KB
/
analyzer.go
File metadata and controls
116 lines (96 loc) · 2.87 KB
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
package terraformanalyzer
import (
"bytes"
"context"
"fmt"
"io"
"regexp"
"strings"
"gopkg.in/src-d/lookout-sdk.v0/pb"
"github.com/hashicorp/hcl2/hcl"
"github.com/hashicorp/hcl2/hcl/hclsyntax"
"github.com/hashicorp/hcl2/hclwrite"
"gopkg.in/src-d/go-log.v1"
)
// this regex checks if this is a terraform hcl file name
var terraformFileRegex = regexp.MustCompile(`\.tf$`)
type Analyzer struct {
DataClient pb.DataClient
Version string
}
func (a Analyzer) NotifyReviewEvent(ctx context.Context, review *pb.ReviewEvent) (*pb.EventResponse, error) {
log.Infof("got review request %v", review)
changes, err := a.DataClient.GetChanges(ctx, &pb.ChangesRequest{
Head: &review.Head,
Base: &review.Base,
WantContents: true,
WantLanguage: false,
WantUAST: false,
ExcludeVendored: true,
IncludePattern: `\.tf$`,
})
if err != nil {
log.Errorf(err, "GetChanges from DataServer failed")
return nil, err
}
var comments []*pb.Comment
hadFiles := map[string]bool{}
for {
change, err := changes.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Errorf(err, "GetChanges from DataServer failed")
return nil, err
}
log.Infof("analyzing '%s'", change.Head.Path)
if change.Head == nil {
log.Infof("ignoring deleted '%s'", change.Base.Path)
continue
}
if _, hasAnalyzed := hadFiles[change.Head.Path]; hasAnalyzed {
log.Infof("ignoring already analyzed '%s'", change.Head.Path)
continue
}
hadFiles[change.Head.Path] = true
// run the file through the HCL syntax parser
_, syntaxDiags := hclsyntax.ParseConfig(change.Head.Content, change.Head.Path, hcl.Pos{Line: 1, Column: 1})
if syntaxDiags.HasErrors() {
comments = append(comments, &pb.Comment{
File: change.Head.Path,
Line: 0,
Text: fmt.Sprintf("HCL errored on fomatting:\n%s", syntaxDiags),
})
continue
}
formatted := hclwrite.Format(change.Head.Content)
// check if changes have been made
if !bytes.Equal(change.Head.Content, formatted) {
oldLines := strings.Split(string(change.Head.Content), "\n")
newLines := strings.Split(string(formatted), "\n")
if len(oldLines) != len(newLines) {
// multi line changes are not fully supported by GitHub yet, falling back to a comment
comments = append(comments, &pb.Comment{
File: change.Head.Path,
Line: 0,
Text: fmt.Sprintf("This file is not Terraform fmt'ed"),
})
continue
}
for i := range oldLines {
if oldLines[i] != newLines[i] {
comments = append(comments, &pb.Comment{
File: change.Head.Path,
Line: int32(i + 1),
Text: fmt.Sprintf("```suggestion\n%s\n```", newLines[i]),
})
}
}
}
}
return &pb.EventResponse{AnalyzerVersion: a.Version, Comments: comments}, nil
}
func (a Analyzer) NotifyPushEvent(context.Context, *pb.PushEvent) (*pb.EventResponse, error) {
return &pb.EventResponse{}, nil
}