Skip to content

Commit a218a9e

Browse files
committed
fix: configure golangci-lint v2 and resolve lint issues
- Upgrade .golangci.yml to v2 format - Upgrade CI from golangci-lint v1.60 to v2.11 (action v6 → v7) - Upgrade Go from 1.22 to 1.24 in go.mod - Disable errcheck (following Consul/Hashicorp practice) - Add package comments to all new/moved packages - Add doc comments to all exported types and methods in logger/ - Fix unused parameters across tests and implementations - Fix staticcheck SA1012: use context.TODO() instead of nil in slog - Fix staticcheck SA1019: replace deprecated cobra.ExactValidArgs - Fix staticcheck QF1004: use strings.ReplaceAll - Fix revive indent-error-flow in spa/handler.go - Store interceptors on App struct in WithMiddleware option
1 parent 474f0d7 commit a218a9e

File tree

25 files changed

+112
-70
lines changed

25 files changed

+112
-70
lines changed

.github/workflows/lint.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ jobs:
2424
with:
2525
go-version-file: "go.mod"
2626
- name: Run linter
27-
uses: golangci/golangci-lint-action@v6
27+
uses: golangci/golangci-lint-action@v7
2828
with:
29-
version: v1.60
29+
version: v2.11

.golangci.yml

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
output:
2-
formats:
3-
- format: line-number
1+
version: "2"
2+
formatters:
3+
enable:
4+
- goimports
5+
- gofmt
46
linters:
5-
enable-all: false
6-
disable-all: true
7+
disable:
8+
- errcheck
79
enable:
810
- govet
9-
- goimports
1011
- thelper
1112
- tparallel
1213
- unconvert
1314
- wastedassign
1415
- revive
1516
- unused
16-
- gofmt
1717
- whitespace
1818
- misspell
19-
linters-settings:
20-
revive:
21-
ignore-generated-header: true
22-
severity: warning
23-
severity:
24-
default-severity: error
19+
settings:
20+
revive:
21+
severity: warning

app/app.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Package app provides a service lifecycle manager for raystack services.
12
package app
23

