|
| 1 | +# Migration Guide |
| 2 | + |
| 3 | +This guide covers migrating from the previous salt version to the new structure. |
| 4 | + |
| 5 | +## Go version |
| 6 | + |
| 7 | +Update `go.mod` to require Go 1.24: |
| 8 | + |
| 9 | +``` |
| 10 | +go 1.24 |
| 11 | +``` |
| 12 | + |
| 13 | +## Packages removed |
| 14 | + |
| 15 | +| Removed | Replacement | |
| 16 | +|---------|-------------| |
| 17 | +| `observability/logger` | Use `*slog.Logger` from `log/slog` directly | |
| 18 | +| `observability/otelgrpc` | Use `connectrpc.com/otelconnect` | |
| 19 | +| `observability/otelhttpclient` | Use `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` | |
| 20 | +| `server/mux` | Use `github.com/raystack/salt/server` | |
| 21 | +| `db` | Use your preferred DB library (sqlx, pgx, gorm) directly | |
| 22 | +| `auth/oidc` | Planned as complete CLI auth solution (#86) | |
| 23 | +| `auth/audit` | Planned with standardized schema (#87) | |
| 24 | +| `testing/dockertestx` | Use `ory/dockertest/v3` directly | |
| 25 | + |
| 26 | +## Packages moved |
| 27 | + |
| 28 | +| Old | New | |
| 29 | +|-----|-----| |
| 30 | +| `observability` | `telemetry` | |
| 31 | +| `cli/terminator` | `cli/terminal` | |
| 32 | +| `cli/prompter` | `cli/prompt` | |
| 33 | +| `cli/releaser` | `cli/version` | |
| 34 | + |
| 35 | +## Logger |
| 36 | + |
| 37 | +The custom `logger.Logger` interface and all backends (Zap, Logrus, Slog, Noop) are removed. Use `*slog.Logger` from the Go standard library directly. |
| 38 | + |
| 39 | +```go |
| 40 | +// Before |
| 41 | +import "github.com/raystack/salt/observability/logger" |
| 42 | +l := logger.NewZap() |
| 43 | +l := logger.NewLogrus() |
| 44 | +l := logger.NewNoop() |
| 45 | + |
| 46 | +// After |
| 47 | +import "log/slog" |
| 48 | +l := slog.Default() |
| 49 | +l := slog.New(slog.NewJSONHandler(os.Stderr, nil)) |
| 50 | +l := slog.New(slog.DiscardHandler) // noop |
| 51 | +``` |
| 52 | + |
| 53 | +All salt packages that previously accepted `logger.Logger` now accept `*slog.Logger`. |
| 54 | + |
| 55 | +## Server |
| 56 | + |
| 57 | +The dual-port `server/mux` package is replaced by a single-port `server` package with h2c support. |
| 58 | + |
| 59 | +```go |
| 60 | +// Before |
| 61 | +import "github.com/raystack/salt/server/mux" |
| 62 | +mux.Serve(ctx, |
| 63 | + mux.WithHTTPTarget(":8080", httpServer), |
| 64 | + mux.WithGRPCTarget(":8081", grpcServer), |
| 65 | +) |
| 66 | + |
| 67 | +// After |
| 68 | +import "github.com/raystack/salt/server" |
| 69 | +srv := server.New( |
| 70 | + server.WithAddr(":8080"), |
| 71 | + server.WithHandler("/api/", connectHandler), |
| 72 | +) |
| 73 | +srv.Start(ctx) |
| 74 | +``` |
| 75 | + |
| 76 | +H2C and health check (`/ping`) are enabled by default. Use `server.WithoutH2C()` or `server.WithHealthCheck("")` to disable. |
| 77 | + |
| 78 | +## App bootstrap |
| 79 | + |
| 80 | +New `app.Run()` for service bootstrap: |
| 81 | + |
| 82 | +```go |
| 83 | +import "github.com/raystack/salt/app" |
| 84 | + |
| 85 | +app.Run( |
| 86 | + app.WithConfig(&cfg, config.WithFile("config.yaml")), |
| 87 | + app.WithLogger(slog.Default()), |
| 88 | + app.WithHTTPMiddleware(middleware.DefaultHTTP(slog.Default())), |
| 89 | + app.WithHandler("/api/", handler), |
| 90 | + app.WithAddr(cfg.Addr), |
| 91 | +) |
| 92 | +``` |
| 93 | + |
| 94 | +HTTP middleware is explicit — use `middleware.DefaultHTTP(logger)` for the standard chain or compose your own. Database connections are managed via `app.WithOnStart` / `app.WithOnStop` hooks. |
| 95 | + |
| 96 | +## CLI bootstrap |
| 97 | + |
| 98 | +New `cli.Execute()` for CLI applications: |
| 99 | + |
| 100 | +```go |
| 101 | +// Before |
| 102 | +rootCmd := &cobra.Command{Use: "frontier", Short: "identity management"} |
| 103 | +mgr := commander.New(rootCmd, commander.WithTopics(topics)) |
| 104 | +mgr.Init() |
| 105 | +rootCmd.AddCommand(serverCmd, configCmd) |
| 106 | +rootCmd.Execute() |
| 107 | + |
| 108 | +// After |
| 109 | +import "github.com/raystack/salt/cli" |
| 110 | + |
| 111 | +cli.Execute( |
| 112 | + cli.Name("frontier"), |
| 113 | + cli.Description("identity management"), |
| 114 | + cli.Version("0.1.0", "raystack/frontier"), |
| 115 | + cli.Commands(serverCmd, configCmd), |
| 116 | + cli.Topics(topics...), |
| 117 | +) |
| 118 | +``` |
| 119 | + |
| 120 | +Access shared output and prompting in commands: |
| 121 | + |
| 122 | +```go |
| 123 | +func newListCmd() *cobra.Command { |
| 124 | + return &cobra.Command{ |
| 125 | + Use: "list", |
| 126 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 127 | + out := cli.Output(cmd) |
| 128 | + out.Table(rows) |
| 129 | + return nil |
| 130 | + }, |
| 131 | + } |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +## Printer |
| 136 | + |
| 137 | +Package-level functions replaced by `Output` type: |
| 138 | + |
| 139 | +```go |
| 140 | +// Before |
| 141 | +printer.Success("done") |
| 142 | +printer.Table(os.Stdout, rows) |
| 143 | +printer.JSON(data) |
| 144 | +spinner := printer.Spin("loading") |
| 145 | + |
| 146 | +// After |
| 147 | +out := printer.NewOutput(os.Stdout) |
| 148 | +// or inside a command: out := cli.Output(cmd) |
| 149 | + |
| 150 | +out.Success("done") |
| 151 | +out.Table(rows) |
| 152 | +out.JSON(data) |
| 153 | +spinner := out.Spin("loading") |
| 154 | +``` |
| 155 | + |
| 156 | +Color formatting functions remain as package-level helpers returning styled strings: |
| 157 | + |
| 158 | +```go |
| 159 | +printer.Green("text") |
| 160 | +printer.Greenf("count: %d", n) |
| 161 | +printer.Icon("success") // ✔ |
| 162 | +printer.Italic("note") |
| 163 | +``` |
| 164 | + |
| 165 | +## Telemetry |
| 166 | + |
| 167 | +```go |
| 168 | +// Before |
| 169 | +import "github.com/raystack/salt/observability" |
| 170 | +observability.Init(ctx, cfg, logger) |
| 171 | + |
| 172 | +// After |
| 173 | +import "github.com/raystack/salt/telemetry" |
| 174 | +telemetry.Init(ctx, cfg, slogLogger) |
| 175 | +``` |
| 176 | + |
| 177 | +## Middleware |
| 178 | + |
| 179 | +New package for ConnectRPC and HTTP middleware: |
| 180 | + |
| 181 | +```go |
| 182 | +import "github.com/raystack/salt/middleware" |
| 183 | + |
| 184 | +// Connect interceptors for your handler |
| 185 | +interceptors := middleware.Default(slog.Default()) |
| 186 | +handler := myv1connect.NewServiceHandler(svc, connect.WithInterceptors(interceptors...)) |
| 187 | + |
| 188 | +// HTTP middleware |
| 189 | +httpMW := middleware.DefaultHTTP(slog.Default()) |
| 190 | +``` |
| 191 | + |
| 192 | +## Config |
| 193 | + |
| 194 | +```go |
| 195 | +// Import path for validator changed |
| 196 | +// Before: "github.com/go-playground/validator" |
| 197 | +// After: "github.com/go-playground/validator/v10" |
| 198 | + |
| 199 | +// If you imported go-defaults directly: |
| 200 | +// Before: "github.com/mcuadros/go-defaults" |
| 201 | +// After: "github.com/creasty/defaults" |
| 202 | +// API change: defaults.SetDefaults(cfg) → defaults.Set(cfg) |
| 203 | +``` |
| 204 | + |
| 205 | +The config package no longer prints warnings to stdout when a config file is missing. |
| 206 | + |
| 207 | +## Dependency changes |
| 208 | + |
| 209 | +| Removed (direct) | Replacement | |
| 210 | +|-------------------|-------------| |
| 211 | +| `go.uber.org/zap` | `log/slog` (stdlib) | |
| 212 | +| `sirupsen/logrus` | `log/slog` (stdlib) | |
| 213 | +| `AlecAivazis/survey/v2` | `charmbracelet/huh` | |
| 214 | +| `olekukonko/tablewriter` | `text/tabwriter` (stdlib) | |
| 215 | +| `oklog/run` | Removed with `server/mux` | |
| 216 | +| `cli/safeexec` | `exec.LookPath` (stdlib) | |
| 217 | +| `pkg/errors` | `fmt.Errorf` with `%w` (stdlib) | |
| 218 | +| `mcuadros/go-defaults` | `creasty/defaults` | |
| 219 | +| `go-playground/validator` v9 | `go-playground/validator/v10` | |
| 220 | +| `jmoiron/sqlx` | Use directly if needed | |
| 221 | +| `golang-migrate` | Use directly if needed | |
| 222 | +| `ory/dockertest` | Use directly if needed | |
| 223 | + |
| 224 | +| Added | Purpose | |
| 225 | +|-------|---------| |
| 226 | +| `connectrpc.com/connect` | Middleware interceptors | |
| 227 | +| `charmbracelet/huh` | Interactive prompts | |
| 228 | +| `creasty/defaults` | Struct default values | |
| 229 | + |
| 230 | +| Upgraded | From → To | |
| 231 | +|----------|-----------| |
| 232 | +| `go-playground/validator` | v9 → v10 | |
| 233 | +| `charmbracelet/glamour` | v0.3 → v1.0.0 | |
| 234 | +| `muesli/termenv` | v0.11 → v0.16.0 | |
| 235 | +| `briandowns/spinner` | v1.18 → v1.23.2 | |
| 236 | +| `schollz/progressbar` | v3.8 → v3.19.0 | |
| 237 | +| `mattn/go-isatty` | v0.0.19 → v0.0.21 | |
0 commit comments