package builder import ( "compress/gzip" "io" "os" "github.com/andybalholm/brotli" ) const ( gzipLevel = 6 brotliLevel = 9 ) type MultiWriteCloser struct { writers []io.WriteCloser multiWriter io.Writer } func (mw *MultiWriteCloser) Write(p []byte) (n int, err error) { return mw.multiWriter.Write(p) } func (mw *MultiWriteCloser) Close() error { var lastErr error for _, w := range mw.writers { err := w.Close() if err != nil { lastErr = err } } return lastErr } func openFileWrite(filename string) (*os.File, error) { return os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) } func openFileGz(filename string) (*gzip.Writer, error) { filenameGz := filename + ".gz" f, err := openFileWrite(filenameGz) if err != nil { return nil, err } return gzip.NewWriterLevel(f, gzipLevel) } func openFileBrotli(filename string) (*brotli.Writer, error) { filenameBrotli := filename + ".br" f, err := openFileWrite(filenameBrotli) if err != nil { return nil, err } return brotli.NewWriterLevel(f, brotliLevel), nil } func multiOpenFile(filename string) (*MultiWriteCloser, error) { r, err := openFileWrite(filename) if err != nil { return nil, err } gz, err := openFileGz(filename) if err != nil { return nil, err } br, err := openFileBrotli(filename) if err != nil { return nil, err } return &MultiWriteCloser{ writers: []io.WriteCloser{r, gz, br}, multiWriter: io.MultiWriter(r, gz, br), }, nil } func openFileAndVariants(filename string) (io.WriteCloser, error) { if compressFiles { return multiOpenFile(filename) } else { return openFileWrite(filename) } }