Skip to content

Commit a6dda30

Browse files
committed
[lint] fix some issues
1 parent a31e01e commit a6dda30

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1653
-1369
lines changed

.github/workflows/pr.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ jobs:
1212
e2e:
1313
name: E2E
1414
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
1517
steps:
1618
# step 1: checkout repository code
1719
- name: Checkout code into workspace directory
@@ -72,6 +74,7 @@ jobs:
7274
with:
7375
go-version: stable
7476

77+
# RELEASE_ID: Days since project inception (2022-06-15)
7578
- name: Set RELEASE_ID env
7679
run: echo RELEASE_ID=$(( ($(date +%s) - $(date -d "2022-06-15" +%s)) / 86400 )) >> ${GITHUB_ENV}
7780

.golangci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ linters:
445445
wrapcheck:
446446
extra-ignore-sigs:
447447
- .JSON(
448+
- .SendStatus(
448449

449450
exclusions:
450451
generated: lax
@@ -473,7 +474,9 @@ linters:
473474
- dupl
474475
- err113
475476
- errcheck
477+
- exhaustruct
476478
- funlen
479+
- gocognit
477480
- goconst
478481
- gosec
479482
- noctx

internal/config/config.go

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type Gateway struct {
2525
}
2626

2727
type HTTP struct {
28-
Listen string `yaml:"listen" envconfig:"HTTP__LISTEN"` // listen address
28+
Listen string `yaml:"listen" envconfig:"HTTP__LISTEN"` // listen address
2929
Proxies []string `yaml:"proxies" envconfig:"HTTP__PROXIES"` // proxies
3030

3131
API API `yaml:"api"`
@@ -74,7 +74,7 @@ type SSE struct {
7474
}
7575

7676
type Messages struct {
77-
CacheTTLSeconds uint16 `yaml:"cache_ttl_seconds" envconfig:"MESSAGES__CACHE_TTL_SECONDS"` // cache ttl in seconds
77+
CacheTTLSeconds uint16 `yaml:"cache_ttl_seconds" envconfig:"MESSAGES__CACHE_TTL_SECONDS"` // cache ttl in seconds
7878
ProcessedLifetimeHours uint16 `yaml:"processed_lifetime_hours" envconfig:"MESSAGES__PROCESSED_LIFETIME_HOURS"`
7979
}
8080

@@ -86,39 +86,42 @@ type PubSub struct {
8686
URL string `yaml:"url" envconfig:"PUBSUB__URL"`
8787
}
8888

89-
var defaultConfig = Config{
90-
Gateway: Gateway{Mode: GatewayModePublic},
91-
HTTP: HTTP{
92-
Listen: ":3000",
93-
},
94-
Database: Database{
95-
Dialect: "mysql",
96-
Host: "localhost",
97-
Port: 3306,
98-
User: "sms",
99-
Password: "sms",
100-
Database: "sms",
101-
Timezone: "UTC",
102-
},
103-
FCM: FCMConfig{
104-
CredentialsJSON: "",
105-
},
106-
Tasks: Tasks{
107-
Hashing: HashingTask{
108-
IntervalSeconds: uint16(15 * 60),
89+
func Default() Config {
90+
//nolint:exhaustruct,mnd // default values
91+
return Config{
92+
Gateway: Gateway{Mode: GatewayModePublic},
93+
HTTP: HTTP{
94+
Listen: ":3000",
10995
},
110-
},
111-
SSE: SSE{
112-
KeepAlivePeriodSeconds: 15,
113-
},
114-
Messages: Messages{
115-
CacheTTLSeconds: 300, // 5 minutes
116-
ProcessedLifetimeHours: 720, // 30 days
117-
},
118-
Cache: Cache{
119-
URL: "memory://",
120-
},
121-
PubSub: PubSub{
122-
URL: "memory://",
123-
},
96+
Database: Database{
97+
Dialect: "mysql",
98+
Host: "localhost",
99+
Port: 3306,
100+
User: "sms",
101+
Password: "sms",
102+
Database: "sms",
103+
Timezone: "UTC",
104+
},
105+
FCM: FCMConfig{
106+
CredentialsJSON: "",
107+
},
108+
Tasks: Tasks{
109+
Hashing: HashingTask{
110+
IntervalSeconds: uint16(15 * 60),
111+
},
112+
},
113+
SSE: SSE{
114+
KeepAlivePeriodSeconds: 15,
115+
},
116+
Messages: Messages{
117+
CacheTTLSeconds: 300, // 5 minutes
118+
ProcessedLifetimeHours: 720, // 30 days
119+
},
120+
Cache: Cache{
121+
URL: "memory://",
122+
},
123+
PubSub: PubSub{
124+
URL: "memory://",
125+
},
126+
}
124127
}

internal/config/module.go

Lines changed: 117 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -19,114 +19,125 @@ import (
1919
"go.uber.org/zap"
2020
)
2121

22-
var Module = fx.Module(
23-
"appconfig",
24-
fx.Provide(
25-
func(log *zap.Logger) Config {
26-
if err := config.LoadConfig(&defaultConfig); err != nil {
27-
log.Error("Error loading config", zap.Error(err))
28-
}
22+
//nolint:funlen // long function
23+
func Module() fx.Option {
24+
return fx.Module(
25+
"appconfig",
26+
fx.Provide(
27+
func(log *zap.Logger) Config {
28+
defaultConfig := Default()
2929

30-
return defaultConfig
31-
},
32-
fx.Private,
33-
),
34-
fx.Provide(func(cfg Config) http.Config {
35-
return http.Config{
36-
Listen: cfg.HTTP.Listen,
37-
Proxies: cfg.HTTP.Proxies,
30+
if err := config.LoadConfig(&defaultConfig); err != nil {
31+
log.Error("Error loading config", zap.Error(err))
32+
}
3833

39-
WriteTimeout: 30 * time.Minute, // SSE requires longer timeout
40-
}
41-
}),
42-
fx.Provide(func(cfg Config) db.Config {
43-
return db.Config{
44-
Dialect: db.Dialect(cfg.Database.Dialect),
45-
Host: cfg.Database.Host,
46-
Port: cfg.Database.Port,
47-
User: cfg.Database.User,
48-
Password: cfg.Database.Password,
49-
Database: cfg.Database.Database,
50-
Timezone: cfg.Database.Timezone,
51-
Debug: cfg.Database.Debug,
34+
return defaultConfig
35+
},
36+
fx.Private,
37+
),
38+
fx.Provide(func(cfg Config) http.Config {
39+
const writeTimeout = 30 * time.Minute
5240

53-
MaxOpenConns: cfg.Database.MaxOpenConns,
54-
MaxIdleConns: cfg.Database.MaxIdleConns,
55-
}
56-
}),
57-
fx.Provide(func(cfg Config) push.Config {
58-
mode := push.ModeFCM
59-
if cfg.Gateway.Mode == GatewayModePrivate {
60-
mode = push.ModeUpstream
61-
}
41+
return http.Config{
42+
Listen: cfg.HTTP.Listen,
43+
Proxies: cfg.HTTP.Proxies,
6244

63-
return push.Config{
64-
Mode: mode,
65-
ClientOptions: map[string]string{
66-
"credentials": cfg.FCM.CredentialsJSON,
67-
},
68-
Debounce: time.Duration(cfg.FCM.DebounceSeconds) * time.Second,
69-
Timeout: time.Duration(cfg.FCM.TimeoutSeconds) * time.Second,
70-
}
71-
}),
72-
fx.Provide(func(cfg Config) messages.HashingTaskConfig {
73-
return messages.HashingTaskConfig{
74-
Interval: time.Duration(cfg.Tasks.Hashing.IntervalSeconds) * time.Second,
75-
}
76-
}),
77-
fx.Provide(func(cfg Config) auth.Config {
78-
return auth.Config{
79-
Mode: auth.Mode(cfg.Gateway.Mode),
80-
PrivateToken: cfg.Gateway.PrivateToken,
81-
}
82-
}),
83-
fx.Provide(func(cfg Config) handlers.Config {
84-
// Default and normalize API path/host
85-
if cfg.HTTP.API.Host == "" {
86-
cfg.HTTP.API.Path = "/api"
87-
}
88-
// Ensure leading slash and trim trailing slash (except root)
89-
if !strings.HasPrefix(cfg.HTTP.API.Path, "/") {
90-
cfg.HTTP.API.Path = "/" + cfg.HTTP.API.Path
91-
}
92-
if cfg.HTTP.API.Path != "/" && strings.HasSuffix(cfg.HTTP.API.Path, "/") {
93-
cfg.HTTP.API.Path = strings.TrimRight(cfg.HTTP.API.Path, "/")
94-
}
95-
// Guard against misconfigured scheme in host (accept "host[:port]" only)
96-
cfg.HTTP.API.Host = strings.TrimPrefix(strings.TrimPrefix(cfg.HTTP.API.Host, "https://"), "http://")
45+
WriteTimeout: writeTimeout, // SSE requires longer timeout
46+
}
47+
}),
48+
fx.Provide(func(cfg Config) db.Config {
49+
return db.Config{
50+
Dialect: db.Dialect(cfg.Database.Dialect),
51+
Host: cfg.Database.Host,
52+
Port: cfg.Database.Port,
53+
User: cfg.Database.User,
54+
Password: cfg.Database.Password,
55+
Database: cfg.Database.Database,
56+
Timezone: cfg.Database.Timezone,
57+
Debug: cfg.Database.Debug,
58+
MaxOpenConns: cfg.Database.MaxOpenConns,
59+
MaxIdleConns: cfg.Database.MaxIdleConns,
9760

98-
return handlers.Config{
99-
PublicHost: cfg.HTTP.API.Host,
100-
PublicPath: cfg.HTTP.API.Path,
101-
UpstreamEnabled: cfg.Gateway.Mode == GatewayModePublic,
102-
OpenAPIEnabled: cfg.HTTP.OpenAPI.Enabled,
103-
}
104-
}),
105-
fx.Provide(func(cfg Config) messages.Config {
106-
return messages.Config{
107-
ProcessedLifetime: time.Duration(cfg.Messages.ProcessedLifetimeHours) * time.Hour,
108-
CacheTTL: time.Duration(cfg.Messages.CacheTTLSeconds) * time.Second,
109-
}
110-
}),
111-
fx.Provide(func(cfg Config) devices.Config {
112-
return devices.Config{
113-
UnusedLifetime: 365 * 24 * time.Hour, //TODO: make it configurable
114-
}
115-
}),
116-
fx.Provide(func(cfg Config) sse.Config {
117-
return sse.NewConfig(
118-
sse.WithKeepAlivePeriod(time.Duration(cfg.SSE.KeepAlivePeriodSeconds) * time.Second),
119-
)
120-
}),
121-
fx.Provide(func(cfg Config) cache.Config {
122-
return cache.Config{
123-
URL: cfg.Cache.URL,
124-
}
125-
}),
126-
fx.Provide(func(cfg Config) pubsub.Config {
127-
return pubsub.Config{
128-
URL: cfg.PubSub.URL,
129-
BufferSize: 128,
130-
}
131-
}),
132-
)
61+
DSN: "",
62+
ConnMaxIdleTime: 0,
63+
ConnMaxLifetime: 0,
64+
}
65+
}),
66+
fx.Provide(func(cfg Config) push.Config {
67+
mode := push.ModeFCM
68+
if cfg.Gateway.Mode == GatewayModePrivate {
69+
mode = push.ModeUpstream
70+
}
71+
72+
return push.Config{
73+
Mode: mode,
74+
ClientOptions: map[string]string{
75+
"credentials": cfg.FCM.CredentialsJSON,
76+
},
77+
Debounce: time.Duration(cfg.FCM.DebounceSeconds) * time.Second,
78+
Timeout: time.Duration(cfg.FCM.TimeoutSeconds) * time.Second,
79+
}
80+
}),
81+
fx.Provide(func(cfg Config) messages.HashingTaskConfig {
82+
return messages.HashingTaskConfig{
83+
Interval: time.Duration(cfg.Tasks.Hashing.IntervalSeconds) * time.Second,
84+
}
85+
}),
86+
fx.Provide(func(cfg Config) auth.Config {
87+
return auth.Config{
88+
Mode: auth.Mode(cfg.Gateway.Mode),
89+
PrivateToken: cfg.Gateway.PrivateToken,
90+
}
91+
}),
92+
fx.Provide(func(cfg Config) handlers.Config {
93+
// Default and normalize API path/host
94+
if cfg.HTTP.API.Host == "" {
95+
cfg.HTTP.API.Path = "/api"
96+
}
97+
// Ensure leading slash and trim trailing slash (except root)
98+
if !strings.HasPrefix(cfg.HTTP.API.Path, "/") {
99+
cfg.HTTP.API.Path = "/" + cfg.HTTP.API.Path
100+
}
101+
if cfg.HTTP.API.Path != "/" && strings.HasSuffix(cfg.HTTP.API.Path, "/") {
102+
cfg.HTTP.API.Path = strings.TrimRight(cfg.HTTP.API.Path, "/")
103+
}
104+
// Guard against misconfigured scheme in host (accept "host[:port]" only)
105+
cfg.HTTP.API.Host = strings.TrimPrefix(strings.TrimPrefix(cfg.HTTP.API.Host, "https://"), "http://")
106+
107+
return handlers.Config{
108+
PublicHost: cfg.HTTP.API.Host,
109+
PublicPath: cfg.HTTP.API.Path,
110+
UpstreamEnabled: cfg.Gateway.Mode == GatewayModePublic,
111+
OpenAPIEnabled: cfg.HTTP.OpenAPI.Enabled,
112+
}
113+
}),
114+
fx.Provide(func(cfg Config) messages.Config {
115+
return messages.Config{
116+
ProcessedLifetime: time.Duration(cfg.Messages.ProcessedLifetimeHours) * time.Hour,
117+
CacheTTL: time.Duration(cfg.Messages.CacheTTLSeconds) * time.Second,
118+
}
119+
}),
120+
fx.Provide(func(_ Config) devices.Config {
121+
return devices.Config{
122+
UnusedLifetime: 365 * 24 * time.Hour, //TODO: make it configurable
123+
}
124+
}),
125+
fx.Provide(func(cfg Config) sse.Config {
126+
return sse.NewConfig(
127+
sse.WithKeepAlivePeriod(time.Duration(cfg.SSE.KeepAlivePeriodSeconds) * time.Second),
128+
)
129+
}),
130+
fx.Provide(func(cfg Config) cache.Config {
131+
return cache.Config{
132+
URL: cfg.Cache.URL,
133+
}
134+
}),
135+
fx.Provide(func(cfg Config) pubsub.Config {
136+
const bufferSize = 128
137+
return pubsub.Config{
138+
URL: cfg.PubSub.URL,
139+
BufferSize: bufferSize,
140+
}
141+
}),
142+
)
143+
}

0 commit comments

Comments
 (0)