No description
  • Go 99.6%
  • Makefile 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jason Lunz a87fae0841
Merge pull request #51 from github/znull/stage-v2-clean
go-pipe v2: Stage API, pooled copies, MemoryWatch removal
2026-06-20 18:33:38 +02:00
.github Update comment to reflect full version requirement 2026-01-12 09:50:59 +00:00
pipe Preserve first command kill reason 2026-06-18 19:39:09 +02:00
.gitignore go-pipe: initial release 2022-11-21 16:31:12 +01:00
.golangci.yml Upgrade golangci-lint to v2.8 for Go 1.24 compatibility 2026-01-12 09:40:12 +00:00
CODE_OF_CONDUCT.md go-pipe: initial release 2022-11-21 16:31:12 +01:00
CODEOWNERS go-pipe: initial release 2022-11-21 16:31:12 +01:00
CONTRIBUTING.md go-pipe: initial release 2022-11-21 16:31:12 +01:00
go.mod Bump module path to v2 for breaking Stage interface change 2026-05-30 16:38:17 +02:00
go.sum Dependencies update. update uber leak dependency 2026-01-15 12:02:37 +01:00
LICENSE.md go-pipe: initial release 2022-11-21 16:31:12 +01:00
Makefile go-pipe: initial release 2022-11-21 16:31:12 +01:00
README.md use correct code example in README 2026-06-15 19:24:01 +02:00
SECURITY.md go-pipe: initial release 2022-11-21 16:31:12 +01:00
SUPPORT.md go-pipe: initial release 2022-11-21 16:31:12 +01:00

go-pipe GoDoc

A package used to easily build command pipelines in your Go applications

Important

We have not thoroughly tested this package on OSs other than Linux, especially Windows. At this time, using this package on Windows based systems is considered experimental and will be supported only on a best effort basis.

Migrating to v2

It's normal for pipelines to stop before all input has been consumed1. If an earlier stage continues writing after that happens, the write side of the pipe can fail with EPIPE, SIGPIPE, or io.ErrClosedPipe.

In go-pipe v1 it was possible to get away without handling this case, because a command stage's stdin was connected in a way that often (but not necessarily!) drained the write side and hid the error from the previous stage feeding it. That was an implementation detail, not a guarantee. In go-pipe v2, producer stages are more likely to be connected directly to a command's stdin, and thus see the error themselves.

Fortunately, this is easily handled by wrapping the stage with pipe.IgnoreError(stage, pipe.IsPipeError). If the producer only writes output and is otherwise stateless, that's the only thing needed.

If the producer also updates state, metrics, cursors, or has other side effects, in a way that depends on how much of the output was produced, then in addition to using pipe.IgnoreError, you must also ensure producer-owned state is brought to a consistent point before returning the error.

For example, if a stateful producer function must process its entire input for correctness regardless of whether it was read by the consumer, it should use a pattern like:

var writeErr error
for _, item := range items {
	updateState(item)
	if writeErr == nil {
		_, writeErr = fmt.Fprintln(stdout, item)
	}
}
return writeErr

Links


  1. In cat foo | head | grep -q, for example, either head or grep could exit before its input is fully consumed. ↩︎