Skip to content

pack.Client::Build() closes logger's io.Writer  #1214

Description

@matejvasek

Summary

I am using pack code as a library in my own Go project.
I am not sure how much is this supported and whether this is really a bug.

Still:

        // logWriter is os.Stdout in verbose mode of this app
	packClient, err := pack.NewClient(pack.WithLogger(logging.New(logWriter)))
	if err != nil {
		return
	}

	// the builder must be trusted to reproduce the issue
	if err = packClient.Build(ctx, packOpts); err != nil {
        }
        // os.Stdout is closed here

The issue is that after invocation of packClient.Build() the logWriter is closed.

There is a code that check whether logWriter instance also implements io.Closer and if it does it will call close on it deliberately.
In case that the builder is trusted the logWriter (os.Stdout) is unaltered passed down and closed (since it is *os.File).
This is not good, especially for stdout.

In case the builder is not trusted the logWriter is wrapped by logging.PrefixWriter which is not io.Closer so everything works all right.

In standalone pack CLI it's not an issue because the os.Stdout is closed just before exiting, but if used a an library this is not convenient.

For now I workarounded this by wrapping os.Stdout into a struct that implements only io.Writer not io.Closer.

IMHO the io.Writer passed to the API shouldn't be closed, it's really surprising when that happens.

It might make sense if the parameter had to be io.WriteCloser, then user could expect that the stream will be closed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueA good first issue to get started with.size/smSmall level of effortstatus/readyIssue ready to be worked on.type/bugIssue that reports an unexpected behaviour.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions