diff --git a/api/v1/v1.go b/api/v1/v1.go index bb0408a..d399303 100644 --- a/api/v1/v1.go +++ b/api/v1/v1.go @@ -300,7 +300,7 @@ func (api *API) PullTags(cn *collection.Collection) error { }(repo, tags, done) } - return wait.Until(done) + return wait.WithTolerance(done) } // PushTags compares images from remote and "push" (usually local) registries, @@ -357,7 +357,7 @@ func (api *API) PushTags(cn *collection.Collection, push PushConfig) error { }(repo, tags, done) } - return wait.Until(done) + return wait.WithTolerance(done) } func logDebugData(data io.Reader) { diff --git a/main.go b/main.go index 78db5bf..8c0a0d5 100644 --- a/main.go +++ b/main.go @@ -36,6 +36,8 @@ type Options struct { } `positional-args:"yes" required:"yes"` } +var exitCode = 0 + var doNotFail = false func suicide(err error, critical bool) { @@ -44,6 +46,8 @@ func suicide(err error, critical bool) { if !doNotFail || critical { os.Exit(1) } + + exitCode = 254 // not typical error code, for "git grep" friendliness } func parseFlags() (*Options, error) { @@ -169,7 +173,7 @@ func main() { } if !o.DaemonMode { - os.Exit(0) + os.Exit(exitCode) } fmt.Printf("WAIT: %v\n-\n", o.PollingInterval) diff --git a/util/wait/wait.go b/util/wait/wait.go index 6366827..09889e7 100644 --- a/util/wait/wait.go +++ b/util/wait/wait.go @@ -1,5 +1,7 @@ package wait +import "fmt" + // Until iterates over buffered error channel and: // * upon receiving non-nil value from the channel, makes an early return with this value // * if no non-nil values were received from iteration over the channel, it just returns nil @@ -21,3 +23,29 @@ func Until(done chan error) error { return nil } + +// WithTolerance is the same as Until, but it does not return immediately on errors +// rather loops through all channel capacity returning "composite" error in the end. +func WithTolerance(done chan error) error { + var errMessage string + + i := 0 + + for err := range done { + if err != nil { + errMessage = errMessage + err.Error() + "\n" + } + + i++ + + if i >= cap(done) { + close(done) + } + } + + if len(errMessage) == 0 { + return nil + } + + return fmt.Errorf(errMessage) +}