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

Configure Feed

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

Implements linter for pkg/hold

authored by

Eduardo Cuducos and committed by tangled.org 2d5039d3 e0a2dda1

+137 -26
+11
.golangci.yml
··· 25 25 linters: 26 26 - errcheck 27 27 28 + # TODO: fix issues and remove these paths one by one 29 + - path: pkg/auth 30 + linters: 31 + - errcheck 32 + - path: pkg/appview 33 + linters: 34 + - errcheck 35 + - path: cmd/credential-helper 36 + linters: 37 + - errcheck 38 + 28 39 formatters: 29 40 enable: 30 41 - gofmt
+24
.tangled/workflows/lint.yaml
··· 1 + when: 2 + - event: ["push"] 3 + branch: ["*"] 4 + - event: ["pull_request"] 5 + branch: ["main"] 6 + 7 + engine: kubernetes 8 + image: golang:1.25-trixie 9 + architecture: amd64 10 + 11 + steps: 12 + - name: Download and Generate 13 + environment: 14 + CGO_ENABLED: 1 15 + command: | 16 + go mod download 17 + go generate ./... 18 + 19 + - name: Run Linter 20 + environment: 21 + CGO_ENABLED: 1 22 + command: | 23 + curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.2 24 + golangci-lint run ./...
+102 -26
pkg/hold/pds/xrpc.go
··· 207 207 } 208 208 209 209 w.Header().Set("Content-Type", "application/json") 210 - json.NewEncoder(w).Encode(response) 210 + if err := json.NewEncoder(w).Encode(response); err != nil { 211 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 212 + w.WriteHeader(http.StatusInternalServerError) 213 + } 211 214 } 212 215 213 216 // HandleDescribeServer returns server metadata ··· 227 230 } 228 231 229 232 w.Header().Set("Content-Type", "application/json") 230 - json.NewEncoder(w).Encode(response) 233 + if err := json.NewEncoder(w).Encode(response); err != nil { 234 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 235 + w.WriteHeader(http.StatusInternalServerError) 236 + } 231 237 } 232 238 233 239 // HandleResolveHandle resolves a handle to a DID ··· 255 261 } 256 262 257 263 w.Header().Set("Content-Type", "application/json") 258 - json.NewEncoder(w).Encode(response) 264 + if err := json.NewEncoder(w).Encode(response); err != nil { 265 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 266 + w.WriteHeader(http.StatusInternalServerError) 267 + } 259 268 } 260 269 261 270 // HandleGetProfile returns aggregated profile information ··· 290 299 response := h.buildProfileResponse(r.Context()) 291 300 292 301 w.Header().Set("Content-Type", "application/json") 293 - json.NewEncoder(w).Encode(response) 302 + if err := json.NewEncoder(w).Encode(response); err != nil { 303 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 304 + w.WriteHeader(http.StatusInternalServerError) 305 + } 294 306 } 295 307 296 308 // HandleGetProfiles returns aggregated profile information for multiple actors ··· 341 353 } 342 354 343 355 w.Header().Set("Content-Type", "application/json") 344 - json.NewEncoder(w).Encode(response) 356 + if err := json.NewEncoder(w).Encode(response); err != nil { 357 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 358 + w.WriteHeader(http.StatusInternalServerError) 359 + } 345 360 } 346 361 347 362 // buildProfileResponse builds a profile response map (shared by GetProfile and GetProfiles) ··· 435 450 } 436 451 437 452 w.Header().Set("Content-Type", "application/json") 438 - json.NewEncoder(w).Encode(response) 453 + if err := json.NewEncoder(w).Encode(response); err != nil { 454 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 455 + w.WriteHeader(http.StatusInternalServerError) 456 + } 439 457 } 440 458 441 459 // HandleGetRecord retrieves a record from the repository ··· 479 497 } 480 498 481 499 w.Header().Set("Content-Type", "application/json") 482 - json.NewEncoder(w).Encode(response) 500 + if err := json.NewEncoder(w).Encode(response); err != nil { 501 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 502 + w.WriteHeader(http.StatusInternalServerError) 503 + } 483 504 } 484 505 485 506 // HandleListRecords lists records in a collection ··· 551 572 // Empty repo, return empty list 552 573 response := map[string]any{"records": []any{}} 553 574 w.Header().Set("Content-Type", "application/json") 554 - json.NewEncoder(w).Encode(response) 575 + if err := json.NewEncoder(w).Encode(response); err != nil { 576 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 577 + w.WriteHeader(http.StatusInternalServerError) 578 + } 555 579 return 556 580 } 557 581 ··· 598 622 } 599 623 600 624 w.Header().Set("Content-Type", "application/json") 601 - json.NewEncoder(w).Encode(response) 625 + if err := json.NewEncoder(w).Encode(response); err != nil { 626 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 627 + w.WriteHeader(http.StatusInternalServerError) 628 + } 602 629 } 603 630 604 631 // handleListRecordsMST uses the legacy MST-based listing (fallback for tests) ··· 620 647 // Empty repo, return empty list 621 648 response := map[string]any{"records": []any{}} 622 649 w.Header().Set("Content-Type", "application/json") 623 - json.NewEncoder(w).Encode(response) 650 + if err := json.NewEncoder(w).Encode(response); err != nil { 651 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 652 + w.WriteHeader(http.StatusInternalServerError) 653 + } 624 654 return 625 655 } 626 656 ··· 729 759 } 730 760 731 761 w.Header().Set("Content-Type", "application/json") 732 - json.NewEncoder(w).Encode(response) 762 + if err := json.NewEncoder(w).Encode(response); err != nil { 763 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 764 + w.WriteHeader(http.StatusInternalServerError) 765 + } 733 766 } 734 767 735 768 // HandleDeleteRecord deletes a record from the repository ··· 799 832 if !currentCID.Equals(swapRecordCID) { 800 833 // Swap failed - record CID doesn't match 801 834 w.WriteHeader(http.StatusBadRequest) 802 - json.NewEncoder(w).Encode(map[string]any{ 835 + response := map[string]any{ 803 836 "error": "InvalidSwap", 804 837 "message": "record CID does not match swapRecord", 805 - }) 838 + } 839 + if err := json.NewEncoder(w).Encode(response); err != nil { 840 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 841 + w.WriteHeader(http.StatusInternalServerError) 842 + } 806 843 return 807 844 } 808 845 } ··· 846 883 } 847 884 848 885 w.Header().Set("Content-Type", "application/json") 849 - json.NewEncoder(w).Encode(response) 886 + if err := json.NewEncoder(w).Encode(response); err != nil { 887 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 888 + w.WriteHeader(http.StatusInternalServerError) 889 + } 850 890 } 851 891 852 892 // HandleSyncGetRecord returns a single record as a CAR file for sync ··· 900 940 } 901 941 902 942 // Write the CAR data to the response 903 - w.Write(buf.Bytes()) 943 + if _, err := w.Write(buf.Bytes()); err != nil { 944 + slog.Error("failed to write car to http response", "error", err, "path", r.URL.Path) 945 + w.WriteHeader(http.StatusInternalServerError) 946 + } 904 947 } 905 948 906 949 // HandleGetRepo returns the full repository as a CAR file ··· 1063 1106 } 1064 1107 1065 1108 w.Header().Set("Content-Type", "application/json") 1066 - json.NewEncoder(w).Encode(response) 1109 + if err := json.NewEncoder(w).Encode(response); err != nil { 1110 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1111 + w.WriteHeader(http.StatusInternalServerError) 1112 + } 1067 1113 } 1068 1114 1069 1115 // HandleGetBlob routes blob requests to appropriate handlers based on blob type ··· 1139 1185 "url": presignedURL, 1140 1186 } 1141 1187 w.Header().Set("Content-Type", "application/json") 1142 - json.NewEncoder(w).Encode(response) 1188 + if err := json.NewEncoder(w).Encode(response); err != nil { 1189 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1190 + w.WriteHeader(http.StatusInternalServerError) 1191 + } 1143 1192 } 1144 1193 1145 1194 // handleGetATProtoBlob handles standard ATProto blob requests ··· 1193 1242 "repos": []any{}, 1194 1243 } 1195 1244 w.Header().Set("Content-Type", "application/json") 1196 - json.NewEncoder(w).Encode(response) 1245 + if err := json.NewEncoder(w).Encode(response); err != nil { 1246 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1247 + w.WriteHeader(http.StatusInternalServerError) 1248 + } 1197 1249 return 1198 1250 } 1199 1251 ··· 1205 1257 "repos": []any{}, 1206 1258 } 1207 1259 w.Header().Set("Content-Type", "application/json") 1208 - json.NewEncoder(w).Encode(response) 1260 + if err := json.NewEncoder(w).Encode(response); err != nil { 1261 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1262 + w.WriteHeader(http.StatusInternalServerError) 1263 + } 1209 1264 return 1210 1265 } 1211 1266 ··· 1223 1278 } 1224 1279 1225 1280 w.Header().Set("Content-Type", "application/json") 1226 - json.NewEncoder(w).Encode(response) 1281 + if err := json.NewEncoder(w).Encode(response); err != nil { 1282 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1283 + w.WriteHeader(http.StatusInternalServerError) 1284 + } 1227 1285 } 1228 1286 1229 1287 // HandleGetRepoStatus returns the hosting status for a repository ··· 1252 1310 "active": true, 1253 1311 } 1254 1312 w.Header().Set("Content-Type", "application/json") 1255 - json.NewEncoder(w).Encode(response) 1313 + if err := json.NewEncoder(w).Encode(response); err != nil { 1314 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1315 + w.WriteHeader(http.StatusInternalServerError) 1316 + } 1256 1317 return 1257 1318 } 1258 1319 ··· 1264 1325 } 1265 1326 1266 1327 w.Header().Set("Content-Type", "application/json") 1267 - json.NewEncoder(w).Encode(response) 1328 + if err := json.NewEncoder(w).Encode(response); err != nil { 1329 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1330 + w.WriteHeader(http.StatusInternalServerError) 1331 + } 1268 1332 } 1269 1333 1270 1334 // HandleDIDDocument returns the DID document ··· 1276 1340 } 1277 1341 1278 1342 w.Header().Set("Content-Type", "application/json") 1279 - json.NewEncoder(w).Encode(doc) 1343 + if err := json.NewEncoder(w).Encode(doc); err != nil { 1344 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1345 + w.WriteHeader(http.StatusInternalServerError) 1346 + } 1280 1347 } 1281 1348 1282 1349 // HandleAtprotoDID returns the DID for handle resolution ··· 1375 1442 } 1376 1443 w.Header().Set("Content-Type", "application/json") 1377 1444 w.WriteHeader(http.StatusOK) 1378 - json.NewEncoder(w).Encode(response) 1445 + if err := json.NewEncoder(w).Encode(response); err != nil { 1446 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1447 + w.WriteHeader(http.StatusInternalServerError) 1448 + } 1379 1449 return 1380 1450 } 1381 1451 } ··· 1408 1478 1409 1479 w.Header().Set("Content-Type", "application/json") 1410 1480 w.WriteHeader(http.StatusCreated) 1411 - json.NewEncoder(w).Encode(response) 1481 + if err := json.NewEncoder(w).Encode(response); err != nil { 1482 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1483 + w.WriteHeader(http.StatusInternalServerError) 1484 + } 1412 1485 } 1413 1486 1414 1487 // GetPresignedURL generates a presigned URL for GET, HEAD, or PUT operations ··· 1546 1619 } 1547 1620 1548 1621 w.Header().Set("Content-Type", "application/json") 1549 - json.NewEncoder(w).Encode(stats) 1622 + if err := json.NewEncoder(w).Encode(stats); err != nil { 1623 + slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path) 1624 + w.WriteHeader(http.StatusInternalServerError) 1625 + } 1550 1626 }