1
0
mirror of https://github.com/juanfont/headscale.git synced 2026-02-07 20:04:00 +01:00
juanfont.headscale/cmd/headscale/cli/SIMPLIFICATION.md
Kristoffer Dalby 67f2c20052 compli
2025-07-14 20:43:57 +00:00

82 lines
2.1 KiB
Markdown

# CLI Simplification - WithClient Pattern
## Problem
Every CLI command has repetitive gRPC client setup boilerplate:
```go
// This pattern appears 25+ times across all commands
ctx, client, conn, cancel := newHeadscaleCLIWithConfig()
defer cancel()
defer conn.Close()
// ... command logic ...
```
## Solution
Simple closure that handles client lifecycle:
```go
// client.go - 16 lines total
func WithClient(fn func(context.Context, v1.HeadscaleServiceClient) error) error {
ctx, client, conn, cancel := newHeadscaleCLIWithConfig()
defer cancel()
defer conn.Close()
return fn(ctx, client)
}
```
## Usage Example
### Before (users.go listUsersCmd):
```go
Run: func(cmd *cobra.Command, args []string) {
output, _ := cmd.Flags().GetString("output")
ctx, client, conn, cancel := newHeadscaleCLIWithConfig() // 4 lines
defer cancel()
defer conn.Close()
request := &v1.ListUsersRequest{}
// ... build request ...
response, err := client.ListUsers(ctx, request)
if err != nil {
ErrorOutput(err, "Cannot get users: "+status.Convert(err).Message(), output)
}
// ... handle response ...
}
```
### After:
```go
Run: func(cmd *cobra.Command, args []string) {
output, _ := cmd.Flags().GetString("output")
err := WithClient(func(ctx context.Context, client v1.HeadscaleServiceClient) error {
request := &v1.ListUsersRequest{}
// ... build request ...
response, err := client.ListUsers(ctx, request)
if err != nil {
ErrorOutput(err, "Cannot get users: "+status.Convert(err).Message(), output)
return err
}
// ... handle response ...
return nil
})
if err != nil {
return // Error already handled
}
}
```
## Benefits
- **Removes 4 lines of boilerplate** from every command
- **Ensures proper cleanup** - no forgetting defer statements
- **Simpler error handling** - return from closure, handled centrally
- **Easy to apply** - minimal changes to existing commands
## Rollout
This pattern can be applied to all 25+ commands systematically, removing ~100 lines of repetitive boilerplate.