fix: address review feedback for truncation and DTO mapping
- commit
- 256e07443bb6fe3b28cd3b28b50272c563628969
- author
- brice · · 2026-01-17 13:29 UTC
- parent
- 87ca6dc
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +27 -3
M internal/adapters/in/cli/routes.go +19 -0
| @@ -23,6 +23,10 @@ var configPath string | |||
| 23 | 23 | // For tags, truncates to maxLen with ellipsis if needed. | |
| 24 | 24 | func truncateImage(image string, maxLen int) string { | |
| 25 | 25 | // Handle digest references: image@sha256:abc123... | |
| 26 | + | if maxLen <= 0 { | |
| 27 | + | return "" | |
| 28 | + | } | |
| 29 | + | ||
| 26 | 30 | if idx := strings.Index(image, "@sha256:"); idx != -1 { | |
| 27 | 31 | name := image[:idx] | |
| 28 | 32 | digest := image[idx+8:] // Skip "@sha256:" | |
| @@ -33,8 +37,14 @@ func truncateImage(image string, maxLen int) string { | |||
| 33 | 37 | if len(short) > maxLen { | |
| 34 | 38 | // Truncate from the end to maintain valid reference format | |
| 35 | 39 | if maxLen <= 3 { | |
| 40 | + | if len(short) < maxLen { | |
| 41 | + | return short | |
| 42 | + | } | |
| 36 | 43 | return short[:maxLen] | |
| 37 | 44 | } | |
| 45 | + | if len(short) <= maxLen { | |
| 46 | + | return short | |
| 47 | + | } | |
| 38 | 48 | return short[:maxLen-3] + "..." | |
| 39 | 49 | } | |
| 40 | 50 | return short | |
| @@ -43,6 +53,9 @@ func truncateImage(image string, maxLen int) string { | |||
| 43 | 53 | // Regular tag: truncate if needed | |
| 44 | 54 | if len(image) > maxLen { | |
| 45 | 55 | if maxLen <= 3 { | |
| 56 | + | if len(image) < maxLen { | |
| 57 | + | return image | |
| 58 | + | } | |
| 46 | 59 | return image[:maxLen] | |
| 47 | 60 | } | |
| 48 | 61 | return image[:maxLen-3] + "..." | |
| @@ -54,8 +67,14 @@ func truncateNetwork(network string, maxLen int) string { | |||
| 54 | 67 | if network == "" || network == "-" { | |
| 55 | 68 | return "-" | |
| 56 | 69 | } | |
| 70 | + | if maxLen <= 0 { | |
| 71 | + | return "" | |
| 72 | + | } | |
| 57 | 73 | if len(network) > maxLen { | |
| 58 | 74 | if maxLen <= 3 { | |
| 75 | + | if len(network) < maxLen { | |
| 76 | + | return network | |
| 77 | + | } | |
| 59 | 78 | return network[:maxLen] | |
| 60 | 79 | } | |
| 61 | 80 | return network[:maxLen-3] + "..." | |
| @@ -23,6 +23,10 @@ var configPath string | |||||
| 23 | // For tags, truncates to maxLen with ellipsis if needed. | 23 | // For tags, truncates to maxLen with ellipsis if needed. | ||
| 24 | func truncateImage(image string, maxLen int) string { | 24 | func truncateImage(image string, maxLen int) string { | ||
| 25 | // Handle digest references: image@sha256:abc123... | 25 | // Handle digest references: image@sha256:abc123... | ||
| 26 | + | if maxLen <= 0 { | |||
| 27 | + | return "" | |||
| 28 | + | } | |||
| 29 | + | ||||
| 26 | if idx := strings.Index(image, "@sha256:"); idx != -1 { | 30 | if idx := strings.Index(image, "@sha256:"); idx != -1 { | ||
| 27 | name := image[:idx] | 31 | name := image[:idx] | ||
| 28 | digest := image[idx+8:] // Skip "@sha256:" | 32 | digest := image[idx+8:] // Skip "@sha256:" | ||
| @@ -33,8 +37,14 @@ func truncateImage(image string, maxLen int) string { | |||||
| 33 | if len(short) > maxLen { | 37 | if len(short) > maxLen { | ||
| 34 | // Truncate from the end to maintain valid reference format | 38 | // Truncate from the end to maintain valid reference format | ||
| 35 | if maxLen <= 3 { | 39 | if maxLen <= 3 { | ||
| 40 | + | if len(short) < maxLen { | |||
| 41 | + | return short | |||
| 42 | + | } | |||
| 36 | return short[:maxLen] | 43 | return short[:maxLen] | ||
| 37 | } | 44 | } | ||
| 45 | + | if len(short) <= maxLen { | |||
| 46 | + | return short | |||
| 47 | + | } | |||
| 38 | return short[:maxLen-3] + "..." | 48 | return short[:maxLen-3] + "..." | ||
| 39 | } | 49 | } | ||
| 40 | return short | 50 | return short | ||
| @@ -43,6 +53,9 @@ func truncateImage(image string, maxLen int) string { | |||||
| 43 | // Regular tag: truncate if needed | 53 | // Regular tag: truncate if needed | ||
| 44 | if len(image) > maxLen { | 54 | if len(image) > maxLen { | ||
| 45 | if maxLen <= 3 { | 55 | if maxLen <= 3 { | ||
| 56 | + | if len(image) < maxLen { | |||
| 57 | + | return image | |||
| 58 | + | } | |||
| 46 | return image[:maxLen] | 59 | return image[:maxLen] | ||
| 47 | } | 60 | } | ||
| 48 | return image[:maxLen-3] + "..." | 61 | return image[:maxLen-3] + "..." | ||
| @@ -54,8 +67,14 @@ func truncateNetwork(network string, maxLen int) string { | |||||
| 54 | if network == "" || network == "-" { | 67 | if network == "" || network == "-" { | ||
| 55 | return "-" | 68 | return "-" | ||
| 56 | } | 69 | } | ||
| 70 | + | if maxLen <= 0 { | |||
| 71 | + | return "" | |||
| 72 | + | } | |||
| 57 | if len(network) > maxLen { | 73 | if len(network) > maxLen { | ||
| 58 | if maxLen <= 3 { | 74 | if maxLen <= 3 { | ||
| 75 | + | if len(network) < maxLen { | |||
| 76 | + | return network | |||
| 77 | + | } | |||
| 59 | return network[:maxLen] | 78 | return network[:maxLen] | ||
| 60 | } | 79 | } | ||
| 61 | return network[:maxLen-3] + "..." | 80 | return network[:maxLen-3] + "..." | ||
M internal/adapters/in/http/admin/handler.go +8 -1
| @@ -361,12 +361,19 @@ func (h *Handler) handleNetworks(w http.ResponseWriter, r *http.Request) { | |||
| 361 | 361 | if network == nil { | |
| 362 | 362 | continue | |
| 363 | 363 | } | |
| 364 | + | var labelsCopy map[string]string | |
| 365 | + | if network.Labels != nil { | |
| 366 | + | labelsCopy = make(map[string]string, len(network.Labels)) | |
| 367 | + | for key, value := range network.Labels { | |
| 368 | + | labelsCopy[key] = value | |
| 369 | + | } | |
| 370 | + | } | |
| 364 | 371 | response = append(response, dto.Network{ | |
| 365 | 372 | ID: network.ID, | |
| 366 | 373 | Name: network.Name, | |
| 367 | 374 | Driver: network.Driver, | |
| 368 | 375 | Containers: append([]string{}, network.Containers...), | |
| 369 | - | Labels: network.Labels, | |
| 376 | + | Labels: labelsCopy, | |
| 370 | 377 | }) | |
| 371 | 378 | } | |
| 372 | 379 | ||
| @@ -361,12 +361,19 @@ func (h *Handler) handleNetworks(w http.ResponseWriter, r *http.Request) { | |||||
| 361 | if network == nil { | 361 | if network == nil { | ||
| 362 | continue | 362 | continue | ||
| 363 | } | 363 | } | ||
| 364 | + | var labelsCopy map[string]string | |||
| 365 | + | if network.Labels != nil { | |||
| 366 | + | labelsCopy = make(map[string]string, len(network.Labels)) | |||
| 367 | + | for key, value := range network.Labels { | |||
| 368 | + | labelsCopy[key] = value | |||
| 369 | + | } | |||
| 370 | + | } | |||
| 364 | response = append(response, dto.Network{ | 371 | response = append(response, dto.Network{ | ||
| 365 | ID: network.ID, | 372 | ID: network.ID, | ||
| 366 | Name: network.Name, | 373 | Name: network.Name, | ||
| 367 | Driver: network.Driver, | 374 | Driver: network.Driver, | ||
| 368 | Containers: append([]string{}, network.Containers...), | 375 | Containers: append([]string{}, network.Containers...), | ||
| 369 | - | Labels: network.Labels, | 376 | + | Labels: labelsCopy, |
| 370 | }) | 377 | }) | ||
| 371 | } | 378 | } | ||
| 372 | 379 | ||||
M internal/adapters/in/http/registry/handler_test.go +0 -2
| @@ -94,8 +94,6 @@ func TestHandler_GetManifest_NotFound(t *testing.T) { | |||
| 94 | 94 | ||
| 95 | 95 | assert.Equal(t, http.StatusNotFound, rec.Code) | |
| 96 | 96 | assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) | |
| 97 | - | ||
| 98 | - | assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) | |
| 99 | 97 | } | |
| 100 | 98 | ||
| 101 | 99 | func TestHandler_BlobRoutes_MethodNotAllowed(t *testing.T) { | |
| @@ -94,8 +94,6 @@ func TestHandler_GetManifest_NotFound(t *testing.T) { | |||||
| 94 | 94 | ||||
| 95 | assert.Equal(t, http.StatusNotFound, rec.Code) | 95 | assert.Equal(t, http.StatusNotFound, rec.Code) | ||
| 96 | assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) | 96 | assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) | ||
| 97 | - | ||||
| 98 | - | assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) | |||
| 99 | } | 97 | } | ||
| 100 | 98 | ||||
| 101 | func TestHandler_BlobRoutes_MethodNotAllowed(t *testing.T) { | 99 | func TestHandler_BlobRoutes_MethodNotAllowed(t *testing.T) { | ||