---
name: xe-go-style
description: Write Go code following the conventions and patterns used in the within.website/x repository, including CLI patterns, error handling, logging with slog, HTTP handlers, and testing.
---

# Xe's Go Style Guide

Write Go code following the conventions and patterns used by Xe Iaso.

## Project Structure

```
├── cmd/            # Main applications (each subdirectory is a binary)
│   ├── x/          # CLI with subcommands
│   │   ├── main.go
│   │   └── cmd/    # Subcommand packages
│   └── sakurajima/ # Service binaries
│       ├── main.go
│       └── internal/  # Command-specific internal packages
├── internal/       # Private packages shared across commands
├── web/            # Web-related services and API clients
└── gen/            # Generated code (protobuf)
```

Package naming: lowercase, single words preferred (slog, flagenv, kahless).

## CLI Pattern (CRITICAL)

All command-line tools MUST call `flagenv.Parse()` and then `flag.Parse()`.

```go
package main

import (
    "flag"

    "github.com/facebookgo/flagenv"
)

var (
    bind  = flag.String("bind", ":8080", "HTTP bind address")
    dbLoc = flag.String("db-loc", "", "Database location")
)

func main() {
    flagenv.Parse()
    flag.Parse()
}
```

Configuration loading order: flags → env vars (flagenv) → flags (final override).

### Subcommands

Use `github.com/google/subcommands` for subcommand-based CLIs:

```go
package main

import (
    "context"
    "flag"
    "os"

    "github.com/facebookgo/flagenv"
    "github.com/google/subcommands"
)

func main() {
    flagenv.Parse()

    subcommands.Register(subcommands.HelpCommand(), "")
    subcommands.Register(subcommands.FlagsCommand(), "")
    subcommands.Register(subcommands.CommandsCommand(), "")
    subcommands.Register(&serveCmd{}, "")
    subcommands.Register(&versionCmd{}, "")

    os.Exit(int(subcommands.Execute(context.Background())))
}

type serveCmd struct {
    dbLoc string
}

func (c *serveCmd) Name() string     { return "serve" }
func (c *serveCmd) Synopsis() string { return "Start the server" }
func (c *serveCmd) Usage() string {
    return "serve [flags]\nStart the HTTP server.\n"
}

func (c *serveCmd) SetFlags(f *flag.FlagSet) {
    f.StringVar(&c.dbLoc, "db-loc", "", "Database location")
}

func (c *serveCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
    // Implementation
    return subcommands.ExitSuccess
}
```

Flag names use kebab-case: `--db-loc`, `--grpc-bind`, `--slog-level`.

## Error Handling

Define package-level sentinel errors:

```go
var ErrNotFound = errors.New("store: key not found")
var ErrCantDecode = errors.New("store: can't decode value")
```

Wrap errors with context using `%w`:

```go
if err != nil {
    return nil, fmt.Errorf("failed to connect to database: %w", err)
}
return nil, fmt.Errorf("ollama: error encoding request: %w", err)
```

Combine multiple validation errors with `errors.Join`:

```go
func (t *Toplevel) Valid() error {
    var errs []error
    if err := t.Bind.Valid(); err != nil {
        errs = append(errs, fmt.Errorf("invalid bind block:\n%w", err))
    }
    if len(errs) != 0 {
        return fmt.Errorf("invalid configuration file:\n%w", errors.Join(errs...))
    }
    return nil
}
```

Check errors with `errors.Is()` and `errors.As()`:

```go
if errors.Is(err, ErrNotFound) {
    // handle not found
}
```

Custom error types implement `Error()` and `slog.LogValue()`:

