## Summary - Disable the `ireturn` linter rule in golangci-lint configuration - Remove all related `nolint:ireturn` comments from the codebase The `ireturn` rule was flagging factory functions that intentionally return interfaces for dependency injection, which is a common and valid Go pattern. Since this pattern is used extensively throughout the codebase for good architectural reasons, it makes sense to disable this rule entirely. It also seems buggy, and seems to conflict with other lint rules - causing unnecessary toil.See: https://stackoverflow.com/questions/72385337/golang-linter-always-complains
152 lines
4.4 KiB
Go
152 lines
4.4 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/modelcontextprotocol/registry/internal/database"
|
|
"github.com/modelcontextprotocol/registry/internal/model"
|
|
)
|
|
|
|
// fakeRegistryService implements RegistryService interface with an in-memory database
|
|
type fakeRegistryService struct {
|
|
db *database.MemoryDB
|
|
}
|
|
|
|
// NewFakeRegistryService creates a new fake registry service with pre-populated data
|
|
func NewFakeRegistryService() RegistryService {
|
|
// Sample registry entries with updated model structure using ServerDetail
|
|
serverDetails := []*model.ServerDetail{
|
|
{
|
|
Name: "bluegreen/mcp-server",
|
|
Description: "A dummy MCP registry for testing",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/example/mcp-1",
|
|
Source: "github",
|
|
ID: "example/mcp-1",
|
|
},
|
|
VersionDetail: model.VersionDetail{
|
|
Version: "1.0.0",
|
|
},
|
|
},
|
|
{
|
|
Name: "orangepurple/mcp-server",
|
|
Description: "Another dummy MCP registry for testing",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/example/mcp-2",
|
|
Source: "github",
|
|
ID: "example/mcp-2",
|
|
},
|
|
VersionDetail: model.VersionDetail{
|
|
Version: "0.9.0",
|
|
},
|
|
},
|
|
{
|
|
Name: "greenyellow/mcp-server",
|
|
Description: "Yet another dummy MCP registry for testing",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/example/mcp-3",
|
|
Source: "github",
|
|
ID: "example/mcp-3",
|
|
},
|
|
VersionDetail: model.VersionDetail{
|
|
Version: "0.9.5",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create a new in-memory database using registry metadata IDs
|
|
serverDetailMap := make(map[string]*model.ServerDetail)
|
|
for _, entry := range serverDetails {
|
|
registryID := uuid.New().String() // Generate registry metadata ID
|
|
serverDetailMap[registryID] = entry
|
|
}
|
|
memDB := database.NewMemoryDB(serverDetailMap)
|
|
return &fakeRegistryService{
|
|
db: memDB,
|
|
}
|
|
}
|
|
|
|
// List retrieves servers with extension wrapper format
|
|
func (s *fakeRegistryService) List(cursor string, limit int) ([]model.ServerResponse, string, error) {
|
|
// Create a timeout context for the database operation
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
// Use the database's List method to get ServerRecord entries
|
|
serverRecords, nextCursor, err := s.db.List(ctx, nil, cursor, limit)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
// Convert ServerRecord to ServerResponse format
|
|
result := make([]model.ServerResponse, len(serverRecords))
|
|
for i, record := range serverRecords {
|
|
result[i] = record.ToServerResponse()
|
|
}
|
|
|
|
return result, nextCursor, nil
|
|
}
|
|
|
|
// GetByID retrieves a specific server by its registry metadata ID in extension wrapper format
|
|
func (s *fakeRegistryService) GetByID(id string) (*model.ServerResponse, error) {
|
|
// Create a timeout context for the database operation
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
// Use the database's GetByID method to retrieve the server record
|
|
serverRecord, err := s.db.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Convert ServerRecord to ServerResponse format
|
|
response := serverRecord.ToServerResponse()
|
|
return &response, nil
|
|
}
|
|
|
|
// Publish publishes a server with separated extensions
|
|
func (s *fakeRegistryService) Publish(req model.PublishRequest) (*model.ServerResponse, error) {
|
|
// Create a timeout context for the database operation
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
// Validate the request
|
|
if err := model.ValidatePublisherExtensions(req); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Validate server name exists
|
|
if _, err := model.ParseServerName(req.Server); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Extract publisher extensions from request
|
|
publisherExtensions := model.ExtractPublisherExtensions(req)
|
|
|
|
// Create registry metadata for fake service (always marks as latest)
|
|
now := time.Now()
|
|
registryMetadata := model.RegistryMetadata{
|
|
ID: uuid.New().String(),
|
|
PublishedAt: now,
|
|
UpdatedAt: now,
|
|
IsLatest: true,
|
|
ReleaseDate: now.Format(time.RFC3339),
|
|
}
|
|
|
|
// Publish to database
|
|
serverRecord, err := s.db.Publish(ctx, req.Server, publisherExtensions, registryMetadata)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Convert ServerRecord to ServerResponse format
|
|
response := serverRecord.ToServerResponse()
|
|
return &response, nil
|
|
}
|
|
|
|
// Close closes the in-memory database connection
|
|
func (s *fakeRegistryService) Close() error {
|
|
return s.db.Close()
|
|
}
|