@@ -3,89 +3,87 @@ package logio
33import (
44 "bytes"
55 "errors"
6- "fmt"
76 "io"
87 "os"
98 "regexp"
9+ "sync"
1010)
1111
1212// PipeWiring is a helper struct to define the setup and binding of tools and
1313// xcbuild with a filter and stdout. It is purely boilerplate reduction and it is the
1414// users responsibility to choose between this and manual hooking of the in/outputs.
1515// It also provides a convenient Close() method that only closes things that can/should be closed.
1616type PipeWiring struct {
17- XcbuildRawout bytes.Buffer
17+ XcbuildRawout * bytes.Buffer
1818 XcbuildStdout io.Writer
1919 XcbuildStderr io.Writer
2020 ToolStdin io.ReadCloser
2121 ToolStdout io.WriteCloser
2222 ToolStderr io.WriteCloser
2323
24- closer func () error
24+ toolPipeW * io.PipeWriter
25+ bufferedStdout * Sink
26+ toolInSink * Sink
27+ filter * PrefixFilter
28+
29+ closeFilterOnce sync.Once
30+ }
31+
32+ // CloseFilter closes the filter and waits for it to finish
33+ func (p * PipeWiring ) CloseFilter () error {
34+ err := error (nil )
35+ p .closeFilterOnce .Do (func () {
36+ err = p .filter .Close ()
37+ <- p .filter .Done ()
38+
39+ })
40+ return err
2541}
2642
27- // Close closes the PipeWiring instances that needs to be closing as part of this instance.
28- //
29- // In reality it can only close the filter and the tool input as everything else is
30- // managed by a command or the os.
31- func (i * PipeWiring ) Close () error {
32- return i .closer ()
43+ // Close ...
44+ func (p * PipeWiring ) Close () error {
45+ filterErr := p .CloseFilter ()
46+ toolSinkErr := p .toolInSink .Close ()
47+ pipeWErr := p .toolPipeW .Close ()
48+ bufferedStdoutErr := p .bufferedStdout .Close ()
49+
50+ return errors .Join (filterErr , toolSinkErr , pipeWErr , bufferedStdoutErr )
3351}
3452
3553// SetupPipeWiring creates a new PipeWiring instance that contains the usual
3654// input/outputs that an xcodebuild command and a logging tool needs when we are also
3755// using a logging filter.
3856func SetupPipeWiring (filter * regexp.Regexp ) * PipeWiring {
3957 // Create a buffer to store raw xcbuild output
40- var rawXcbuild bytes.Buffer
58+ rawXcbuild := bytes .NewBuffer ( nil )
4159 // Pipe filtered logs to tool
4260 toolPipeR , toolPipeW := io .Pipe ()
4361
4462 // Add a buffer before stdout
4563 bufferedStdout := NewSink (os .Stdout )
4664 // Add a buffer before tool input
47- xcbuildLogs := NewSink (toolPipeW )
65+ toolInSink := NewSink (toolPipeW )
66+ xcbuildLogs := io .MultiWriter (rawXcbuild , toolInSink )
4867 // Create a filter for [Bitrise ...] prefixes
4968 bitrisePrefixFilter := NewPrefixFilter (
5069 filter ,
5170 bufferedStdout ,
5271 xcbuildLogs ,
5372 )
5473
55- // Send raw xcbuild out to raw out and filter
56- rawInputDuplication := io .MultiWriter (& rawXcbuild , bitrisePrefixFilter )
57-
5874 return & PipeWiring {
5975 XcbuildRawout : rawXcbuild ,
60- XcbuildStdout : rawInputDuplication ,
61- XcbuildStderr : rawInputDuplication ,
76+ XcbuildStdout : bitrisePrefixFilter ,
77+ XcbuildStderr : bitrisePrefixFilter ,
6278 ToolStdin : toolPipeR ,
6379 ToolStdout : os .Stdout ,
6480 ToolStderr : os .Stderr ,
65- closer : func () error {
66- // XcbuildRawout - no need to close
67- // XcbuildStdout - Multiwriter, meaning we need to close the subwriters
68- // XcbuildStderr - Multiwriter, meaning we need to close the subwriters
69- // ToolStdout - We are not closing stdout
70- // ToolSterr - We are not closing stderr
71-
72- var errStr string
73-
74- if err := bitrisePrefixFilter .Close (); err != nil {
75- errStr += fmt .Sprintf ("failed to close log filter, error: %s" , err .Error ())
76- }
77- if err := toolPipeW .Close (); err != nil {
78- if len (errStr ) > 0 {
79- errStr += ", "
80- }
81- errStr += fmt .Sprintf ("failed to close xcodebuild-xcpretty pipe, error: %s" , err .Error ())
82- }
8381
84- if len (errStr ) > 0 {
85- return errors .New (errStr )
86- }
82+ toolPipeW : toolPipeW ,
83+ bufferedStdout : bufferedStdout ,
84+ toolInSink : toolInSink ,
85+ filter : bitrisePrefixFilter ,
8786
88- return nil
89- },
87+ closeFilterOnce : sync.Once {},
9088 }
9189}
0 commit comments