@@ -95,6 +95,10 @@ type ConsoleReporter struct {
9595 writer map [string ]io.Writer
9696 times map [string ]time.Time
9797 mu sync.RWMutex
98+
99+ // out is the writer to print to. Normally this is os.Stdout, but it can be set to a buffer for testing.
100+ out io.Writer
101+ now func () time.Time
98102}
99103
100104// exclusiveWriter makes a write an exclusive resource by protecting Write calls with a mutex.
@@ -115,6 +119,8 @@ func NewConsoleReporter() *ConsoleReporter {
115119 return & ConsoleReporter {
116120 writer : make (map [string ]io.Writer ),
117121 times : make (map [string ]time.Time ),
122+ out : os .Stdout ,
123+ now : time .Now ,
118124 }
119125}
120126
@@ -134,7 +140,7 @@ func (r *ConsoleReporter) getWriter(pkg *Package) io.Writer {
134140 return res
135141 }
136142
137- res = & exclusiveWriter {O : textio .NewPrefixWriter (os . Stdout , getRunPrefix (pkg ))}
143+ res = & exclusiveWriter {O : textio .NewPrefixWriter (r . out , getRunPrefix (pkg ))}
138144 r .writer [name ] = res
139145 r .mu .Unlock ()
140146 }
@@ -166,7 +172,7 @@ func (r *ConsoleReporter) BuildStarted(pkg *Package, status map[*Package]Package
166172 i ++
167173 }
168174 sort .Slice (lines , func (i , j int ) bool { return lines [i ] < lines [j ] })
169- tw := tabwriter .NewWriter (os . Stdout , 0 , 2 , 2 , ' ' , 0 )
175+ tw := tabwriter .NewWriter (r . out , 0 , 2 , 2 , ' ' , 0 )
170176 fmt .Fprintln (tw , strings .Join (lines , "" ))
171177 tw .Flush ()
172178}
@@ -191,7 +197,7 @@ func (r *ConsoleReporter) PackageBuildStarted(pkg *Package) {
191197 }
192198
193199 r .mu .Lock ()
194- r .times [pkg .FullName ()] = time . Now ()
200+ r .times [pkg .FullName ()] = r . now ()
195201 r .mu .Unlock ()
196202
197203 _ , _ = io .WriteString (out , color .Sprintf ("<fg=yellow>build started</> <gray>(version %s)</>\n " , version ))
@@ -210,20 +216,32 @@ func (r *ConsoleReporter) PackageBuildFinished(pkg *Package, rep *PackageBuildRe
210216 out := r .getWriter (pkg )
211217
212218 r .mu .Lock ()
213- dur := time . Since (r .times [nme ])
219+ dur := r . now (). Sub (r .times [nme ])
214220 delete (r .writer , nme )
215221 delete (r .times , nme )
216222 r .mu .Unlock ()
217223
224+ // Format phase durations
225+ var phaseDurations []string
226+ for _ , phase := range rep .Phases {
227+ if d := rep .PhaseDuration (phase ); d > 0 {
228+ phaseDurations = append (phaseDurations , fmt .Sprintf ("%s: %.1fs" , phase , d .Seconds ()))
229+ }
230+ }
231+ phaseDurStr := ""
232+ if len (phaseDurations ) > 0 {
233+ phaseDurStr = color .Sprintf (" [%s]" , strings .Join (phaseDurations , " | " ))
234+ }
235+
218236 var msg string
219- if rep .Error != nil {
237+ if rep .Error != nil {
220238 msg = color .Sprintf ("<red>package build failed while %sing</>\n <white>Reason:</> %s\n " , rep .LastPhase (), rep .Error )
221239 } else {
222240 var coverage string
223241 if rep .TestCoverageAvailable {
224242 coverage = color .Sprintf ("<fg=yellow>test coverage: %d%%</> <gray>(%d of %d functions have tests)</>\n " , rep .TestCoveragePercentage , rep .FunctionsWithTest , rep .FunctionsWithTest + rep .FunctionsWithoutTest )
225243 }
226- msg = color .Sprintf ("%s<green>package build succeded</> <gray>(%.2fs)</>\n " , coverage , dur .Seconds ())
244+ msg = color .Sprintf ("%s<green>package build succeded</> <gray>(%.2fs)%s </>\n " , coverage , dur .Seconds (), phaseDurStr )
227245 }
228246 //nolint:errcheck
229247 io .WriteString (out , msg )
0 commit comments