A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go

various linting fixes

evan.jarrett.net efef46b1 fbcaf56f

verified
+2 -2
cmd/credential-helper/main.go
··· 180 180 181 181 // Wait for user to complete OAuth flow, then retry 182 182 fmt.Fprintf(os.Stderr, "Waiting for authentication") 183 - for i := 0; i < 60; i++ { // Wait up to 2 minutes 183 + for range 60 { // Wait up to 2 minutes 184 184 time.Sleep(2 * time.Second) 185 185 fmt.Fprintf(os.Stderr, ".") 186 186 ··· 765 765 curParts := strings.Split(curV, ".") 766 766 767 767 // Compare each part 768 - for i := 0; i < len(newParts) && i < len(curParts); i++ { 768 + for i := range min(len(newParts), len(curParts)) { 769 769 newNum := 0 770 770 curNum := 0 771 771 fmt.Sscanf(newParts[i], "%d", &newNum)
+4 -2
pkg/appview/db/device_store.go
··· 365 365 } 366 366 367 367 // UpdateLastUsed updates the last used timestamp 368 - func (s *DeviceStore) UpdateLastUsed(secretHash string) error { 368 + func (s *DeviceStore) UpdateLastUsed(secretHash string) { 369 369 _, err := s.db.Exec(` 370 370 UPDATE devices 371 371 SET last_used = ? 372 372 WHERE secret_hash = ? 373 373 `, time.Now(), secretHash) 374 374 375 - return err 375 + if err != nil { 376 + slog.Warn("Failed to update device last used timestamp", "component", "device_store", "error", err) 377 + } 376 378 } 377 379 378 380 // CleanupExpired removes expired pending authorizations
+4 -10
pkg/appview/db/device_store_test.go
··· 56 56 func TestGenerateUserCode(t *testing.T) { 57 57 // Generate multiple codes to test 58 58 codes := make(map[string]bool) 59 - for i := 0; i < 100; i++ { 59 + for range 100 { 60 60 code := generateUserCode() 61 61 62 62 // Test format: XXXX-XXXX ··· 372 372 return 373 373 } 374 374 if !tt.wantErr { 375 - if device == nil { 376 - t.Error("Expected device, got nil") 377 - } 378 375 if device.DID != "did:plc:alice123" { 379 376 t.Errorf("DID = %v, want did:plc:alice123", device.DID) 380 377 } ··· 399 396 } 400 397 401 398 // Create 3 devices 402 - for i := 0; i < 3; i++ { 399 + for i := range 3 { 403 400 pending, err := store.CreatePendingAuth("Device "+string(rune('A'+i)), "192.168.1.1", "Agent") 404 401 if err != nil { 405 402 t.Fatalf("CreatePendingAuth() error = %v", err) ··· 417 414 } 418 415 419 416 // Verify they're sorted by created_at DESC (newest first) 420 - for i := 0; i < len(devices)-1; i++ { 417 + for i := range len(devices) - 1 { 421 418 if devices[i].CreatedAt.Before(devices[i+1].CreatedAt) { 422 419 t.Error("Devices should be sorted by created_at DESC") 423 420 } ··· 521 518 time.Sleep(10 * time.Millisecond) 522 519 523 520 // Update last used 524 - err = store.UpdateLastUsed(device.SecretHash) 525 - if err != nil { 526 - t.Errorf("UpdateLastUsed() error = %v", err) 527 - } 521 + store.UpdateLastUsed(device.SecretHash) 528 522 529 523 // Verify it was updated 530 524 device2, err := store.ValidateDeviceSecret(secret)
+6 -8
pkg/appview/db/oauth_store.go
··· 213 213 } 214 214 215 215 // CleanupOldSessions removes sessions older than the specified duration 216 - func (s *OAuthStore) CleanupOldSessions(ctx context.Context, olderThan time.Duration) error { 216 + func (s *OAuthStore) CleanupOldSessions(ctx context.Context, olderThan time.Duration) { 217 217 cutoff := time.Now().Add(-olderThan) 218 218 219 219 result, err := s.db.ExecContext(ctx, ` ··· 222 222 `, cutoff) 223 223 224 224 if err != nil { 225 - return fmt.Errorf("failed to cleanup old sessions: %w", err) 225 + slog.Warn("Failed to cleanup old OAuth sessions", "component", "oauth_store", "error", err) 226 + return 226 227 } 227 228 228 229 deleted, _ := result.RowsAffected() 229 230 if deleted > 0 { 230 231 slog.Info("Cleaned up old OAuth sessions", "count", deleted, "older_than", olderThan) 231 232 } 232 - 233 - return nil 234 233 } 235 234 236 235 // CleanupExpiredAuthRequests removes auth requests older than 10 minutes 237 - func (s *OAuthStore) CleanupExpiredAuthRequests(ctx context.Context) error { 236 + func (s *OAuthStore) CleanupExpiredAuthRequests(ctx context.Context) { 238 237 cutoff := time.Now().Add(-10 * time.Minute) 239 238 240 239 result, err := s.db.ExecContext(ctx, ` ··· 243 242 `, cutoff) 244 243 245 244 if err != nil { 246 - return fmt.Errorf("failed to cleanup auth requests: %w", err) 245 + slog.Warn("Failed to cleanup expired auth requests", "component", "oauth_store", "error", err) 246 + return 247 247 } 248 248 249 249 deleted, _ := result.RowsAffected() 250 250 if deleted > 0 { 251 251 slog.Info("Cleaned up expired auth requests", "count", deleted) 252 252 } 253 - 254 - return nil 255 253 } 256 254 257 255 // InvalidateSessionsWithMismatchedScopes removes all sessions whose scopes don't match the desired scopes
+1 -3
pkg/appview/db/oauth_store_test.go
··· 353 353 } 354 354 355 355 // Run cleanup (remove sessions older than 30 days) 356 - if err := store.CleanupOldSessions(ctx, 30*24*time.Hour); err != nil { 357 - t.Fatalf("Failed to cleanup old sessions: %v", err) 358 - } 356 + store.CleanupOldSessions(ctx, 30*24*time.Hour) 359 357 360 358 // Verify old session was deleted 361 359 _, err = store.GetSession(ctx, did1, "old_session")
+2 -2
pkg/appview/db/session_store_test.go
··· 252 252 253 253 // Create multiple sessions for alice 254 254 sessionIDs := make([]string, 3) 255 - for i := 0; i < 3; i++ { 255 + for i := range 3 { 256 256 id, err := store.Create(did, "alice.bsky.social", "https://pds.example.com", 1*time.Hour) 257 257 if err != nil { 258 258 t.Fatalf("Create() error = %v", err) ··· 516 516 517 517 // Generate multiple session IDs 518 518 ids := make(map[string]bool) 519 - for i := 0; i < 100; i++ { 519 + for range 100 { 520 520 id, err := store.Create("did:plc:alice123", "alice.bsky.social", "https://pds.example.com", 1*time.Hour) 521 521 if err != nil { 522 522 t.Fatalf("Create() error = %v", err)
-13
pkg/appview/holdhealth/worker_test.go
··· 1 - package holdhealth 2 - 3 - import "testing" 4 - 5 - func TestWorker_Struct(t *testing.T) { 6 - // Simple struct test 7 - worker := &Worker{} 8 - if worker == nil { 9 - t.Error("Expected non-nil worker") 10 - } 11 - } 12 - 13 - // TODO: Add background health check tests
+1 -1
pkg/appview/jetstream/processor_test.go
··· 675 675 } 676 676 677 677 // Test 5: Process multiple deactivation events (idempotent) 678 - for i := 0; i < 3; i++ { 678 + for i := range 3 { 679 679 err = processor.ProcessAccount(context.Background(), testDID, false, "deactivated") 680 680 if err != nil { 681 681 t.Logf("Expected cache invalidation error on iteration %d: %v", i, err)
+1 -2
pkg/appview/jetstream/worker.go
··· 128 128 129 129 // Reset read deadline - we know connection is alive 130 130 // Allow 90 seconds for next pong (3x ping interval) 131 - conn.SetReadDeadline(time.Now().Add(90 * time.Second)) 132 - return nil 131 + return conn.SetReadDeadline(time.Now().Add(90 * time.Second)) 133 132 }) 134 133 135 134 // Set initial read deadline
+2 -2
pkg/appview/middleware/auth_test.go
··· 318 318 // Pre-create all users and sessions before concurrent access 319 319 // This ensures database is fully initialized before goroutines start 320 320 sessionIDs := make([]string, 10) 321 - for i := 0; i < 10; i++ { 321 + for i := range 10 { 322 322 did := fmt.Sprintf("did:plc:user%d", i) 323 323 handle := fmt.Sprintf("user%d.bsky.social", i) 324 324 ··· 358 358 var wg sync.WaitGroup 359 359 var mu sync.Mutex // Protect results map 360 360 361 - for i := 0; i < 10; i++ { 361 + for i := range 10 { 362 362 wg.Add(1) 363 363 go func(index int, sessionID string) { 364 364 defer wg.Done()
+1 -1
pkg/appview/middleware/registry.go
··· 555 555 556 556 // Store HTTP method in context for routing decisions 557 557 // This is used by routing_repository.go to distinguish pull (GET/HEAD) from push (PUT/POST) 558 - ctx = context.WithValue(ctx, "http.request.method", r.Method) 558 + ctx = context.WithValue(ctx, storage.HTTPRequestMethod, r.Method) 559 559 560 560 // Extract Authorization header 561 561 authHeader := r.Header.Get("Authorization")
+14 -13
pkg/appview/ogcard/card.go
··· 143 143 defer face.Close() 144 144 145 145 textWidth := font.MeasureString(face, text).Round() 146 - if align == AlignCenter { 146 + switch align { 147 + case AlignCenter: 147 148 x -= float64(textWidth) / 2 148 - } else if align == AlignRight { 149 + case AlignRight: 149 150 x -= float64(textWidth) 150 151 } 151 152 } ··· 292 293 // DrawRoundedRect draws a filled rounded rectangle 293 294 func (c *Card) DrawRoundedRect(x, y, w, h, radius int, col color.Color) { 294 295 // Draw main rectangle (without corners) 295 - for dy := radius; dy < h-radius; dy++ { 296 - for dx := 0; dx < w; dx++ { 297 - c.img.Set(x+dx, y+dy, col) 296 + for dy := range h - 2*radius { 297 + for dx := range w { 298 + c.img.Set(x+dx, y+radius+dy, col) 298 299 } 299 300 } 300 301 // Draw top and bottom strips (without corners) 301 - for dy := 0; dy < radius; dy++ { 302 - for dx := radius; dx < w-radius; dx++ { 303 - c.img.Set(x+dx, y+dy, col) 304 - c.img.Set(x+dx, y+h-1-dy, col) 302 + for dy := range radius { 303 + for dx := range w - 2*radius { 304 + c.img.Set(x+radius+dx, y+dy, col) 305 + c.img.Set(x+radius+dx, y+h-1-dy, col) 305 306 } 306 307 } 307 308 // Draw rounded corners 308 - for dy := 0; dy < radius; dy++ { 309 - for dx := 0; dx < radius; dx++ { 309 + for dy := range radius { 310 + for dx := range radius { 310 311 // Check if point is within circle 311 312 cx := radius - dx - 1 312 313 cy := radius - dy - 1 ··· 388 389 centerX := radius 389 390 centerY := radius 390 391 391 - for y := 0; y < diameter; y++ { 392 - for x := 0; x < diameter; x++ { 392 + for y := range diameter { 393 + for x := range diameter { 393 394 dx := x - centerX 394 395 dy := y - centerY 395 396 if dx*dx+dy*dy <= radius*radius {
+1
pkg/appview/readme/fetcher.go
··· 1 + // Package readme provides fetching and rendering of README files from Git hosting platforms. 1 2 package readme 2 3 3 4 import (
+1 -1
pkg/appview/readme/fetcher_test.go
··· 301 301 } 302 302 303 303 func containsSubstringHelper(s, substr string) bool { 304 - for i := 0; i <= len(s)-len(substr); i++ { 304 + for i := range len(s) - len(substr) + 1 { 305 305 if s[i:i+len(substr)] == substr { 306 306 return true 307 307 }
+1 -1
pkg/appview/storage/manifest_store.go
··· 76 76 // Notify hold about manifest pull (for stats tracking) 77 77 // Only count GET requests (actual downloads), not HEAD requests (existence checks) 78 78 // Check HTTP method from context (distribution library stores it as "http.request.method") 79 - if method, ok := ctx.Value("http.request.method").(string); ok && method == "GET" { 79 + if method, ok := ctx.Value(HTTPRequestMethod).(string); ok && method == "GET" { 80 80 // Do this asynchronously to avoid blocking the response 81 81 if s.ctx.ServiceToken != "" && s.ctx.Handle != "" { 82 82 go func() {
+1 -1
pkg/appview/storage/profile_test.go
··· 340 340 341 341 // Make 5 concurrent GetProfile calls 342 342 var wg sync.WaitGroup 343 - for i := 0; i < 5; i++ { 343 + for range 5 { 344 344 wg.Add(1) 345 345 go func() { 346 346 defer wg.Done()
+6 -5
pkg/appview/storage/proxy_blob_store.go
··· 552 552 } 553 553 554 554 // abortMultipartUpload aborts a multipart upload via XRPC abortUpload endpoint 555 - func (p *ProxyBlobStore) abortMultipartUpload(ctx context.Context, digest, uploadID string) error { 555 + func (p *ProxyBlobStore) abortMultipartUpload(ctx context.Context, uploadID string) error { 556 556 reqBody := map[string]any{ 557 557 "uploadId": uploadID, 558 558 } ··· 760 760 slog.Debug("Flushing final buffer", "component", "proxy_blob_store/Commit", "bytes", w.buffer.Len()) 761 761 if err := w.flushPart(); err != nil { 762 762 // Try to abort multipart on error 763 - tempDigest := fmt.Sprintf("uploads/temp-%s", w.id) 764 - w.store.abortMultipartUpload(ctx, tempDigest, w.uploadID) 763 + if err := w.store.abortMultipartUpload(ctx, w.uploadID); err != nil { 764 + slog.Warn("Failed to abort multipart upload", "component", "proxy_blob_store/Cancel", "error", err) 765 + // Continue anyway - we want to mark upload as cancelled 766 + } 765 767 return distribution.Descriptor{}, fmt.Errorf("failed to flush final part: %w", err) 766 768 } 767 769 } ··· 794 796 globalUploadsMu.Unlock() 795 797 796 798 // Abort multipart upload 797 - tempDigest := fmt.Sprintf("uploads/temp-%s", w.id) 798 - if err := w.store.abortMultipartUpload(ctx, tempDigest, w.uploadID); err != nil { 799 + if err := w.store.abortMultipartUpload(ctx, w.uploadID); err != nil { 799 800 slog.Warn("Failed to abort multipart upload", "component", "proxy_blob_store/Cancel", "error", err) 800 801 // Continue anyway - we want to mark upload as cancelled 801 802 }
+1 -1
pkg/appview/storage/proxy_blob_store_test.go
··· 563 563 { 564 564 name: "abortMultipartUpload", 565 565 testFunc: func(store *ProxyBlobStore) error { 566 - return store.abortMultipartUpload(context.Background(), "sha256:test", "upload-123") 566 + return store.abortMultipartUpload(context.Background(), "upload-123") 567 567 }, 568 568 expectedPath: atproto.HoldAbortUpload, 569 569 },
+5 -1
pkg/appview/storage/routing_repository.go
··· 11 11 "github.com/distribution/distribution/v3" 12 12 ) 13 13 14 + type contextKey string 15 + 16 + const HTTPRequestMethod contextKey = "http.request.method" 17 + 14 18 // RoutingRepository routes manifests to ATProto and blobs to external hold service 15 19 // The registry (AppView) is stateless and NEVER stores blobs locally 16 20 // NOTE: A fresh instance is created per-request (see middleware/registry.go) ··· 55 59 // Push operations use the discovery-based hold DID from user's profile/default 56 60 // This allows users to change their default hold and have new pushes go there 57 61 isPull := false 58 - if method, ok := ctx.Value("http.request.method").(string); ok { 62 + if method, ok := ctx.Value(HTTPRequestMethod).(string); ok { 59 63 isPull = method == "GET" || method == "HEAD" 60 64 } 61 65
+5 -5
pkg/appview/storage/routing_repository_test.go
··· 126 126 } 127 127 repo := NewRoutingRepository(nil, ctx) 128 128 129 - pullCtx := context.WithValue(context.Background(), "http.request.method", method) 129 + pullCtx := context.WithValue(context.Background(), HTTPRequestMethod, method) 130 130 blobStore := repo.Blobs(pullCtx) 131 131 132 132 assert.NotNil(t, blobStore) ··· 164 164 repo := NewRoutingRepository(nil, ctx) 165 165 166 166 // Create context with push method 167 - pushCtx := context.WithValue(context.Background(), "http.request.method", tc.method) 167 + pushCtx := context.WithValue(context.Background(), HTTPRequestMethod, tc.method) 168 168 blobStore := repo.Blobs(pushCtx) 169 169 170 170 assert.NotNil(t, blobStore) ··· 330 330 wg.Wait() 331 331 332 332 // Verify all stores are non-nil (due to race conditions, they may not all be the same instance) 333 - for i := 0; i < numGoroutines; i++ { 333 + for i := range numGoroutines { 334 334 assert.NotNil(t, manifestStores[i], "manifest store should not be nil") 335 335 } 336 336 ··· 351 351 wg.Wait() 352 352 353 353 // Verify all stores are non-nil (due to race conditions, they may not all be the same instance) 354 - for i := 0; i < numGoroutines; i++ { 354 + for i := range numGoroutines { 355 355 assert.NotNil(t, blobStores[i], "blob store should not be nil") 356 356 } 357 357 ··· 376 376 repo := NewRoutingRepository(nil, ctx) 377 377 378 378 // For pull (GET), database should take priority 379 - pullCtx := context.WithValue(context.Background(), "http.request.method", "GET") 379 + pullCtx := context.WithValue(context.Background(), HTTPRequestMethod, "GET") 380 380 blobStore := repo.Blobs(pullCtx) 381 381 382 382 assert.NotNil(t, blobStore)
+2 -2
pkg/atproto/directory_test.go
··· 35 35 instances := make(chan any, numGoroutines) 36 36 37 37 // Launch many goroutines concurrently accessing GetDirectory 38 - for i := 0; i < numGoroutines; i++ { 38 + for range numGoroutines { 39 39 go func() { 40 40 defer wg.Done() 41 41 dir := GetDirectory() ··· 73 73 t.Run("multiple calls in sequence", func(t *testing.T) { 74 74 // Get directory multiple times in sequence 75 75 dirs := make([]any, 10) 76 - for i := 0; i < 10; i++ { 76 + for i := range 10 { 77 77 dirs[i] = GetDirectory() 78 78 } 79 79
+1 -1
pkg/auth/cache.go
··· 1 - // Package token provides service token caching and management for AppView. 1 + // Package auth provides service token caching and management for AppView. 2 2 // Service tokens are JWTs issued by a user's PDS to authorize AppView to 3 3 // act on their behalf when communicating with hold services. Tokens are 4 4 // cached with automatic expiry parsing and 10-second safety margins.
-11
pkg/auth/hold_remote_test.go
··· 14 14 "atcr.io/pkg/atproto" 15 15 ) 16 16 17 - func TestNewRemoteHoldAuthorizer(t *testing.T) { 18 - // Test with nil database (should still work) 19 - authorizer := NewRemoteHoldAuthorizer(nil, false) 20 - if authorizer == nil { 21 - t.Fatal("Expected non-nil authorizer") 22 - } 23 - 24 - // Verify it implements the HoldAuthorizer interface 25 - var _ HoldAuthorizer = authorizer 26 - } 27 - 28 17 func TestNewRemoteHoldAuthorizer_TestMode(t *testing.T) { 29 18 // Test with testMode enabled 30 19 authorizer := NewRemoteHoldAuthorizer(nil, true)
+2 -1
pkg/auth/oauth/client_test.go
··· 1 1 package oauth 2 2 3 3 import ( 4 + "testing" 5 + 4 6 "github.com/bluesky-social/indigo/atproto/auth/oauth" 5 - "testing" 6 7 ) 7 8 8 9 func TestNewClientApp(t *testing.T) {
+2 -1
pkg/auth/oauth/server_test.go
··· 2 2 3 3 import ( 4 4 "context" 5 - "github.com/bluesky-social/indigo/atproto/auth/oauth" 6 5 "net/http" 7 6 "net/http/httptest" 8 7 "strings" 9 8 "testing" 10 9 "time" 10 + 11 + "github.com/bluesky-social/indigo/atproto/auth/oauth" 11 12 ) 12 13 13 14 func TestNewServer(t *testing.T) {
+1
pkg/auth/token/claims.go
··· 1 + // Package token provides JWT claims and token handling for registry authentication. 1 2 package token 2 3 3 4 import (
+1 -1
pkg/hold/pds/events_test.go
··· 150 150 testCID, _ := cid.Decode("bafyreib2rxk3rkhh5ylyxj3x3gathxt3s32qvwj2lf3qg4kmzr6b7teqke") 151 151 152 152 // Broadcast 5 events (exceeds maxHistory of 3) 153 - for i := 0; i < 5; i++ { 153 + for range 5 { 154 154 event := &RepoEvent{ 155 155 NewRoot: testCID, 156 156 Rev: "test-rev",
+3 -3
pkg/hold/pds/layer_test.go
··· 377 377 } 378 378 379 379 // Create layer records for owner 380 - for i := 0; i < 3; i++ { 380 + for i := range 3 { 381 381 record := atproto.NewLayerRecord( 382 382 "sha256:owner"+string(rune('a'+i)), 383 383 1024*1024*100, // 100MB each ··· 454 454 addCrewMemberWithBerth(t, pds, crewDID, "writer", []string{"blob:write"}, "") 455 455 456 456 // Create layer records for crew member 457 - for i := 0; i < 2; i++ { 457 + for i := range 2 { 458 458 record := atproto.NewLayerRecord( 459 459 "sha256:crew"+string(rune('a'+i)), 460 460 1024*1024*50, // 50MB each ··· 685 685 686 686 // Create multiple layer records with same digest (should be deduplicated) 687 687 digest := "sha256:duplicatelayer" 688 - for i := 0; i < 5; i++ { 688 + for i := range 5 { 689 689 record := atproto.NewLayerRecord( 690 690 digest, 691 691 1024*1024*100, // 100MB
+3 -3
pkg/hold/pds/records_test.go
··· 322 322 defer ri.Close() 323 323 324 324 // Add 5 records 325 - for i := 0; i < 5; i++ { 325 + for i := range 5 { 326 326 rkey := string(rune('a' + i)) 327 327 if err := ri.IndexRecord("io.atcr.hold.crew", rkey, "cid-"+rkey); err != nil { 328 328 t.Fatalf("IndexRecord() error = %v", err) ··· 473 473 defer ri.Close() 474 474 475 475 // Add records to two collections 476 - for i := 0; i < 3; i++ { 476 + for i := range 3 { 477 477 ri.IndexRecord("io.atcr.hold.crew", string(rune('a'+i)), "cid1") 478 478 } 479 - for i := 0; i < 5; i++ { 479 + for i := range 5 { 480 480 ri.IndexRecord("io.atcr.hold.captain", string(rune('a'+i)), "cid2") 481 481 } 482 482
+1 -2
pkg/hold/pds/server.go
··· 103 103 // Uses same database as carstore for simplicity 104 104 var recordsIndex *RecordsIndex 105 105 if dbPath != ":memory:" { 106 - recordsDbPath := dbPath + "/db.sqlite3" 107 - recordsIndex, err = NewRecordsIndex(recordsDbPath) 106 + recordsIndex, err = NewRecordsIndex(dbPath + "/db.sqlite3") 108 107 if err != nil { 109 108 return nil, fmt.Errorf("failed to create records index: %w", err) 110 109 }
+1 -1
pkg/hold/pds/status_test.go
··· 232 232 } 233 233 234 234 func findSubstring(s, substr string) bool { 235 - for i := 0; i <= len(s)-len(substr); i++ { 235 + for i := range len(s) - len(substr) + 1 { 236 236 if s[i:i+len(substr)] == substr { 237 237 return true 238 238 }
+4 -4
pkg/hold/pds/xrpc_test.go
··· 609 609 610 610 // Note: Bootstrap already added 1 crew member 611 611 // Add 4 more for a total of 5 612 - for i := 0; i < 4; i++ { 612 + for i := range 4 { 613 613 _, err := handler.pds.AddCrewMember(ctx, "did:plc:member"+string(rune(i+'0')), "reader", []string{"blob:read"}) 614 614 if err != nil { 615 615 t.Fatalf("Failed to add crew member: %v", err) ··· 673 673 holdDID := "did:web:hold.example.com" 674 674 675 675 // Add crew members 676 - for i := 0; i < 3; i++ { 676 + for i := range 3 { 677 677 _, err := handler.pds.AddCrewMember(ctx, "did:plc:member"+string(rune(i+'0')), "reader", []string{"blob:read"}) 678 678 if err != nil { 679 679 t.Fatalf("Failed to add crew member: %v", err) ··· 888 888 holdDID := "did:web:hold.example.com" 889 889 890 890 // Add 4 more crew members for total of 5 891 - for i := 0; i < 4; i++ { 891 + for i := range 4 { 892 892 _, err := handler.pds.AddCrewMember(ctx, fmt.Sprintf("did:plc:member%d", i), "reader", []string{"blob:read"}) 893 893 if err != nil { 894 894 t.Fatalf("Failed to add crew member: %v", err) ··· 968 968 holdDID := "did:web:hold.example.com" 969 969 970 970 // Add crew members 971 - for i := 0; i < 3; i++ { 971 + for i := range 3 { 972 972 _, err := handler.pds.AddCrewMember(ctx, fmt.Sprintf("did:plc:member%d", i), "reader", []string{"blob:read"}) 973 973 if err != nil { 974 974 t.Fatalf("Failed to add crew member: %v", err)
+1
pkg/hold/quota/config.go
··· 1 + // Package quota provides storage quota management for hold services. 1 2 package quota 2 3 3 4 import (
+2 -2
pkg/logging/logger_test.go
··· 366 366 defer slog.SetDefault(originalLogger) 367 367 368 368 b.ResetTimer() 369 - for i := 0; i < b.N; i++ { 369 + for range b.N { 370 370 InitLogger("info") 371 371 } 372 372 } ··· 376 376 defer slog.SetDefault(originalLogger) 377 377 378 378 b.ResetTimer() 379 - for i := 0; i < b.N; i++ { 379 + for range b.N { 380 380 cleanup := SetupTestLogger() 381 381 cleanup() 382 382 }