tangled
alpha
login
or
join now
cuducos.me
/
at-container-registry
forked from
evan.jarrett.net/at-container-registry
0
fork
atom
A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
0
fork
atom
overview
issues
pulls
pipelines
Implements linter for pkg/hold
Eduardo Cuducos
2 months ago
d6739dfc
482d921c
+137
-26
3 changed files
expand all
collapse all
unified
split
.golangci.yml
.tangled
workflows
lint.yaml
pkg
hold
pds
xrpc.go
+11
.golangci.yml
reviewed
···
25
25
linters:
26
26
- errcheck
27
27
28
28
+
# TODO: fix issues and remove these paths one by one
29
29
+
- path: pkg/auth
30
30
+
linters:
31
31
+
- errcheck
32
32
+
- path: pkg/appview
33
33
+
linters:
34
34
+
- errcheck
35
35
+
- path: cmd/credential-helper
36
36
+
linters:
37
37
+
- errcheck
38
38
+
28
39
formatters:
29
40
enable:
30
41
- gofmt
+24
.tangled/workflows/lint.yaml
reviewed
···
1
1
+
when:
2
2
+
- event: ["push"]
3
3
+
branch: ["*"]
4
4
+
- event: ["pull_request"]
5
5
+
branch: ["main"]
6
6
+
7
7
+
engine: kubernetes
8
8
+
image: golang:1.25-trixie
9
9
+
architecture: amd64
10
10
+
11
11
+
steps:
12
12
+
- name: Download and Generate
13
13
+
environment:
14
14
+
CGO_ENABLED: 1
15
15
+
command: |
16
16
+
go mod download
17
17
+
go generate ./...
18
18
+
19
19
+
- name: Run Linter
20
20
+
environment:
21
21
+
CGO_ENABLED: 1
22
22
+
command: |
23
23
+
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.2
24
24
+
golangci-lint run ./...
+102
-26
pkg/hold/pds/xrpc.go
reviewed
···
207
207
}
208
208
209
209
w.Header().Set("Content-Type", "application/json")
210
210
-
json.NewEncoder(w).Encode(response)
210
210
+
if err := json.NewEncoder(w).Encode(response); err != nil {
211
211
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
212
212
+
w.WriteHeader(http.StatusInternalServerError)
213
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
230
-
json.NewEncoder(w).Encode(response)
233
233
+
if err := json.NewEncoder(w).Encode(response); err != nil {
234
234
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
235
235
+
w.WriteHeader(http.StatusInternalServerError)
236
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
258
-
json.NewEncoder(w).Encode(response)
264
264
+
if err := json.NewEncoder(w).Encode(response); err != nil {
265
265
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
266
266
+
w.WriteHeader(http.StatusInternalServerError)
267
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
293
-
json.NewEncoder(w).Encode(response)
302
302
+
if err := json.NewEncoder(w).Encode(response); err != nil {
303
303
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
304
304
+
w.WriteHeader(http.StatusInternalServerError)
305
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
344
-
json.NewEncoder(w).Encode(response)
356
356
+
if err := json.NewEncoder(w).Encode(response); err != nil {
357
357
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
358
358
+
w.WriteHeader(http.StatusInternalServerError)
359
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
438
-
json.NewEncoder(w).Encode(response)
453
453
+
if err := json.NewEncoder(w).Encode(response); err != nil {
454
454
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
455
455
+
w.WriteHeader(http.StatusInternalServerError)
456
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
482
-
json.NewEncoder(w).Encode(response)
500
500
+
if err := json.NewEncoder(w).Encode(response); err != nil {
501
501
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
502
502
+
w.WriteHeader(http.StatusInternalServerError)
503
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
554
-
json.NewEncoder(w).Encode(response)
575
575
+
if err := json.NewEncoder(w).Encode(response); err != nil {
576
576
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
577
577
+
w.WriteHeader(http.StatusInternalServerError)
578
578
+
}
555
579
return
556
580
}
557
581
···
598
622
}
599
623
600
624
w.Header().Set("Content-Type", "application/json")
601
601
-
json.NewEncoder(w).Encode(response)
625
625
+
if err := json.NewEncoder(w).Encode(response); err != nil {
626
626
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
627
627
+
w.WriteHeader(http.StatusInternalServerError)
628
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
623
-
json.NewEncoder(w).Encode(response)
650
650
+
if err := json.NewEncoder(w).Encode(response); err != nil {
651
651
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
652
652
+
w.WriteHeader(http.StatusInternalServerError)
653
653
+
}
624
654
return
625
655
}
626
656
···
729
759
}
730
760
731
761
w.Header().Set("Content-Type", "application/json")
732
732
-
json.NewEncoder(w).Encode(response)
762
762
+
if err := json.NewEncoder(w).Encode(response); err != nil {
763
763
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
764
764
+
w.WriteHeader(http.StatusInternalServerError)
765
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
802
-
json.NewEncoder(w).Encode(map[string]any{
835
835
+
response := map[string]any{
803
836
"error": "InvalidSwap",
804
837
"message": "record CID does not match swapRecord",
805
805
-
})
838
838
+
}
839
839
+
if err := json.NewEncoder(w).Encode(response); err != nil {
840
840
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
841
841
+
w.WriteHeader(http.StatusInternalServerError)
842
842
+
}
806
843
return
807
844
}
808
845
}
···
846
883
}
847
884
848
885
w.Header().Set("Content-Type", "application/json")
849
849
-
json.NewEncoder(w).Encode(response)
886
886
+
if err := json.NewEncoder(w).Encode(response); err != nil {
887
887
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
888
888
+
w.WriteHeader(http.StatusInternalServerError)
889
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
903
-
w.Write(buf.Bytes())
943
943
+
if _, err := w.Write(buf.Bytes()); err != nil {
944
944
+
slog.Error("failed to write car to http response", "error", err, "path", r.URL.Path)
945
945
+
w.WriteHeader(http.StatusInternalServerError)
946
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
1066
-
json.NewEncoder(w).Encode(response)
1109
1109
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1110
1110
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1111
1111
+
w.WriteHeader(http.StatusInternalServerError)
1112
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
1142
-
json.NewEncoder(w).Encode(response)
1188
1188
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1189
1189
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1190
1190
+
w.WriteHeader(http.StatusInternalServerError)
1191
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
1196
-
json.NewEncoder(w).Encode(response)
1245
1245
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1246
1246
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1247
1247
+
w.WriteHeader(http.StatusInternalServerError)
1248
1248
+
}
1197
1249
return
1198
1250
}
1199
1251
···
1205
1257
"repos": []any{},
1206
1258
}
1207
1259
w.Header().Set("Content-Type", "application/json")
1208
1208
-
json.NewEncoder(w).Encode(response)
1260
1260
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1261
1261
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1262
1262
+
w.WriteHeader(http.StatusInternalServerError)
1263
1263
+
}
1209
1264
return
1210
1265
}
1211
1266
···
1223
1278
}
1224
1279
1225
1280
w.Header().Set("Content-Type", "application/json")
1226
1226
-
json.NewEncoder(w).Encode(response)
1281
1281
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1282
1282
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1283
1283
+
w.WriteHeader(http.StatusInternalServerError)
1284
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
1255
-
json.NewEncoder(w).Encode(response)
1313
1313
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1314
1314
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1315
1315
+
w.WriteHeader(http.StatusInternalServerError)
1316
1316
+
}
1256
1317
return
1257
1318
}
1258
1319
···
1264
1325
}
1265
1326
1266
1327
w.Header().Set("Content-Type", "application/json")
1267
1267
-
json.NewEncoder(w).Encode(response)
1328
1328
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1329
1329
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1330
1330
+
w.WriteHeader(http.StatusInternalServerError)
1331
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
1279
-
json.NewEncoder(w).Encode(doc)
1343
1343
+
if err := json.NewEncoder(w).Encode(doc); err != nil {
1344
1344
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1345
1345
+
w.WriteHeader(http.StatusInternalServerError)
1346
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
1378
-
json.NewEncoder(w).Encode(response)
1445
1445
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1446
1446
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1447
1447
+
w.WriteHeader(http.StatusInternalServerError)
1448
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
1411
-
json.NewEncoder(w).Encode(response)
1481
1481
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1482
1482
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1483
1483
+
w.WriteHeader(http.StatusInternalServerError)
1484
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
1549
-
json.NewEncoder(w).Encode(stats)
1622
1622
+
if err := json.NewEncoder(w).Encode(stats); err != nil {
1623
1623
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1624
1624
+
w.WriteHeader(http.StatusInternalServerError)
1625
1625
+
}
1550
1626
}