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

Configure Feed

Select the types of activity you want to include in your feed.

various linting fixes

+83 -106
+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 }