1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-30 04:50:45 +02:00

fix: improve skip details (#4522)

log all skip reasons instead of only one, using a multierror.Error to
merge them all.

refs https://github.com/orgs/goreleaser/discussions/4469

---------

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker 2024-01-07 14:12:50 -03:00 committed by GitHub
parent e56ec30a80
commit 6e0fc795ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 12 deletions

View File

@ -6,6 +6,7 @@ import (
"sync"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/hashicorp/go-multierror"
"golang.org/x/sync/errgroup"
)
@ -30,9 +31,9 @@ func NewSkipAware(g Group) Group {
}
type skipAwareGroup struct {
g Group
skipErr error
skipOnce sync.Once
g Group
skipErr *multierror.Error
l sync.Mutex
}
// Go execs runs `fn` and saves the result if no error has been encountered.
@ -42,9 +43,9 @@ func (s *skipAwareGroup) Go(fn func() error) {
// if the err is a skip, set it for later, but return nil for now so the
// group proceeds.
if pipe.IsSkip(err) {
s.skipOnce.Do(func() {
s.skipErr = err
})
s.l.Lock()
defer s.l.Unlock()
s.skipErr = multierror.Append(s.skipErr, err)
return nil
}
return err
@ -57,5 +58,13 @@ func (s *skipAwareGroup) Wait() error {
if err := s.g.Wait(); err != nil {
return err
}
if s.skipErr == nil {
return nil
}
if s.skipErr.Len() == 1 {
return s.skipErr.Errors[0]
}
return s.skipErr
}

View File

@ -7,6 +7,7 @@ import (
"time"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/hashicorp/go-multierror"
"github.com/stretchr/testify/require"
)
@ -71,19 +72,49 @@ func TestSemaphoreSkipAware(t *testing.T) {
for _, i := range []int{1, 4} {
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
g := NewSkipAware(New(i))
var lock sync.Mutex
var counter int
for i := 0; i < 10; i++ {
g.Go(func() error {
time.Sleep(10 * time.Millisecond)
lock.Lock()
counter++
lock.Unlock()
return pipe.Skip("fake skip")
})
}
merr := &multierror.Error{}
require.ErrorAs(t, g.Wait(), &merr, "must be a multierror")
require.Len(t, merr.Errors, 10)
})
}
}
func TestSemaphoreSkipAwareSingleError(t *testing.T) {
for _, i := range []int{1, 4} {
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
g := NewSkipAware(New(i))
for i := 0; i < 10; i++ {
i := i
g.Go(func() error {
time.Sleep(10 * time.Millisecond)
if i == 5 {
return pipe.Skip("fake skip")
}
return nil
})
}
require.EqualError(t, g.Wait(), "fake skip")
require.Equal(t, 10, counter)
})
}
}
func TestSemaphoreSkipAwareNoSkips(t *testing.T) {
for _, i := range []int{1, 4} {
t.Run(fmt.Sprintf("limit-%d", i), func(t *testing.T) {
g := NewSkipAware(New(i))
for i := 0; i < 10; i++ {
g.Go(func() error {
time.Sleep(10 * time.Millisecond)
return nil
})
}
require.NoError(t, g.Wait())
})
}
}