fix(cli): propagate rollback list writer errors
- commit
- a3b6bfdf9be06c5c225edb0eed7018106a5975b7
- author
- bnema · · 2026-02-11 20:51 UTC
- parent
- 1c3348b
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +24 -6
M internal/adapters/in/cli/rollback.go +9 -5
| @@ -109,19 +109,23 @@ func runRollbackList(ctx context.Context, w io.Writer, rollbackDomain string) er | |||
| 109 | 109 | return err | |
| 110 | 110 | } | |
| 111 | 111 | ||
| 112 | - | printRollbackTags(w, rollbackDomain, currentTag, tags) | |
| 113 | - | return nil | |
| 112 | + | return printRollbackTags(w, rollbackDomain, currentTag, tags) | |
| 114 | 113 | } | |
| 115 | 114 | ||
| 116 | - | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string) { | |
| 117 | - | fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)) | |
| 115 | + | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string) error { | |
| 116 | + | if _, err := fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)); err != nil { | |
| 117 | + | return err | |
| 118 | + | } | |
| 118 | 119 | for _, tag := range tags { | |
| 119 | 120 | suffix := "" | |
| 120 | 121 | if tag == currentTag { | |
| 121 | 122 | suffix = " (current)" | |
| 122 | 123 | } | |
| 123 | - | fmt.Fprintf(w, "- %s%s\n", tag, suffix) | |
| 124 | + | if _, err := fmt.Fprintf(w, "- %s%s\n", tag, suffix); err != nil { | |
| 125 | + | return err | |
| 126 | + | } | |
| 124 | 127 | } | |
| 128 | + | return nil | |
| 125 | 129 | } | |
| 126 | 130 | ||
| 127 | 131 | func fetchAndSortTags(ctx context.Context, cp ControlPlane, imageName string) ([]string, error) { | |
| @@ -109,19 +109,23 @@ func runRollbackList(ctx context.Context, w io.Writer, rollbackDomain string) er | |||||
| 109 | return err | 109 | return err | ||
| 110 | } | 110 | } | ||
| 111 | 111 | ||||
| 112 | - | printRollbackTags(w, rollbackDomain, currentTag, tags) | 112 | + | return printRollbackTags(w, rollbackDomain, currentTag, tags) |
| 113 | - | return nil | |||
| 114 | } | 113 | } | ||
| 115 | 114 | ||||
| 116 | - | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string) { | 115 | + | func printRollbackTags(w io.Writer, rollbackDomain, currentTag string, tags []string) error { |
| 117 | - | fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)) | 116 | + | if _, err := fmt.Fprintf(w, "Available tags for %s:\n", styles.Theme.Bold.Render(rollbackDomain)); err != nil { |
| 117 | + | return err | |||
| 118 | + | } | |||
| 118 | for _, tag := range tags { | 119 | for _, tag := range tags { | ||
| 119 | suffix := "" | 120 | suffix := "" | ||
| 120 | if tag == currentTag { | 121 | if tag == currentTag { | ||
| 121 | suffix = " (current)" | 122 | suffix = " (current)" | ||
| 122 | } | 123 | } | ||
| 123 | - | fmt.Fprintf(w, "- %s%s\n", tag, suffix) | 124 | + | if _, err := fmt.Fprintf(w, "- %s%s\n", tag, suffix); err != nil { |
| 125 | + | return err | |||
| 126 | + | } | |||
| 124 | } | 127 | } | ||
| 128 | + | return nil | |||
| 125 | } | 129 | } | ||
| 126 | 130 | ||||
| 127 | func fetchAndSortTags(ctx context.Context, cp ControlPlane, imageName string) ([]string, error) { | 131 | func fetchAndSortTags(ctx context.Context, cp ControlPlane, imageName string) ([]string, error) { | ||
M internal/adapters/in/cli/rollback_test.go +15 -1
| @@ -2,11 +2,18 @@ package cli | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "bytes" | |
| 5 | + | "errors" | |
| 5 | 6 | "testing" | |
| 6 | 7 | ||
| 7 | 8 | "github.com/stretchr/testify/assert" | |
| 8 | 9 | ) | |
| 9 | 10 | ||
| 11 | + | type failingWriter struct{} | |
| 12 | + | ||
| 13 | + | func (failingWriter) Write(_ []byte) (int, error) { | |
| 14 | + | return 0, errors.New("write failed") | |
| 15 | + | } | |
| 16 | + | ||
| 10 | 17 | func TestSortSemverTags(t *testing.T) { | |
| 11 | 18 | tests := []struct { | |
| 12 | 19 | name string | |
| @@ -56,7 +63,8 @@ func TestValidateTagExists(t *testing.T) { | |||
| 56 | 63 | func TestPrintRollbackTags_WritesToProvidedWriter(t *testing.T) { | |
| 57 | 64 | var buf bytes.Buffer | |
| 58 | 65 | ||
| 59 | - | printRollbackTags(&buf, "myapp.example.com", "v1.2.0", []string{"v1.2.0", "v1.1.0"}) | |
| 66 | + | err := printRollbackTags(&buf, "myapp.example.com", "v1.2.0", []string{"v1.2.0", "v1.1.0"}) | |
| 67 | + | assert.NoError(t, err) | |
| 60 | 68 | ||
| 61 | 69 | output := buf.String() | |
| 62 | 70 | assert.Contains(t, output, "Available tags for") | |
| @@ -64,3 +72,9 @@ func TestPrintRollbackTags_WritesToProvidedWriter(t *testing.T) { | |||
| 64 | 72 | assert.Contains(t, output, "- v1.2.0 (current)") | |
| 65 | 73 | assert.Contains(t, output, "- v1.1.0") | |
| 66 | 74 | } | |
| 75 | + | ||
| 76 | + | func TestPrintRollbackTags_ReturnsWriteError(t *testing.T) { | |
| 77 | + | err := printRollbackTags(failingWriter{}, "myapp.example.com", "v1.2.0", []string{"v1.2.0"}) | |
| 78 | + | assert.Error(t, err) | |
| 79 | + | assert.Contains(t, err.Error(), "write failed") | |
| 80 | + | } | |
| @@ -2,11 +2,18 @@ package cli | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "bytes" | 4 | "bytes" | ||
| 5 | + | "errors" | |||
| 5 | "testing" | 6 | "testing" | ||
| 6 | 7 | ||||
| 7 | "github.com/stretchr/testify/assert" | 8 | "github.com/stretchr/testify/assert" | ||
| 8 | ) | 9 | ) | ||
| 9 | 10 | ||||
| 11 | + | type failingWriter struct{} | |||
| 12 | + | ||||
| 13 | + | func (failingWriter) Write(_ []byte) (int, error) { | |||
| 14 | + | return 0, errors.New("write failed") | |||
| 15 | + | } | |||
| 16 | + | ||||
| 10 | func TestSortSemverTags(t *testing.T) { | 17 | func TestSortSemverTags(t *testing.T) { | ||
| 11 | tests := []struct { | 18 | tests := []struct { | ||
| 12 | name string | 19 | name string | ||
| @@ -56,7 +63,8 @@ func TestValidateTagExists(t *testing.T) { | |||||
| 56 | func TestPrintRollbackTags_WritesToProvidedWriter(t *testing.T) { | 63 | func TestPrintRollbackTags_WritesToProvidedWriter(t *testing.T) { | ||
| 57 | var buf bytes.Buffer | 64 | var buf bytes.Buffer | ||
| 58 | 65 | ||||
| 59 | - | printRollbackTags(&buf, "myapp.example.com", "v1.2.0", []string{"v1.2.0", "v1.1.0"}) | 66 | + | err := printRollbackTags(&buf, "myapp.example.com", "v1.2.0", []string{"v1.2.0", "v1.1.0"}) |
| 67 | + | assert.NoError(t, err) | |||
| 60 | 68 | ||||
| 61 | output := buf.String() | 69 | output := buf.String() | ||
| 62 | assert.Contains(t, output, "Available tags for") | 70 | assert.Contains(t, output, "Available tags for") | ||
| @@ -64,3 +72,9 @@ func TestPrintRollbackTags_WritesToProvidedWriter(t *testing.T) { | |||||
| 64 | assert.Contains(t, output, "- v1.2.0 (current)") | 72 | assert.Contains(t, output, "- v1.2.0 (current)") | ||
| 65 | assert.Contains(t, output, "- v1.1.0") | 73 | assert.Contains(t, output, "- v1.1.0") | ||
| 66 | } | 74 | } | ||
| 75 | + | ||||
| 76 | + | func TestPrintRollbackTags_ReturnsWriteError(t *testing.T) { | |||
| 77 | + | err := printRollbackTags(failingWriter{}, "myapp.example.com", "v1.2.0", []string{"v1.2.0"}) | |||
| 78 | + | assert.Error(t, err) | |||
| 79 | + | assert.Contains(t, err.Error(), "write failed") | |||
| 80 | + | } | |||