Skip to content

Commit 00422d9

Browse files
committed
refactor: integrate UI components and enhance logging in webhook-cli
This commit enhances the webhook-cli by integrating UI components for improved output formatting and user interaction. It replaces standard error handling with formatted error messages and updates logging to utilize a new logging interface. Additionally, it refines command outputs for capture operations, including delete and list commands, to provide clearer and more structured information. Test cases have been added to validate these changes, ensuring robustness and reliability in user interactions.
1 parent 8ebd8d7 commit 00422d9

9 files changed

Lines changed: 419 additions & 155 deletions

File tree

apps/webhook-cli/cmd/better-webhook/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
rootcmd "github.com/endalk200/better-webhook/apps/webhook-cli/internal/cli/root"
2626
templatescmd "github.com/endalk200/better-webhook/apps/webhook-cli/internal/cli/templates"
2727
platformtime "github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/time"
28+
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/ui"
2829
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/version"
2930
)
3031

@@ -48,7 +49,7 @@ func main() {
4849
})
4950

5051
if err := rootCommand.Execute(); err != nil {
51-
_, _ = fmt.Fprintln(os.Stderr, err)
52+
_, _ = fmt.Fprintln(os.Stderr, ui.FormatError(err))
5253
os.Exit(1)
5354
}
5455
}

