readSeedFile reads seed data from various sources
(ctx context.Context, path string)
| 63 | |
| 64 | // readSeedFile reads seed data from various sources |
| 65 | func readSeedFile(ctx context.Context, path string) ([]*apiv0.ServerJSON, error) { |
| 66 | var data []byte |
| 67 | var err error |
| 68 | |
| 69 | if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { |
| 70 | // Handle HTTP URLs |
| 71 | if strings.HasSuffix(path, "/v0/servers") || strings.Contains(path, "/v0/servers") { |
| 72 | // This is a registry API endpoint - fetch paginated data |
| 73 | return fetchFromRegistryAPI(ctx, path) |
| 74 | } |
| 75 | // This is a direct file URL |
| 76 | data, err = fetchFromHTTP(ctx, path) |
| 77 | } else { |
| 78 | // Handle local file paths |
| 79 | data, err = os.ReadFile(path) |
| 80 | } |
| 81 | |
| 82 | if err != nil { |
| 83 | return nil, fmt.Errorf("failed to read seed data from %s: %w", path, err) |
| 84 | } |
| 85 | |
| 86 | // Parse ServerJSON array format |
| 87 | var serverResponses []apiv0.ServerJSON |
| 88 | if err := json.Unmarshal(data, &serverResponses); err != nil { |
| 89 | return nil, fmt.Errorf("failed to parse seed data as ServerJSON array format: %w", err) |
| 90 | } |
| 91 | |
| 92 | if len(serverResponses) == 0 { |
| 93 | return []*apiv0.ServerJSON{}, nil |
| 94 | } |
| 95 | |
| 96 | // Validate servers and collect warnings instead of failing the whole batch |
| 97 | var validRecords []*apiv0.ServerJSON |
| 98 | var invalidServers []string |
| 99 | var validationFailures []string |
| 100 | |
| 101 | for _, response := range serverResponses { |
| 102 | // ValidateServerJSON returns all validation results; using FirstError() to preserve existing behavior |
| 103 | // In future, consider logging all issues from result.Issues for better diagnostics |
| 104 | result := validators.ValidateServerJSON(&response, validators.ValidationSchemaVersionAndSemantic) |
| 105 | if err := result.FirstError(); err != nil { |
| 106 | // Log warning and track invalid server instead of failing |
| 107 | invalidServers = append(invalidServers, response.Name) |
| 108 | validationFailures = append(validationFailures, fmt.Sprintf("Server '%s': %v", response.Name, err)) |
| 109 | log.Printf("Warning: Skipping invalid server '%s': %v", response.Name, err) |
| 110 | continue |
| 111 | } |
| 112 | |
| 113 | // Add valid ServerJSON to records |
| 114 | validRecords = append(validRecords, &response) |
| 115 | } |
| 116 | |
| 117 | // Print summary of validation results |
| 118 | if len(invalidServers) > 0 { |
| 119 | log.Printf("Validation summary: %d servers passed validation, %d invalid servers skipped", len(validRecords), len(invalidServers)) |
| 120 | log.Printf("Invalid servers: %v", invalidServers) |
| 121 | for _, failure := range validationFailures { |
| 122 | log.Printf(" - %s", failure) |
no test coverage detected
searching dependent graphs…