@@ -17,6 +17,7 @@ import (
17
17
)
18
18
19
19
type Arguments struct {
20
+ FailIfChanged bool
20
21
ToStdout bool
21
22
StdinFilepath string
22
23
Files []string
@@ -26,9 +27,10 @@ type Arguments struct {
26
27
func Run (log * slog.Logger , stdin io.Reader , stdout io.Writer , args Arguments ) (err error ) {
27
28
// If no files are provided, read from stdin and write to stdout.
28
29
if len (args .Files ) == 0 {
29
- return format (writeToWriter (stdout ), readFromReader (stdin , args .StdinFilepath ), true )
30
+ out , _ := format (writeToWriter (stdout ), readFromReader (stdin , args .StdinFilepath ), true )
31
+ return out
30
32
}
31
- process := func (fileName string ) error {
33
+ process := func (fileName string ) ( error , bool ) {
32
34
read := readFromFile (fileName )
33
35
write := writeToFile
34
36
if args .ToStdout {
@@ -38,22 +40,24 @@ func Run(log *slog.Logger, stdin io.Reader, stdout io.Writer, args Arguments) (e
38
40
return format (write , read , writeIfUnchanged )
39
41
}
40
42
dir := args .Files [0 ]
41
- return NewFormatter (log , dir , process , args .WorkerCount ).Run ()
43
+ return NewFormatter (log , dir , process , args .WorkerCount , args . FailIfChanged ).Run ()
42
44
}
43
45
44
46
type Formatter struct {
45
- Log * slog.Logger
46
- Dir string
47
- Process func (fileName string ) error
48
- WorkerCount int
47
+ Log * slog.Logger
48
+ Dir string
49
+ Process func (fileName string ) (error , bool )
50
+ WorkerCount int
51
+ FailIfChange bool
49
52
}
50
53
51
- func NewFormatter (log * slog.Logger , dir string , process func (fileName string ) error , workerCount int ) * Formatter {
54
+ func NewFormatter (log * slog.Logger , dir string , process func (fileName string ) ( error , bool ), workerCount int , failIfChange bool ) * Formatter {
52
55
f := & Formatter {
53
- Log : log ,
54
- Dir : dir ,
55
- Process : process ,
56
- WorkerCount : workerCount ,
56
+ Log : log ,
57
+ Dir : dir ,
58
+ Process : process ,
59
+ WorkerCount : workerCount ,
60
+ FailIfChange : failIfChange ,
57
61
}
58
62
if f .WorkerCount == 0 {
59
63
f .WorkerCount = runtime .NumCPU ()
@@ -62,12 +66,16 @@ func NewFormatter(log *slog.Logger, dir string, process func(fileName string) er
62
66
}
63
67
64
68
func (f * Formatter ) Run () (err error ) {
69
+ changesMade := 0
65
70
start := time .Now ()
66
71
results := make (chan processor.Result )
67
72
f .Log .Debug ("Walking directory" , slog .String ("path" , f .Dir ))
68
73
go processor .Process (f .Dir , f .Process , f .WorkerCount , results )
69
74
var successCount , errorCount int
70
75
for r := range results {
76
+ if r .ChangesMade {
77
+ changesMade += 1
78
+ }
71
79
if r .Error != nil {
72
80
f .Log .Error (r .FileName , slog .Any ("error" , r .Error ))
73
81
errorCount ++
@@ -76,10 +84,18 @@ func (f *Formatter) Run() (err error) {
76
84
f .Log .Debug (r .FileName , slog .Duration ("duration" , r .Duration ))
77
85
successCount ++
78
86
}
79
- f .Log .Info ("Format complete" , slog .Int ("count" , successCount + errorCount ), slog .Int ("errors" , errorCount ), slog .Duration ("duration" , time .Since (start )))
87
+
88
+ if f .FailIfChange && changesMade > 0 {
89
+ f .Log .Error ("Templates were valid but not properly formatted" , slog .Int ("count" , successCount + errorCount ), slog .Int ("changed" , changesMade ), slog .Int ("errors" , errorCount ), slog .Duration ("duration" , time .Since (start )))
90
+ return fmt .Errorf ("templates were not formatted properly" )
91
+ }
92
+
93
+ f .Log .Info ("Format Complete" , slog .Int ("count" , successCount + errorCount ), slog .Int ("errors" , errorCount ), slog .Int ("changed" , changesMade ), slog .Duration ("duration" , time .Since (start )))
94
+
80
95
if errorCount > 0 {
81
96
return fmt .Errorf ("formatting failed" )
82
97
}
98
+
83
99
return
84
100
}
85
101
@@ -122,26 +138,29 @@ func writeToFile(fileName, tgt string) error {
122
138
return atomic .WriteFile (fileName , bytes .NewBufferString (tgt ))
123
139
}
124
140
125
- func format (write writer , read reader , writeIfUnchanged bool ) (err error ) {
141
+ func format (write writer , read reader , writeIfUnchanged bool ) (err error , fileChanged bool ) {
126
142
fileName , src , err := read ()
127
143
if err != nil {
128
- return err
144
+ return err , false
129
145
}
130
146
t , err := parser .ParseString (src )
131
147
if err != nil {
132
- return err
148
+ return err , false
133
149
}
134
150
t .Filepath = fileName
135
151
t , err = imports .Process (t )
136
152
if err != nil {
137
- return err
153
+ return err , false
138
154
}
139
155
w := new (bytes.Buffer )
140
156
if err = t .Write (w ); err != nil {
141
- return fmt .Errorf ("formatting error: %w" , err )
157
+ return fmt .Errorf ("formatting error: %w" , err ), false
142
158
}
143
- if ! writeIfUnchanged && src == w .String () {
144
- return nil
159
+
160
+ fileChanged = (src != w .String ())
161
+
162
+ if ! writeIfUnchanged && ! fileChanged {
163
+ return nil , fileChanged
145
164
}
146
- return write (fileName , w .String ())
165
+ return write (fileName , w .String ()), fileChanged
147
166
}
0 commit comments