From 66aa579adca5c01d63a291c3f662006ab2388844 Mon Sep 17 00:00:00 2001 From: John Weathers Date: Fri, 27 Feb 2026 13:46:07 -0500 Subject: [PATCH 1/2] feat(helm): warn on 'helm list' truncation with default --max limit add a stderr warning when results are truncated by the default --max limit. Closes #31617 Signed-off-by: John Weathers --- pkg/action/list.go | 6 ++++- pkg/action/list_test.go | 49 +++++++++++++++++++++++++++++++++++++++++ pkg/cmd/list.go | 11 ++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/pkg/action/list.go b/pkg/action/list.go index 06727bd9a..7f83a4b1e 100644 --- a/pkg/action/list.go +++ b/pkg/action/list.go @@ -135,6 +135,8 @@ type List struct { Failed bool Pending bool Selector string + // Truncated indicates results were omitted due to Limit + Truncated bool } // NewList constructs a new *List @@ -213,7 +215,7 @@ func (l *List) Run() ([]ri.Releaser, error) { } // Calculate the limit and offset, and then truncate results if necessary. - limit := len(results) + limit := len(rresults) if l.Limit > 0 && l.Limit < limit { limit = l.Limit } @@ -221,6 +223,8 @@ func (l *List) Run() ([]ri.Releaser, error) { if l := len(rresults); l < last { last = l } + l.Truncated = last < len(rresults) + rresults = rresults[l.Offset:last] return releaseV1ListToReleaserList(rresults) diff --git a/pkg/action/list_test.go b/pkg/action/list_test.go index 643bcea42..4a3759f28 100644 --- a/pkg/action/list_test.go +++ b/pkg/action/list_test.go @@ -175,6 +175,55 @@ func TestList_LimitOffsetOutOfBounds(t *testing.T) { is.Len(list, 2) } +func TestList_Truncation(t *testing.T) { + is := assert.New(t) + // Create 3 releases + lister := newListFixture(t) + makeMeSomeReleases(t, lister.cfg.Releases) + + lister.Limit = 5 + lister.Offset = 0 + list, err := lister.Run() + is.NoError(err) + is.Len(list, 3) + is.False(lister.Truncated, "Expected Truncated to be false when limit > total") + + lister.Limit = 3 + lister.Offset = 0 + list, err = lister.Run() + is.NoError(err) + is.Len(list, 3) + is.False(lister.Truncated, "Expected Truncated to be false when limit == total") + + lister.Limit = 2 + lister.Offset = 0 + list, err = lister.Run() + is.NoError(err) + is.Len(list, 2) + is.True(lister.Truncated, "Expected Truncated to be true when limit < total") + + lister.Limit = 1 + lister.Offset = 1 + list, err = lister.Run() + is.NoError(err) + is.Len(list, 1) + is.True(lister.Truncated, "Expected Truncated to be true when offset + limit < total") + + lister.Limit = 1 + lister.Offset = 2 + list, err = lister.Run() + is.NoError(err) + is.Len(list, 1) + is.False(lister.Truncated, "Expected Truncated to be false when offset + limit == total") + + lister.Limit = 1 + lister.Offset = 3 + list, err = lister.Run() + is.NoError(err) + is.Len(list, 0) + is.False(lister.Truncated, "Expected Truncated to be false when offset >= total") +} + func TestList_StateMask(t *testing.T) { is := assert.New(t) lister := newListFixture(t) diff --git a/pkg/cmd/list.go b/pkg/cmd/list.go index 3c15a0954..0eb393dcf 100644 --- a/pkg/cmd/list.go +++ b/pkg/cmd/list.go @@ -113,7 +113,16 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { } } - return outfmt.Write(out, newReleaseListWriter(results, client.TimeFormat, client.NoHeaders, settings.ShouldDisableColor())) + if err := outfmt.Write(out, newReleaseListWriter(results, client.TimeFormat, client.NoHeaders, settings.ShouldDisableColor())); err != nil { + return err + } + + outputFlag := cmd.Flag("output") + if outputFlag.Value.String() == "table" && client.Truncated && !cmd.Flags().Changed("max") { + fmt.Fprintln(os.Stderr, "WARNING: results were truncated due to the default --max limit. Use --max to show more releases.") + } + + return nil }, } From 1f77d24a86b85a086b3a66ccbaa73173db95c96d Mon Sep 17 00:00:00 2001 From: John Weathers Date: Fri, 27 Feb 2026 18:04:58 -0500 Subject: [PATCH 2/2] fix(list): reset Truncated state and use Cobra stderr stream Reset Truncated on each Run(), use cmd.ErrOrStderr(), and reorder tests to cover early-return stale state. Signed-off-by: John Weathers --- pkg/action/list.go | 2 ++ pkg/action/list_test.go | 13 +++++++------ pkg/cmd/list.go | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pkg/action/list.go b/pkg/action/list.go index 7f83a4b1e..e254a4977 100644 --- a/pkg/action/list.go +++ b/pkg/action/list.go @@ -153,6 +153,8 @@ func (l *List) Run() ([]ri.Releaser, error) { return nil, err } + l.Truncated = false + var filter *regexp.Regexp if l.Filter != "" { var err error diff --git a/pkg/action/list_test.go b/pkg/action/list_test.go index 4a3759f28..e35b1f15c 100644 --- a/pkg/action/list_test.go +++ b/pkg/action/list_test.go @@ -209,19 +209,20 @@ func TestList_Truncation(t *testing.T) { is.Len(list, 1) is.True(lister.Truncated, "Expected Truncated to be true when offset + limit < total") + // Early return path should reset Truncated even after a truncated run lister.Limit = 1 - lister.Offset = 2 + lister.Offset = 3 list, err = lister.Run() is.NoError(err) - is.Len(list, 1) - is.False(lister.Truncated, "Expected Truncated to be false when offset + limit == total") + is.Len(list, 0) + is.False(lister.Truncated, "Expected Truncated to be false when offset >= total") lister.Limit = 1 - lister.Offset = 3 + lister.Offset = 2 list, err = lister.Run() is.NoError(err) - is.Len(list, 0) - is.False(lister.Truncated, "Expected Truncated to be false when offset >= total") + is.Len(list, 1) + is.False(lister.Truncated, "Expected Truncated to be false when offset + limit == total") } func TestList_StateMask(t *testing.T) { diff --git a/pkg/cmd/list.go b/pkg/cmd/list.go index 0eb393dcf..dc3d4fe0e 100644 --- a/pkg/cmd/list.go +++ b/pkg/cmd/list.go @@ -119,7 +119,7 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { outputFlag := cmd.Flag("output") if outputFlag.Value.String() == "table" && client.Truncated && !cmd.Flags().Changed("max") { - fmt.Fprintln(os.Stderr, "WARNING: results were truncated due to the default --max limit. Use --max to show more releases.") + fmt.Fprintln(cmd.ErrOrStderr(), "WARNING: results were truncated due to the default --max limit. Use --max to show more releases.") } return nil