style: adopt golangci-lint v2 and resolve all findings

Add .golangci.yml (v2): the standard linters plus bodyclose, errorlint, noctx, misspell, rowserrcheck, sqlclosecheck, unconvert, usestdlibvars, with gofumpt + goimports formatters. Enable the std-error-handling exclusion preset for idiomatic Close/Remove/Setenv ignores; scope-exclude SA1019 (parser.ParseDir in tools/openapigen) and ST1005 (intentional capitalized user-facing error copy that tests assert verbatim). No inline nolint directives were introduced.

Resolve all 217 findings behavior-preserving: gofumpt/goimports formatting, explicit blank assignment on intentionally ignored errors, errors.Is/errors.As and %w wrapping, context-aware stdlib calls (CommandContext/QueryContext/NewRequestWithContext/Dialer), staticcheck simplifications, removed redundant conversions, http.StatusOK and http.MethodGet, inlined the go:fix intPtr helper, and deferred sql rows Close. Add a golangci CI job mirroring the existing Go jobs.
This commit is contained in:
MHSanaei
2026-06-27 15:42:22 +02:00
parent 7efa0d9ddd
commit fa1a19c03c
81 changed files with 410 additions and 286 deletions
+11 -6
View File
@@ -2,6 +2,7 @@ package mtproto
import (
"bufio"
"context"
"encoding/json"
"fmt"
"net"
@@ -181,7 +182,7 @@ func (m *Manager) ensureLocked(inst Instance) error {
cur.tag = inst.Tag
return nil
}
cur.proc.Stop()
_ = cur.proc.Stop()
delete(m.procs, inst.Id)
}
metricsPort, err := FreeLocalPort()
@@ -211,7 +212,7 @@ func (m *Manager) Remove(id int) {
m.mu.Lock()
defer m.mu.Unlock()
if cur, ok := m.procs[id]; ok {
cur.proc.Stop()
_ = cur.proc.Stop()
delete(m.procs, id)
_ = os.Remove(configPathForID(id))
logger.Infof("mtproto: stopped mtg for inbound %d", id)
@@ -231,7 +232,7 @@ func (m *Manager) Reconcile(desired []Instance) {
}
for id, cur := range m.procs {
if _, ok := want[id]; !ok {
cur.proc.Stop()
_ = cur.proc.Stop()
delete(m.procs, id)
_ = os.Remove(configPathForID(id))
}
@@ -323,7 +324,7 @@ func (m *Manager) CollectTraffic() []Traffic {
// for mtg's metrics endpoint and to allocate the per-inbound SOCKS egress
// bridge port persisted into mtproto inbound settings.
func FreeLocalPort() (int, error) {
l, err := net.Listen("tcp", "127.0.0.1:0")
l, err := (&net.ListenConfig{}).Listen(context.Background(), "tcp", "127.0.0.1:0")
if err != nil {
return 0, err
}
@@ -383,7 +384,11 @@ func writeConfig(path string, inst Instance, metricsPort int) error {
// Best-effort: an unreachable endpoint or unrecognised format yields ok=false.
func scrapeTraffic(port int) (up int64, down int64, ok bool) {
client := http.Client{Timeout: 3 * time.Second}
resp, err := client.Get(fmt.Sprintf("http://127.0.0.1:%d/metrics", port))
req, reqErr := http.NewRequestWithContext(context.Background(), http.MethodGet, fmt.Sprintf("http://127.0.0.1:%d/metrics", port), nil)
if reqErr != nil {
return 0, 0, false
}
resp, err := client.Do(req)
if err != nil {
return 0, 0, false
}
@@ -418,7 +423,7 @@ func scrapeTraffic(port int) (up int64, down int64, ok bool) {
func parseMetricLine(line string) (name string, labels map[string]string, value float64, err error) {
labels = map[string]string{}
rest := line
var rest string
if brace := strings.IndexByte(line, '{'); brace >= 0 {
name = line[:brace]
end := strings.IndexByte(line, '}')
+2 -1
View File
@@ -5,6 +5,7 @@
package mtproto
import (
"context"
"errors"
"fmt"
"os"
@@ -154,7 +155,7 @@ func (p *Process) Start() error {
if p.IsRunning() {
return errors.New("mtg is already running")
}
cmd := exec.Command(GetBinaryPath(), "run", p.configPath)
cmd := exec.CommandContext(context.Background(), GetBinaryPath(), "run", p.configPath)
cmd.Stdout = p.logWriter
cmd.Stderr = p.logWriter
p.cmd = cmd
+4 -3
View File
@@ -7,8 +7,9 @@ import (
"sync"
"unsafe"
"github.com/mhsanaei/3x-ui/v3/internal/logger"
"golang.org/x/sys/windows"
"github.com/mhsanaei/3x-ui/v3/internal/logger"
)
var (
@@ -36,7 +37,7 @@ func ensureKillOnExitJob() (windows.Handle, error) {
uint32(unsafe.Sizeof(info)),
)
if err != nil {
windows.CloseHandle(h)
_ = windows.CloseHandle(h)
killOnExitJobErr = err
return
}
@@ -59,7 +60,7 @@ func attachChildLifetime(cmd *exec.Cmd) {
logger.Warningf("mtproto: OpenProcess for job attach failed: %v", err)
return
}
defer windows.CloseHandle(h)
defer func() { _ = windows.CloseHandle(h) }()
if err := windows.AssignProcessToJobObject(job, h); err != nil {
logger.Warningf("mtproto: AssignProcessToJobObject failed: %v", err)
}