1
0

feat: 配置 golangci-lint 静态分析并修复存量违规

- 新增 backend/.golangci.yml 配置 12 个 linter(forbidigo、errorlint、errcheck、staticcheck、revive、gocritic、gosec、bodyclose、noctx、nilerr、goimports、gocyclo)
- 新增 lefthook.yml 配置 pre-commit hook 自动运行 lint
- 修复存量代码违规:errors.Is/As 替换、zap.Error 替换、import 排序、errcheck 修复
- 更新 README 补充编码规范说明
- 归档 backend-code-lint 变更
This commit is contained in:
2026-04-24 13:01:48 +08:00
parent 4c78ab6cc8
commit 4c6b49099d
96 changed files with 1290 additions and 1348 deletions

View File

@@ -13,10 +13,7 @@ import (
"strings"
"time"
"github.com/getlantern/systray"
"github.com/gin-gonic/gin"
"github.com/gofrs/flock"
"go.uber.org/zap"
"nex/embedfs"
"nex/backend/internal/config"
"nex/backend/internal/conversion"
@@ -28,9 +25,13 @@ import (
"nex/backend/internal/provider"
"nex/backend/internal/repository"
"nex/backend/internal/service"
pkgLogger "nex/backend/pkg/logger"
"nex/embedfs"
"github.com/getlantern/systray"
"github.com/gin-gonic/gin"
"github.com/gofrs/flock"
"go.uber.org/zap"
pkgLogger "nex/backend/pkg/logger"
)
var (
@@ -51,12 +52,16 @@ func main() {
showError("Nex Gateway", "已有 Nex 实例运行")
os.Exit(1)
}
defer singleLock.Unlock()
defer func() {
if err := singleLock.Unlock(); err != nil {
minimalLogger.Warn("释放实例锁失败", zap.Error(err))
}
}()
if err := checkPortAvailable(port); err != nil {
minimalLogger.Error("端口不可用", zap.Error(err))
showError("Nex Gateway", err.Error())
os.Exit(1)
return
}
cfg, err := config.LoadConfig()
@@ -75,7 +80,11 @@ func main() {
if err != nil {
minimalLogger.Fatal("初始化日志失败", zap.Error(err))
}
defer zapLogger.Sync()
defer func() {
if err := zapLogger.Sync(); err != nil {
minimalLogger.Warn("同步日志失败", zap.Error(err))
}
}()
cfg.PrintSummary(zapLogger)
@@ -144,14 +153,14 @@ func main() {
go func() {
zapLogger.Info("AI Gateway 启动", zap.String("addr", server.Addr))
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
zapLogger.Fatal("服务器启动失败", zap.String("error", err.Error()))
zapLogger.Fatal("服务器启动失败", zap.Error(err))
}
}()
go func() {
time.Sleep(500 * time.Millisecond)
if err := openBrowser(fmt.Sprintf("http://localhost:%d", port)); err != nil {
zapLogger.Warn("无法打开浏览器", zap.String("error", err.Error()))
zapLogger.Warn("无法打开浏览器", zap.Error(err))
}
}()
@@ -193,7 +202,7 @@ func setupRoutes(r *gin.Engine, proxyHandler *handler.ProxyHandler, providerHand
func setupStaticFiles(r *gin.Engine) {
distFS, err := fs.Sub(embedfs.FrontendDist, "frontend-dist")
if err != nil {
zapLogger.Fatal("无法加载前端资源", zap.String("error", err.Error()))
zapLogger.Fatal("无法加载前端资源", zap.Error(err))
}
getContentType := func(path string) string {
@@ -266,7 +275,7 @@ func setupSystray(port int) {
icon, err = embedfs.Assets.ReadFile("assets/icon.png")
}
if err != nil {
zapLogger.Error("无法加载托盘图标", zap.String("error", err.Error()))
zapLogger.Error("无法加载托盘图标", zap.Error(err))
}
systray.SetIcon(icon)
systray.SetTitle("Nex Gateway")
@@ -287,7 +296,9 @@ func setupSystray(port int) {
for {
select {
case <-mOpen.ClickedCh:
openBrowser(fmt.Sprintf("http://localhost:%d", port))
if err := openBrowser(fmt.Sprintf("http://localhost:%d", port)); err != nil {
zapLogger.Warn("打开浏览器失败", zap.Error(err))
}
case <-mAbout.ClickedCh:
showAbout()
case <-mQuit.ClickedCh:
@@ -308,7 +319,9 @@ func doShutdown() {
if server != nil {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
server.Shutdown(ctx)
if err := server.Shutdown(ctx); err != nil && zapLogger != nil {
zapLogger.Warn("关闭服务器失败", zap.Error(err))
}
}
if shutdownCancel != nil {
@@ -346,8 +359,8 @@ func (s *SingletonLock) Lock() error {
return nil
}
func (s *SingletonLock) Unlock() {
s.flock.Unlock()
func (s *SingletonLock) Unlock() error {
return s.flock.Unlock()
}
func openBrowser(url string) error {