apps/webhook-cli/internal/adapters/transport/httpcapture/server.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import (
66
"errors"
77
"fmt"
88
"io"
9-
"log"
109
"net"
1110
"net/http"
1211
"sort"
1312
"strings"
1413
"sync"
1514
"time"
1615

16+
charmlog "github.com/charmbracelet/log"
17+
1718
appcapture "github.com/endalk200/better-webhook/apps/webhook-cli/internal/app/capture"
1819
domain "github.com/endalk200/better-webhook/apps/webhook-cli/internal/domain/capture"
1920
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/logging"
@@ -27,7 +28,8 @@ var (
2728
)
2829

2930
type Logger interface {
30-
Printf(format string, values ...interface{})
31+
Info(msg interface{}, keyvals ...interface{})
32+
Warn(msg interface{}, keyvals ...interface{})
3133
}
3234

3335
type RouteResolver interface {
@@ -70,7 +72,7 @@ func NewServer(options ServerOptions) (*Server, error) {
7072

7173
logger := options.Logger
7274
if logger == nil {
73-
logger = log.Default()
75+
logger = charmlog.Default()
7476
}
7577

7678
routeResolver := options.RouteResolver
@@ -211,17 +213,23 @@ func (s *Server) handleCaptureRequest(w http.ResponseWriter, req *http.Request)
211213
return
212214
}
213215

214-
if result.RelayErr != nil && s.options.Verbose {
215-
s.logger.Printf("relay hook error: %s", logging.SanitizeForLog(result.RelayErr.Error()))
216+
if result.RelayErr != nil {
217+
s.logger.Warn("relay hook error", "err", logging.SanitizeForLog(result.RelayErr.Error()))
216218
}
219+
217220
if s.options.Verbose {
218-
s.logger.Printf(
219-
"captured %s %s provider=%s file=%s body=%dB",
220-
logging.SanitizeForLog(result.Saved.Capture.Method),
221-
logging.SanitizeForLog(logging.TruncateForLog(result.Saved.Capture.Path, 256)),
222-
logging.SanitizeForLog(result.Saved.Capture.Provider),
223-
logging.SanitizeForLog(result.Saved.File),
224-
result.Saved.Capture.ContentLength,
221+
s.logger.Info("captured",
222+
"method", logging.SanitizeForLog(result.Saved.Capture.Method),
223+
"path", logging.SanitizeForLog(logging.TruncateForLog(result.Saved.Capture.Path, 256)),
224+
"provider", logging.SanitizeForLog(result.Saved.Capture.Provider),
225+
"file", logging.SanitizeForLog(result.Saved.File),
226+
"body", fmt.Sprintf("%dB", result.Saved.Capture.ContentLength),
227+
)
228+
} else {
229+
s.logger.Info("captured",
230+
"method", logging.SanitizeForLog(result.Saved.Capture.Method),
231+
"path", logging.SanitizeForLog(logging.TruncateForLog(result.Saved.Capture.Path, 256)),
232+
"provider", logging.SanitizeForLog(result.Saved.Capture.Provider),
225233
)
226234
}
227235

apps/webhook-cli/internal/cli/capture/command.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/adapters/transport/httpcapture"
1515
appcapture "github.com/endalk200/better-webhook/apps/webhook-cli/internal/app/capture"
1616
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/runtime"
17+
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/ui"
1718
)
1819

1920
type (
@@ -55,9 +56,10 @@ func NewCommand(deps Dependencies) *cobra.Command {
5556
return err
5657
}
5758

58-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Webhook capture server listening on http://%s:%d\n", captureArgs.Host, port)
59-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Captures directory: %s\n", captureArgs.CapturesDir)
60-
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Press Ctrl+C to stop")
59+
url := fmt.Sprintf("http://%s:%d", captureArgs.Host, port)
60+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s %s\n", ui.Bold.Render("Listening on"), ui.Info.Render(url))
61+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s %s\n", ui.Bold.Render("Captures dir"), ui.Muted.Render(captureArgs.CapturesDir))
62+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), ui.Faint.Render("Press Ctrl+C to stop"))
6163

6264
baseCtx := cmd.Context()
6365
if baseCtx == nil {

apps/webhook-cli/internal/cli/captures/command.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import (
55

66
appcaptures "github.com/endalk200/better-webhook/apps/webhook-cli/internal/app/captures"
77
replaycmd "github.com/endalk200/better-webhook/apps/webhook-cli/internal/cli/replay"
8+
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/ui"
89
)
910

1011
type ServiceFactory func(capturesDir string) (*appcaptures.Service, error)
1112

1213
type Dependencies struct {
1314
ServiceFactory ServiceFactory
1415
ReplayDependencies replaycmd.Dependencies
16+
Prompter ui.Prompter
1517
}
1618

1719
func NewCommand(deps Dependencies) *cobra.Command {

apps/webhook-cli/internal/cli/captures/delete_command.go

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package captures
22

33
import (
4-
"bufio"
54
"context"
6-
"errors"
75
"fmt"
8-
"io"
9-
"strings"
106

117
"github.com/spf13/cobra"
128

139
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/runtime"
10+
"github.com/endalk200/better-webhook/apps/webhook-cli/internal/platform/ui"
1411
)
1512

1613
func newDeleteCommand(deps Dependencies) *cobra.Command {
@@ -40,18 +37,23 @@ func newDeleteCommand(deps Dependencies) *cobra.Command {
4037
return mapCaptureCommandError(err, deleteArgs.Selector)
4138
}
4239

40+
prompter := deps.Prompter
41+
if prompter == nil {
42+
prompter = ui.DefaultPrompter
43+
}
44+
4345
if !deleteArgs.Force {
4446
id := target.Capture.ID
4547
if len(id) > 8 {
4648
id = id[:8]
4749
}
48-
prompt := fmt.Sprintf("Delete capture %s (%s %s)? [y/N]: ", id, target.Capture.Method, target.Capture.Path)
49-
confirmed, confirmErr := promptConfirm(cmd, prompt)
50+
prompt := fmt.Sprintf("Delete capture %s (%s %s)?", id, target.Capture.Method, target.Capture.Path)
51+
confirmed, confirmErr := prompter.Confirm(prompt, cmd.InOrStdin(), cmd.OutOrStdout())
5052
if confirmErr != nil {
5153
return confirmErr
5254
}
5355
if !confirmed {
54-
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Cancelled.")
56+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), ui.FormatCancelled())
5557
return nil
5658
}
5759
}
@@ -65,7 +67,7 @@ func newDeleteCommand(deps Dependencies) *cobra.Command {
6567
if len(shortID) > 8 {
6668
shortID = shortID[:8]
6769
}
68-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Deleted capture %s (%s)\n", shortID, deleted.File)
70+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), ui.FormatSuccess(fmt.Sprintf("Deleted capture %s (%s)", shortID, deleted.File)))
6971
return nil
7072
},
7173
}
@@ -74,21 +76,3 @@ func newDeleteCommand(deps Dependencies) *cobra.Command {
7476
cmd.Flags().String("captures-dir", "", "Directory where captures are stored")
7577
return cmd
7678
}
77-
78-
func promptConfirm(cmd *cobra.Command, prompt string) (bool, error) {
79-
_, _ = fmt.Fprint(cmd.OutOrStdout(), prompt)
80-
reader := bufio.NewReader(cmd.InOrStdin())
81-
line, err := reader.ReadString('\n')
82-
if err != nil {
83-
if errors.Is(err, io.EOF) {
84-
normalized := strings.TrimSpace(strings.ToLower(line))
85-
if normalized == "" {
86-
return false, nil
87-
}
88-
return normalized == "y" || normalized == "yes", nil
89-
}
90-
return false, err
91-
}
92-
normalized := strings.TrimSpace(strings.ToLower(line))
93-
return normalized == "y" || normalized == "yes", nil
94-
}

0 commit comments

Comments
 (0)