```go
type Error struct {
    WantStatus, GotStatus int
    URL                   *url.URL
    Method                string
    ResponseBody          string
}

func (e Error) Error() string {
    return fmt.Sprintf("%s %s: wanted status code %d, got: %d: %v",
        e.Method, e.URL, e.WantStatus, e.GotStatus, e.ResponseBody)
}

func (e Error) LogValue() slog.Value {
    return slog.GroupValue(
        slog.Int("want_status", e.WantStatus),
        slog.Int("got_status", e.GotStatus),
        slog.String("url", e.URL.String()),
        slog.String("method", e.Method),
        slog.String("body", e.ResponseBody),
    )
}
```

## Logging

Use `log/slog` (never the plain `log` package). Output JSON to stderr. Use `-slog-level` flag for runtime control.

```go
slog.Info("starting up",
    "bind", *bind,
    "db-loc", *dbLoc,
)
slog.Error("failed to create dao", "err", err)
slog.Debug("processing", "count", len(items))
```

Always use `"err"` as the key for errors. Implement `LogValue()` for complex types:

```go
func (s *Show) LogValue() slog.Value {
    return slog.GroupValue(
        slog.String("title", s.GetTitle()),
        slog.String("disk_path", s.GetDiskPath()),
    )
}
```

## HTTP Patterns

Middleware pattern:

```go
func PasswordMiddleware(username, password string, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        user, pass, ok := r.BasicAuth()
        if !ok || user != username || pass != password {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}
```

Chaining middleware:

```go
var h http.Handler = topLevel
h = xffMW.Handler(h)
h = cors.Default().Handler(h)
h = FlyRegionAnnotation(h)
```

HTTP client with context and error handling:

```go
func (c *Client) doRequest(ctx context.Context, method, path string, wantCode int, body io.Reader) (*http.Response, error) {
    req, err := http.NewRequestWithContext(ctx, method, u.String(), body)
    if err != nil {
        return nil, fmt.Errorf("failed to create request: %w", err)
    }

    resp, err := c.http.Do(req)
    if err != nil {
        return nil, fmt.Errorf("request failed: %w", err)
    }

    if resp.StatusCode != wantCode {
        return nil, web.NewError(wantCode, resp)
    }
    return resp, nil
}
```

Server lifecycle with errgroup:

```go
g, gCtx := errgroup.WithContext(ctx)

g.Go(func() error {
    ln, err := net.Listen("tcp", cfg.Bind.HTTP)
    if err != nil {
        return fmt.Errorf("failed to listen: %w", err)
    }
    return rtr.HandleHTTP(gCtx, ln)
})

return g.Wait()
```

## Testing

Tests co-located with source (`*_test.go`). Use table-driven tests:

```go
func TestDomainValid(t *testing.T) {
    t.Parallel()

    for _, tt := range []struct {
        name        string
        input       Domain
        err         error
        errContains string
    }{
        {name: "simple happy path", input: Domain{Name: "example.com"}},
        {name: "invalid domain", input: Domain{Name: "\uFFFD.com"}, err: ErrInvalidDomainName},
    } {
        t.Run(tt.name, func(t *testing.T) {
            err := tt.input.Valid()
            if tt.err != nil {
                if !errors.Is(err, tt.err) {
                    t.Logf("want: %v", tt.err)
                    t.Logf("got:  %v", err)
                    t.Error("got wrong error")
                }
            }
        })
    }
}
```

Testing best practices:

- Use `tt` as the loop variable in table-driven tests
- Always include `name` field for subtests
- Use `t.Helper()` for helper functions
- Use `t.Parallel()` for independent tests
- Use `t.TempDir()` for temporary directories
- Use `httptest.NewServer()` for HTTP mocking
- Use `errors.Is()` for error comparison
- Include `t.Logf("want: %v", x)` and `t.Logf("got: %v", y)` for debugging

```go
func loadConfig(t *testing.T, fname string) config.Toplevel {
    t.Helper()
    // ...
}
```

## Code Style

- Use `go fmt`/`goimports` for formatting
- Tabs for indentation
- `camelCase` for variables
- `PascalCase` for exported identifiers
- Files use snake_case
- Packages use lower-case module names
