Skip to content

Commit c35e98a

Browse files
yuluo-yxrootfs
andauthored
infra: add golangci lint check (#401)
* infra: add golangci lint check Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * infra: add golangci lint check Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * fi Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * fix Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * infra: add golang ci lint for precommit hook Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * fix test and build ci error Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * fix: fix precommit parallel golangci-lint run error Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> * fix Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> --------- Signed-off-by: yuluo-yx <yuluo08290126@gmail.com> Co-authored-by: Huamin Chen <rootfs@users.noreply.github.com>
1 parent db323a5 commit c35e98a

Some content is hidden

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

56 files changed

+387
-215
lines changed

.github/workflows/pre-commit.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ jobs:
4848
pkg-config
4949
npm install -g markdownlint-cli
5050
pip install --user yamllint codespell
51+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0
5152
5253
- name: Cache Rust dependencies
5354
uses: actions/cache@v4

.github/workflows/test-and-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
make \
3333
build-essential \
3434
pkg-config
35+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0
3536
3637
- name: Cache Rust dependencies
3738
uses: actions/cache@v4
@@ -74,7 +75,6 @@ jobs:
7475
run: |
7576
pip install -U "huggingface_hub[cli]" hf_transfer
7677
77-
7878
- name: Download models (minimal on PRs)
7979
env:
8080
CI_MINIMAL_MODELS: ${{ github.event_name == 'pull_request' }}

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ repos:
2222
language: system
2323
files: \.go$
2424

25+
- repo: local
26+
hooks:
27+
- id: golang-lint
28+
name: go lint
29+
entry: make go-lint
30+
language: system
31+
files: \.go$
32+
pass_filenames: false
33+
2534
# Markdown specific hooks
2635
- repo: local
2736
hooks:

Dockerfile.precommit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ RUN pip install --break-system-packages yamllint
2929

3030
# CodeSpell
3131
RUN pip install --break-system-packages codespell
32+
33+
# Golangci-lint
34+
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0

src/semantic-router/cmd/main.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/prometheus/client_golang/prometheus/promhttp"
14+
1415
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/api"
1516
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/config"
1617
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/extproc"
@@ -63,16 +64,16 @@ func main() {
6364
ServiceVersion: cfg.Observability.Tracing.Resource.ServiceVersion,
6465
DeploymentEnvironment: cfg.Observability.Tracing.Resource.DeploymentEnvironment,
6566
}
66-
if err := observability.InitTracing(ctx, tracingCfg); err != nil {
67-
observability.Warnf("Failed to initialize tracing: %v", err)
67+
if tracingErr := observability.InitTracing(ctx, tracingCfg); tracingErr != nil {
68+
observability.Warnf("Failed to initialize tracing: %v", tracingErr)
6869
}
6970

7071
// Set up graceful shutdown for tracing
7172
defer func() {
7273
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
7374
defer cancel()
74-
if err := observability.ShutdownTracing(shutdownCtx); err != nil {
75-
observability.Errorf("Failed to shutdown tracing: %v", err)
75+
if shutdownErr := observability.ShutdownTracing(shutdownCtx); shutdownErr != nil {
76+
observability.Errorf("Failed to shutdown tracing: %v", shutdownErr)
7677
}
7778
}()
7879
}
@@ -86,8 +87,8 @@ func main() {
8687
observability.Infof("Received shutdown signal, cleaning up...")
8788
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
8889
defer cancel()
89-
if err := observability.ShutdownTracing(shutdownCtx); err != nil {
90-
observability.Errorf("Failed to shutdown tracing: %v", err)
90+
if shutdownErr := observability.ShutdownTracing(shutdownCtx); shutdownErr != nil {
91+
observability.Errorf("Failed to shutdown tracing: %v", shutdownErr)
9192
}
9293
os.Exit(0)
9394
}()
@@ -97,8 +98,8 @@ func main() {
9798
http.Handle("/metrics", promhttp.Handler())
9899
metricsAddr := fmt.Sprintf(":%d", *metricsPort)
99100
observability.Infof("Starting metrics server on %s", metricsAddr)
100-
if err := http.ListenAndServe(metricsAddr, nil); err != nil {
101-
observability.Errorf("Metrics server error: %v", err)
101+
if metricsErr := http.ListenAndServe(metricsAddr, nil); metricsErr != nil {
102+
observability.Errorf("Metrics server error: %v", metricsErr)
102103
}
103104
}()
104105

src/semantic-router/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
google.golang.org/grpc v1.75.0
3333
gopkg.in/yaml.v3 v3.0.1
3434
k8s.io/apimachinery v0.31.4
35+
sigs.k8s.io/yaml v1.6.0
3536
)
3637

3738
require (
@@ -89,6 +90,7 @@ require (
8990
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
9091
go.uber.org/automaxprocs v1.6.0 // indirect
9192
go.uber.org/multierr v1.11.0 // indirect
93+
go.yaml.in/yaml/v2 v2.4.2 // indirect
9294
golang.org/x/net v0.43.0 // indirect
9395
golang.org/x/sync v0.16.0 // indirect
9496
golang.org/x/sys v0.35.0 // indirect

src/semantic-router/go.sum

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
354354
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
355355
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
356356
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
357+
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
358+
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
359+
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
360+
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
357361
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
358362
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
359363
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -527,5 +531,5 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm
527531
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
528532
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
529533
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
530-
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
531-
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
534+
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
535+
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

src/semantic-router/pkg/api/server.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ func (s *ClassificationAPIServer) setupRoutes() *http.ServeMux {
225225
}
226226

227227
// handleHealth handles health check requests
228-
func (s *ClassificationAPIServer) handleHealth(w http.ResponseWriter, r *http.Request) {
228+
func (s *ClassificationAPIServer) handleHealth(w http.ResponseWriter, _ *http.Request) {
229229
w.Header().Set("Content-Type", "application/json")
230230
w.WriteHeader(http.StatusOK)
231-
w.Write([]byte(`{"status": "healthy", "service": "classification-api"}`))
231+
_, _ = w.Write([]byte(`{"status": "healthy", "service": "classification-api"}`))
232232
}
233233

234234
// APIOverviewResponse represents the response for GET /api/v1
@@ -363,19 +363,15 @@ type OpenAPIComponents struct {
363363
}
364364

365365
// handleAPIOverview handles GET /api/v1 for API discovery
366-
func (s *ClassificationAPIServer) handleAPIOverview(w http.ResponseWriter, r *http.Request) {
366+
func (s *ClassificationAPIServer) handleAPIOverview(w http.ResponseWriter, _ *http.Request) {
367367
// Build endpoints list from registry, filtering out disabled endpoints
368368
endpoints := make([]EndpointInfo, 0, len(endpointRegistry))
369369
for _, metadata := range endpointRegistry {
370370
// Filter out system prompt endpoints if they are disabled
371371
if !s.enableSystemPromptAPI && (metadata.Path == "/config/system-prompts") {
372372
continue
373373
}
374-
endpoints = append(endpoints, EndpointInfo{
375-
Path: metadata.Path,
376-
Method: metadata.Method,
377-
Description: metadata.Description,
378-
})
374+
endpoints = append(endpoints, EndpointInfo(metadata))
379375
}
380376

381377
response := APIOverviewResponse{
@@ -497,13 +493,13 @@ func (s *ClassificationAPIServer) generateOpenAPISpec() OpenAPISpec {
497493
}
498494

499495
// handleOpenAPISpec serves the OpenAPI 3.0 specification at /openapi.json
500-
func (s *ClassificationAPIServer) handleOpenAPISpec(w http.ResponseWriter, r *http.Request) {
496+
func (s *ClassificationAPIServer) handleOpenAPISpec(w http.ResponseWriter, _ *http.Request) {
501497
spec := s.generateOpenAPISpec()
502498
s.writeJSONResponse(w, http.StatusOK, spec)
503499
}
504500

505501
// handleSwaggerUI serves the Swagger UI at /docs
506-
func (s *ClassificationAPIServer) handleSwaggerUI(w http.ResponseWriter, r *http.Request) {
502+
func (s *ClassificationAPIServer) handleSwaggerUI(w http.ResponseWriter, _ *http.Request) {
507503
// Serve a simple HTML page that loads Swagger UI from CDN
508504
html := `<!DOCTYPE html>
509505
<html lang="en">
@@ -545,7 +541,7 @@ func (s *ClassificationAPIServer) handleSwaggerUI(w http.ResponseWriter, r *http
545541

546542
w.Header().Set("Content-Type", "text/html; charset=utf-8")
547543
w.WriteHeader(http.StatusOK)
548-
w.Write([]byte(html))
544+
_, _ = w.Write([]byte(html))
549545
}
550546

551547
// handleIntentClassification handles intent classification requests
@@ -609,7 +605,7 @@ func (s *ClassificationAPIServer) handleSecurityDetection(w http.ResponseWriter,
609605
}
610606

611607
// Placeholder handlers for remaining endpoints
612-
func (s *ClassificationAPIServer) handleCombinedClassification(w http.ResponseWriter, r *http.Request) {
608+
func (s *ClassificationAPIServer) handleCombinedClassification(w http.ResponseWriter, _ *http.Request) {
613609
s.writeErrorResponse(w, http.StatusNotImplemented, "NOT_IMPLEMENTED", "Combined classification not implemented yet")
614610
}
615611

@@ -631,7 +627,7 @@ func (s *ClassificationAPIServer) handleBatchClassification(w http.ResponseWrite
631627

632628
// Check if texts field exists in JSON
633629
var rawReq map[string]interface{}
634-
if err := json.Unmarshal(body, &rawReq); err != nil {
630+
if unmarshalErr := json.Unmarshal(body, &rawReq); unmarshalErr != nil {
635631
metrics.RecordBatchClassificationError("unified", "invalid_json")
636632
s.writeErrorResponse(w, http.StatusBadRequest, "INVALID_INPUT", "Invalid JSON format")
637633
return
@@ -645,9 +641,9 @@ func (s *ClassificationAPIServer) handleBatchClassification(w http.ResponseWrite
645641
}
646642

647643
var req BatchClassificationRequest
648-
if err := s.parseJSONRequest(r, &req); err != nil {
644+
if parseErr := s.parseJSONRequest(r, &req); parseErr != nil {
649645
metrics.RecordBatchClassificationError("unified", "parse_request_failed")
650-
s.writeErrorResponse(w, http.StatusBadRequest, "INVALID_INPUT", err.Error())
646+
s.writeErrorResponse(w, http.StatusBadRequest, "INVALID_INPUT", parseErr.Error())
651647
return
652648
}
653649

@@ -660,9 +656,9 @@ func (s *ClassificationAPIServer) handleBatchClassification(w http.ResponseWrite
660656
}
661657

662658
// Validate task_type if provided
663-
if err := validateTaskType(req.TaskType); err != nil {
659+
if validateErr := validateTaskType(req.TaskType); validateErr != nil {
664660
metrics.RecordBatchClassificationError("unified", "invalid_task_type")
665-
s.writeErrorResponse(w, http.StatusBadRequest, "INVALID_TASK_TYPE", err.Error())
661+
s.writeErrorResponse(w, http.StatusBadRequest, "INVALID_TASK_TYPE", validateErr.Error())
666662
return
667663
}
668664

@@ -703,12 +699,12 @@ func (s *ClassificationAPIServer) handleBatchClassification(w http.ResponseWrite
703699
s.writeJSONResponse(w, http.StatusOK, response)
704700
}
705701

706-
func (s *ClassificationAPIServer) handleModelsInfo(w http.ResponseWriter, r *http.Request) {
702+
func (s *ClassificationAPIServer) handleModelsInfo(w http.ResponseWriter, _ *http.Request) {
707703
response := s.buildModelsInfoResponse()
708704
s.writeJSONResponse(w, http.StatusOK, response)
709705
}
710706

711-
func (s *ClassificationAPIServer) handleClassifierInfo(w http.ResponseWriter, r *http.Request) {
707+
func (s *ClassificationAPIServer) handleClassifierInfo(w http.ResponseWriter, _ *http.Request) {
712708
if s.config == nil {
713709
s.writeJSONResponse(w, http.StatusOK, map[string]interface{}{
714710
"status": "no_config",
@@ -726,7 +722,7 @@ func (s *ClassificationAPIServer) handleClassifierInfo(w http.ResponseWriter, r
726722

727723
// handleOpenAIModels handles OpenAI-compatible model listing at /v1/models
728724
// It returns all models discoverable from the router configuration plus a synthetic "auto" model.
729-
func (s *ClassificationAPIServer) handleOpenAIModels(w http.ResponseWriter, r *http.Request) {
725+
func (s *ClassificationAPIServer) handleOpenAIModels(w http.ResponseWriter, _ *http.Request) {
730726
now := time.Now().Unix()
731727

732728
// Start with the special "auto" model always available from the router
@@ -763,15 +759,15 @@ func (s *ClassificationAPIServer) handleOpenAIModels(w http.ResponseWriter, r *h
763759
s.writeJSONResponse(w, http.StatusOK, resp)
764760
}
765761

766-
func (s *ClassificationAPIServer) handleClassificationMetrics(w http.ResponseWriter, r *http.Request) {
762+
func (s *ClassificationAPIServer) handleClassificationMetrics(w http.ResponseWriter, _ *http.Request) {
767763
s.writeErrorResponse(w, http.StatusNotImplemented, "NOT_IMPLEMENTED", "Classification metrics not implemented yet")
768764
}
769765

770-
func (s *ClassificationAPIServer) handleGetConfig(w http.ResponseWriter, r *http.Request) {
766+
func (s *ClassificationAPIServer) handleGetConfig(w http.ResponseWriter, _ *http.Request) {
771767
s.writeErrorResponse(w, http.StatusNotImplemented, "NOT_IMPLEMENTED", "Get config not implemented yet")
772768
}
773769

774-
func (s *ClassificationAPIServer) handleUpdateConfig(w http.ResponseWriter, r *http.Request) {
770+
func (s *ClassificationAPIServer) handleUpdateConfig(w http.ResponseWriter, _ *http.Request) {
775771
s.writeErrorResponse(w, http.StatusNotImplemented, "NOT_IMPLEMENTED", "Update config not implemented yet")
776772
}
777773

@@ -1096,7 +1092,7 @@ type SystemPromptUpdateRequest struct {
10961092
}
10971093

10981094
// handleGetSystemPrompts handles GET /config/system-prompts
1099-
func (s *ClassificationAPIServer) handleGetSystemPrompts(w http.ResponseWriter, r *http.Request) {
1095+
func (s *ClassificationAPIServer) handleGetSystemPrompts(w http.ResponseWriter, _ *http.Request) {
11001096
cfg := s.config
11011097
if cfg == nil {
11021098
http.Error(w, "Configuration not available", http.StatusInternalServerError)

src/semantic-router/pkg/cache/cache_test.go

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ import (
77
"testing"
88
"time"
99

10+
. "github.com/onsi/ginkgo/v2"
11+
. "github.com/onsi/gomega"
12+
"github.com/prometheus/client_golang/prometheus/testutil"
13+
1014
candle_binding "github.com/vllm-project/semantic-router/candle-binding"
1115
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/cache"
1216
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/metrics"
13-
14-
"github.com/prometheus/client_golang/prometheus/testutil"
15-
16-
. "github.com/onsi/ginkgo/v2"
17-
. "github.com/onsi/gomega"
1817
)
1918

2019
func TestCache(t *testing.T) {
@@ -29,9 +28,7 @@ var _ = BeforeSuite(func() {
2928
})
3029

3130
var _ = Describe("Cache Package", func() {
32-
var (
33-
tempDir string
34-
)
31+
var tempDir string
3532

3633
BeforeEach(func() {
3734
var err error
@@ -213,7 +210,6 @@ development:
213210
Expect(backend).To(BeNil())
214211
})
215212
})
216-
217213
})
218214

219215
Describe("ValidateCacheConfig", func() {
@@ -412,9 +408,7 @@ development:
412408
})
413409

414410
Describe("InMemoryCache", func() {
415-
var (
416-
inMemoryCache cache.CacheBackend
417-
)
411+
var inMemoryCache cache.CacheBackend
418412

419413
BeforeEach(func() {
420414
options := cache.InMemoryCacheOptions{
@@ -435,7 +429,7 @@ development:
435429

436430
It("should implement CacheBackend interface", func() {
437431
// Check that the concrete type implements the interface
438-
var _ cache.CacheBackend = inMemoryCache
432+
_ = inMemoryCache
439433
Expect(inMemoryCache).NotTo(BeNil())
440434
})
441435

src/semantic-router/pkg/cache/inmemory_cache_integration_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func TestInMemoryCacheIntegration(t *testing.T) {
4646

4747
// Step 3: Access first entry multiple times to increase its frequency
4848
for range 2 {
49-
responseBody, found, err := cache.FindSimilar("test-model", "Hello world")
50-
if err != nil {
51-
t.Logf("FindSimilar failed (expected due to high threshold): %v", err)
49+
responseBody, found, findErr := cache.FindSimilar("test-model", "Hello world")
50+
if findErr != nil {
51+
t.Logf("FindSimilar failed (expected due to high threshold): %v", findErr)
5252
}
5353
if !found {
5454
t.Errorf("Expected to find similar entry for first query")

0 commit comments

Comments
 (0)