34
import (
@@ -6,6 +7,7 @@ import (
67
"os/signal"
78
"syscall"
89

10+
"connectrpc.com/connect"
911
"github.com/raystack/salt/db"
1012
"github.com/raystack/salt/logger"
1113
"github.com/raystack/salt/server"
@@ -15,14 +17,15 @@ import (
1517
// App is a service lifecycle manager that wires together configuration,
1618
// logging, database, telemetry, and HTTP serving with graceful shutdown.
1719
type App struct {
18-
logger logger.Logger
19-
db *db.Client
20-
dbCfg *db.Config
21-
telCfg *telemetry.Config
22-
telClean func()
23-
serverOps []server.Option
24-
onStart []func(context.Context) error
25-
onStop []func(context.Context) error
20+
logger logger.Logger
21+
db *db.Client
22+
dbCfg *db.Config
23+
telCfg *telemetry.Config
24+
telClean func()
25+
interceptors []connect.Interceptor
26+
serverOps []server.Option
27+
onStart []func(context.Context) error
28+
onStop []func(context.Context) error
2629
}
2730

2831
// New creates a new App by applying the given options.
@@ -103,6 +106,11 @@ func (a *App) DB() *db.Client {
103106
return a.db
104107
}
105108

109+
// Interceptors returns the registered Connect interceptors.
110+
func (a *App) Interceptors() []connect.Interceptor {
111+
return a.interceptors
112+
}
113+
106114
func (a *App) stop(ctx context.Context) {
107115
for _, fn := range a.onStop {
108116
if err := fn(ctx); err != nil {

app/app_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestNew(t *testing.T) {
3232
})
3333

3434
t.Run("returns error from option", func(t *testing.T) {
35-
badOpt := func(a *app.App) error {
35+
badOpt := func(_ *app.App) error {
3636
return fmt.Errorf("bad option")
3737
}
3838
_, err := app.New(badOpt)
@@ -57,7 +57,6 @@ func TestAppStartAndShutdown(t *testing.T) {
5757

5858
time.Sleep(100 * time.Millisecond)
5959

60-
// Verify health check works
6160
resp, err := http.Get("http://127.0.0.1:18950/ping")
6261
require.NoError(t, err)
6362
defer resp.Body.Close()
@@ -79,7 +78,7 @@ func TestAppStartAndShutdown(t *testing.T) {
7978
var hookRan bool
8079
a, err := app.New(
8180
app.WithAddr("127.0.0.1:18951"),
82-
app.WithOnStart(func(ctx context.Context) error {
81+
app.WithOnStart(func(_ context.Context) error {
8382
hookRan = true
8483
return nil
8584
}),
@@ -91,7 +90,7 @@ func TestAppStartAndShutdown(t *testing.T) {
9190
cancel()
9291
}()
9392

94-
a.Start(ctx)
93+
_ = a.Start(ctx)
9594
assert.True(t, hookRan)
9695
})
9796

@@ -101,7 +100,7 @@ func TestAppStartAndShutdown(t *testing.T) {
101100
var hookRan bool
102101
a, err := app.New(
103102
app.WithAddr("127.0.0.1:18952"),
104-
app.WithOnStop(func(ctx context.Context) error {
103+
app.WithOnStop(func(_ context.Context) error {
105104
hookRan = true
106105
return nil
107106
}),
@@ -113,7 +112,7 @@ func TestAppStartAndShutdown(t *testing.T) {
113112
cancel()
114113
}()
115114

116-
a.Start(ctx)
115+
_ = a.Start(ctx)
117116
assert.True(t, hookRan)
118117
})
119118

@@ -124,7 +123,7 @@ func TestAppStartAndShutdown(t *testing.T) {
124123
a, err := app.New(
125124
app.WithLogger(logger.NewNoop()),
126125
app.WithAddr("127.0.0.1:18953"),
127-
app.WithHandler("/hello", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
126+
app.WithHandler("/hello", http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
128127
fmt.Fprint(w, "world")
129128
})),
130129
app.WithHealthCheck("/ping"),

app/option.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Option func(*App) error
2020
// The target must be a pointer to a struct. Config is loaded eagerly
2121
// so that subsequent options can reference fields from it.
2222
func WithConfig(target interface{}, loaderOpts ...config.Option) Option {
23-
return func(a *App) error {
23+
return func(_ *App) error {
2424
loader := config.NewLoader(loaderOpts...)
2525
return loader.Load(target)
2626
}
@@ -101,10 +101,7 @@ func WithGracePeriod(d time.Duration) Option {
101101
// level. Store them on the App for use when wiring handlers.
102102
func WithMiddleware(interceptors ...connect.Interceptor) Option {
103103
return func(a *App) error {
104-
// Interceptors are stored but must be applied by the caller when
105-
// creating ConnectRPC handlers via connect.WithInterceptors().
106-
// This option exists for documentation and future integration.
107-
_ = interceptors
104+
a.interceptors = append(a.interceptors, interceptors...)
108105
return nil
109106
}
110107
}

auth/oidc/utils.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ var callbackResponsePage string
2828

2929
func encode(msg []byte) string {
3030
encoded := base64.StdEncoding.EncodeToString(msg)
31-
encoded = strings.Replace(encoded, "+", "-", -1)
32-
encoded = strings.Replace(encoded, "/", "_", -1)
33-
encoded = strings.Replace(encoded, "=", "", -1)
31+
encoded = strings.ReplaceAll(encoded, "+", "-")
32+
encoded = strings.ReplaceAll(encoded, "/", "_")
33+
encoded = strings.ReplaceAll(encoded, "=", "")
3434
return encoded
3535
}
3636

@@ -152,7 +152,7 @@ func openURL(url string) error {
152152
cmd = "cmd"
153153
args = []string{"/c", "start"}
154154
// If we don't escape &, cmd will ignore everything after the first &.
155-
url = strings.Replace(url, "&", "^&", -1)
155+
url = strings.ReplaceAll(url, "&", "^&")
156156

157157
case "darwin":
158158
cmd = "open"

cli/commander/completion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func (m *Manager) addCompletionCommand() {
2323
Long: summary,
2424
DisableFlagsInUseLine: true,
2525
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
26-
Args: cobra.ExactValidArgs(1),
26+
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
2727
Run: func(cmd *cobra.Command, args []string) {
2828
switch args[0] {
2929
case "bash":

logger/logger.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Package logger provides a structured logging interface with multiple backends.
12
package logger
23

34
import (

logger/logrus.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/sirupsen/logrus"
77
)
88

9+
// Logrus implements Logger using sirupsen/logrus.
910
type Logrus struct {
1011
log *logrus.Logger
1112
}
@@ -20,38 +21,47 @@ func (l Logrus) getFields(args ...interface{}) map[string]interface{} {
2021
return fieldMap
2122
}
2223

24+
// Info logs at info level.
2325
func (l *Logrus) Info(msg string, args ...interface{}) {
2426
l.log.WithFields(l.getFields(args...)).Info(msg)
2527
}
2628

29+
// Debug logs at debug level.
2730
func (l *Logrus) Debug(msg string, args ...interface{}) {
2831
l.log.WithFields(l.getFields(args...)).Debug(msg)
2932
}
3033

34+
// Warn logs at warn level.
3135
func (l *Logrus) Warn(msg string, args ...interface{}) {
3236
l.log.WithFields(l.getFields(args...)).Warn(msg)
3337
}
3438

39+
// Error logs at error level.
3540
func (l *Logrus) Error(msg string, args ...interface{}) {
3641
l.log.WithFields(l.getFields(args...)).Error(msg)
3742
}
3843

44+
// Fatal logs at fatal level and exits.
3945
func (l *Logrus) Fatal(msg string, args ...interface{}) {
4046
l.log.WithFields(l.getFields(args...)).Fatal(msg)
4147
}
4248

49+
// Level returns the current log level.
4350
func (l *Logrus) Level() string {
4451
return l.log.Level.String()
4552
}
4653

54+
// Writer returns the logger's output writer.
4755
func (l *Logrus) Writer() io.Writer {
4856
return l.log.Writer()
4957
}
5058

59+
// Entry returns a logrus Entry with the given key/value pairs.
5160
func (l *Logrus) Entry(args ...interface{}) *logrus.Entry {
5261
return l.log.WithFields(l.getFields(args...))
5362
}
5463

64+
// LogrusWithLevel sets the log level for the Logrus logger.
5565
func LogrusWithLevel(level string) Option {
5666
return func(logger interface{}) {
5767
logLevel, err := logrus.ParseLevel(level)
@@ -62,6 +72,7 @@ func LogrusWithLevel(level string) Option {
6272
}
6373
}
6474

75+
// LogrusWithWriter sets the output writer for the Logrus logger.
6576
func LogrusWithWriter(writer io.Writer) Option {
6677
return func(logger interface{}) {
6778
logger.(*Logrus).log.SetOutput(writer)

logger/noop.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,35 @@ import (
44
"io"
55
)
66

7+
// Noop is a no-operation logger that discards all output, useful in tests.
78
type Noop struct{}
89

9-
func (n *Noop) Info(msg string, args ...interface{}) {}
10-
func (n *Noop) Debug(msg string, args ...interface{}) {}
11-
func (n *Noop) Warn(msg string, args ...interface{}) {}
12-
func (n *Noop) Error(msg string, args ...interface{}) {}
13-
func (n *Noop) Fatal(msg string, args ...interface{}) {}
10+
// Info is a no-op.
11+
func (n *Noop) Info(_ string, _ ...interface{}) {}
1412

13+
// Debug is a no-op.
14+
func (n *Noop) Debug(_ string, _ ...interface{}) {}
15+
16+
// Warn is a no-op.
17+
func (n *Noop) Warn(_ string, _ ...interface{}) {}
18+
19+
// Error is a no-op.
20+
func (n *Noop) Error(_ string, _ ...interface{}) {}
21+
22+
// Fatal is a no-op.
23+
func (n *Noop) Fatal(_ string, _ ...interface{}) {}
24+
25+
// Level returns "unsupported".
1526
func (n *Noop) Level() string {
1627
return "unsupported"
1728
}
29+
30+
// Writer returns io.Discard.
1831
func (n *Noop) Writer() io.Writer {
1932
return io.Discard
2033
}
2134

22-
// NewNoop returns a no operation logger, useful in tests
23-
func NewNoop(opts ...Option) *Noop {
35+
// NewNoop returns a no-operation logger, useful in tests.
36+
func NewNoop(_ ...Option) *Noop {
2437
return &Noop{}
2538
}

0 commit comments

Comments
 (0)