fix(lint): check ignored close and remove errors, simplify release conditions
12 files · +31 -30
M internal/adapters/blobdisk/blobdisk.go +9 -9
| @@ -183,7 +183,7 @@ func (s *Store) Put(ctx context.Context, key string, r io.Reader, size int64) (p | |||
| 183 | 183 | if e != nil { | |
| 184 | 184 | return ports.BlobInfo{}, e | |
| 185 | 185 | } | |
| 186 | - | defer os.Remove(f.Name()) | |
| 186 | + | defer func() { _ = os.Remove(f.Name()) }() | |
| 187 | 187 | h := sha256.New() | |
| 188 | 188 | n, e := io.Copy(io.MultiWriter(f, h), ctxReader{ctx, r}) | |
| 189 | 189 | if e == nil && n != size { | |
| @@ -256,7 +256,7 @@ func (s *Store) Open(ctx context.Context, key string, offset, length int64) (io. | |||
| 256 | 256 | return nil, info, translate(e) | |
| 257 | 257 | } | |
| 258 | 258 | if _, e = f.Seek(offset, io.SeekStart); e != nil { | |
| 259 | - | f.Close() | |
| 259 | + | _ = f.Close() | |
| 260 | 260 | return nil, info, e | |
| 261 | 261 | } | |
| 262 | 262 | var r io.Reader = ctxReader{ctx, f} | |
| @@ -364,15 +364,15 @@ func (s *Store) NewMultipart(ctx context.Context, key string) (ports.MultipartUp | |||
| 364 | 364 | return nil, e | |
| 365 | 365 | } | |
| 366 | 366 | if e := writeMetadata(stage, metadata{key, time.Now().UTC()}); e != nil { | |
| 367 | - | os.RemoveAll(stage) | |
| 367 | + | _ = os.RemoveAll(stage) | |
| 368 | 368 | return nil, e | |
| 369 | 369 | } | |
| 370 | 370 | if e := os.Rename(stage, u.dir()); e != nil { | |
| 371 | - | os.RemoveAll(stage) | |
| 371 | + | _ = os.RemoveAll(stage) | |
| 372 | 372 | return nil, e | |
| 373 | 373 | } | |
| 374 | 374 | if e := syncDir(filepath.Join(s.root, "multipart")); e != nil { | |
| 375 | - | os.RemoveAll(u.dir()) | |
| 375 | + | _ = os.RemoveAll(u.dir()) | |
| 376 | 376 | return nil, e | |
| 377 | 377 | } | |
| 378 | 378 | return u, nil | |
| @@ -396,7 +396,7 @@ func writeMetadata(dir string, m metadata) error { | |||
| 396 | 396 | e = os.Rename(f.Name(), filepath.Join(dir, "metadata")) | |
| 397 | 397 | } | |
| 398 | 398 | if e != nil { | |
| 399 | - | os.Remove(f.Name()) | |
| 399 | + | _ = os.Remove(f.Name()) | |
| 400 | 400 | return e | |
| 401 | 401 | } | |
| 402 | 402 | return syncDir(dir) | |
| @@ -412,7 +412,7 @@ func (u *upload) UploadPart(ctx context.Context, n int, r io.Reader, size int64) | |||
| 412 | 412 | if e != nil { | |
| 413 | 413 | return e | |
| 414 | 414 | } | |
| 415 | - | defer os.Remove(f.Name()) | |
| 415 | + | defer func() { _ = os.Remove(f.Name()) }() | |
| 416 | 416 | count, e := io.Copy(f, ctxReader{ctx, r}) | |
| 417 | 417 | if e == nil && count != size { | |
| 418 | 418 | e = domain.ErrInvalid | |
| @@ -433,7 +433,7 @@ func (u *upload) Complete(ctx context.Context) (ports.BlobInfo, error) { | |||
| 433 | 433 | return ports.BlobInfo{}, domain.ErrInvalid | |
| 434 | 434 | } | |
| 435 | 435 | u.done = true | |
| 436 | - | defer os.RemoveAll(u.dir()) | |
| 436 | + | defer func() { _ = os.RemoveAll(u.dir()) }() | |
| 437 | 437 | entries, e := os.ReadDir(u.dir()) | |
| 438 | 438 | if e != nil { | |
| 439 | 439 | return ports.BlobInfo{}, e | |
| @@ -453,7 +453,7 @@ func (u *upload) Complete(ctx context.Context) (ports.BlobInfo, error) { | |||
| 453 | 453 | var files []*os.File | |
| 454 | 454 | defer func() { | |
| 455 | 455 | for _, f := range files { | |
| 456 | - | f.Close() | |
| 456 | + | _ = f.Close() | |
| 457 | 457 | } | |
| 458 | 458 | }() | |
| 459 | 459 | for i, n := range names { | |
| @@ -183,7 +183,7 @@ func (s *Store) Put(ctx context.Context, key string, r io.Reader, size int64) (p | |||||
| 183 | if e != nil { | 183 | if e != nil { | ||
| 184 | return ports.BlobInfo{}, e | 184 | return ports.BlobInfo{}, e | ||
| 185 | } | 185 | } | ||
| 186 | - | defer os.Remove(f.Name()) | 186 | + | defer func() { _ = os.Remove(f.Name()) }() |
| 187 | h := sha256.New() | 187 | h := sha256.New() | ||
| 188 | n, e := io.Copy(io.MultiWriter(f, h), ctxReader{ctx, r}) | 188 | n, e := io.Copy(io.MultiWriter(f, h), ctxReader{ctx, r}) | ||
| 189 | if e == nil && n != size { | 189 | if e == nil && n != size { | ||
| @@ -256,7 +256,7 @@ func (s *Store) Open(ctx context.Context, key string, offset, length int64) (io. | |||||
| 256 | return nil, info, translate(e) | 256 | return nil, info, translate(e) | ||
| 257 | } | 257 | } | ||
| 258 | if _, e = f.Seek(offset, io.SeekStart); e != nil { | 258 | if _, e = f.Seek(offset, io.SeekStart); e != nil { | ||
| 259 | - | f.Close() | 259 | + | _ = f.Close() |
| 260 | return nil, info, e | 260 | return nil, info, e | ||
| 261 | } | 261 | } | ||
| 262 | var r io.Reader = ctxReader{ctx, f} | 262 | var r io.Reader = ctxReader{ctx, f} | ||
| @@ -364,15 +364,15 @@ func (s *Store) NewMultipart(ctx context.Context, key string) (ports.MultipartUp | |||||
| 364 | return nil, e | 364 | return nil, e | ||
| 365 | } | 365 | } | ||
| 366 | if e := writeMetadata(stage, metadata{key, time.Now().UTC()}); e != nil { | 366 | if e := writeMetadata(stage, metadata{key, time.Now().UTC()}); e != nil { | ||
| 367 | - | os.RemoveAll(stage) | 367 | + | _ = os.RemoveAll(stage) |
| 368 | return nil, e | 368 | return nil, e | ||
| 369 | } | 369 | } | ||
| 370 | if e := os.Rename(stage, u.dir()); e != nil { | 370 | if e := os.Rename(stage, u.dir()); e != nil { | ||
| 371 | - | os.RemoveAll(stage) | 371 | + | _ = os.RemoveAll(stage) |
| 372 | return nil, e | 372 | return nil, e | ||
| 373 | } | 373 | } | ||
| 374 | if e := syncDir(filepath.Join(s.root, "multipart")); e != nil { | 374 | if e := syncDir(filepath.Join(s.root, "multipart")); e != nil { | ||
| 375 | - | os.RemoveAll(u.dir()) | 375 | + | _ = os.RemoveAll(u.dir()) |
| 376 | return nil, e | 376 | return nil, e | ||
| 377 | } | 377 | } | ||
| 378 | return u, nil | 378 | return u, nil | ||
| @@ -396,7 +396,7 @@ func writeMetadata(dir string, m metadata) error { | |||||
| 396 | e = os.Rename(f.Name(), filepath.Join(dir, "metadata")) | 396 | e = os.Rename(f.Name(), filepath.Join(dir, "metadata")) | ||
| 397 | } | 397 | } | ||
| 398 | if e != nil { | 398 | if e != nil { | ||
| 399 | - | os.Remove(f.Name()) | 399 | + | _ = os.Remove(f.Name()) |
| 400 | return e | 400 | return e | ||
| 401 | } | 401 | } | ||
| 402 | return syncDir(dir) | 402 | return syncDir(dir) | ||
| @@ -412,7 +412,7 @@ func (u *upload) UploadPart(ctx context.Context, n int, r io.Reader, size int64) | |||||
| 412 | if e != nil { | 412 | if e != nil { | ||
| 413 | return e | 413 | return e | ||
| 414 | } | 414 | } | ||
| 415 | - | defer os.Remove(f.Name()) | 415 | + | defer func() { _ = os.Remove(f.Name()) }() |
| 416 | count, e := io.Copy(f, ctxReader{ctx, r}) | 416 | count, e := io.Copy(f, ctxReader{ctx, r}) | ||
| 417 | if e == nil && count != size { | 417 | if e == nil && count != size { | ||
| 418 | e = domain.ErrInvalid | 418 | e = domain.ErrInvalid | ||
| @@ -433,7 +433,7 @@ func (u *upload) Complete(ctx context.Context) (ports.BlobInfo, error) { | |||||
| 433 | return ports.BlobInfo{}, domain.ErrInvalid | 433 | return ports.BlobInfo{}, domain.ErrInvalid | ||
| 434 | } | 434 | } | ||
| 435 | u.done = true | 435 | u.done = true | ||
| 436 | - | defer os.RemoveAll(u.dir()) | 436 | + | defer func() { _ = os.RemoveAll(u.dir()) }() |
| 437 | entries, e := os.ReadDir(u.dir()) | 437 | entries, e := os.ReadDir(u.dir()) | ||
| 438 | if e != nil { | 438 | if e != nil { | ||
| 439 | return ports.BlobInfo{}, e | 439 | return ports.BlobInfo{}, e | ||
| @@ -453,7 +453,7 @@ func (u *upload) Complete(ctx context.Context) (ports.BlobInfo, error) { | |||||
| 453 | var files []*os.File | 453 | var files []*os.File | ||
| 454 | defer func() { | 454 | defer func() { | ||
| 455 | for _, f := range files { | 455 | for _, f := range files { | ||
| 456 | - | f.Close() | 456 | + | _ = f.Close() |
| 457 | } | 457 | } | ||
| 458 | }() | 458 | }() | ||
| 459 | for i, n := range names { | 459 | for i, n := range names { | ||
M internal/adapters/blobs3/blobs3_test.go +1 -1
| @@ -75,7 +75,7 @@ func TestCheckDeniedHeadFallsBack(t *testing.T) { | |||
| 75 | 75 | } | |
| 76 | 76 | listed = true | |
| 77 | 77 | w.Header().Set("Content-Type", "application/xml") | |
| 78 | - | w.Write([]byte(`<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>b</Name><IsTruncated>false</IsTruncated></ListBucketResult>`)) | |
| 78 | + | _, _ = w.Write([]byte(`<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>b</Name><IsTruncated>false</IsTruncated></ListBucketResult>`)) | |
| 79 | 79 | })) | |
| 80 | 80 | defer srv.Close() | |
| 81 | 81 | s, e := blobs3.New(context.Background(), blobs3.Config{Bucket: "b", Prefix: "pfx", Endpoint: srv.URL, Region: "test-region", AccessKeyID: "test", SecretAccessKey: "test-secret", ForcePathStyle: true}) | |
| @@ -75,7 +75,7 @@ func TestCheckDeniedHeadFallsBack(t *testing.T) { | |||||
| 75 | } | 75 | } | ||
| 76 | listed = true | 76 | listed = true | ||
| 77 | w.Header().Set("Content-Type", "application/xml") | 77 | w.Header().Set("Content-Type", "application/xml") | ||
| 78 | - | w.Write([]byte(`<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>b</Name><IsTruncated>false</IsTruncated></ListBucketResult>`)) | 78 | + | _, _ = w.Write([]byte(`<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>b</Name><IsTruncated>false</IsTruncated></ListBucketResult>`)) |
| 79 | })) | 79 | })) | ||
| 80 | defer srv.Close() | 80 | defer srv.Close() | ||
| 81 | s, e := blobs3.New(context.Background(), blobs3.Config{Bucket: "b", Prefix: "pfx", Endpoint: srv.URL, Region: "test-region", AccessKeyID: "test", SecretAccessKey: "test-secret", ForcePathStyle: true}) | 81 | s, e := blobs3.New(context.Background(), blobs3.Config{Bucket: "b", Prefix: "pfx", Endpoint: srv.URL, Region: "test-region", AccessKeyID: "test", SecretAccessKey: "test-secret", ForcePathStyle: true}) | ||
M internal/adapters/blobtest/suite.go +3 -3
| @@ -77,7 +77,7 @@ func Run(t *testing.T, newStore func(*testing.T) ports.BlobStore, opts ...Option | |||
| 77 | 77 | require.NoError(t, e) | |
| 78 | 78 | b, e := io.ReadAll(rc) | |
| 79 | 79 | require.NoError(t, e) | |
| 80 | - | rc.Close() | |
| 80 | + | _ = rc.Close() | |
| 81 | 81 | require.Equal(t, "new", string(b)) | |
| 82 | 82 | require.NoError(t, s.Delete(ctx, "ci/roundtrip")) | |
| 83 | 83 | require.NoError(t, s.Delete(ctx, "ci/roundtrip")) | |
| @@ -95,7 +95,7 @@ func Run(t *testing.T, newStore func(*testing.T) ports.BlobStore, opts ...Option | |||
| 95 | 95 | r, _, e := s.Open(ctx, k, 0, -1) | |
| 96 | 96 | require.NoError(t, e) | |
| 97 | 97 | b, e := io.ReadAll(r) | |
| 98 | - | r.Close() | |
| 98 | + | _ = r.Close() | |
| 99 | 99 | require.NoError(t, e) | |
| 100 | 100 | require.Equal(t, k, string(b)) | |
| 101 | 101 | } | |
| @@ -147,7 +147,7 @@ func Run(t *testing.T, newStore func(*testing.T) ports.BlobStore, opts ...Option | |||
| 147 | 147 | r, _, e := s.Open(ctx, "ci/multi", 0, -1) | |
| 148 | 148 | require.NoError(t, e) | |
| 149 | 149 | b, e := io.ReadAll(r) | |
| 150 | - | r.Close() | |
| 150 | + | _ = r.Close() | |
| 151 | 151 | require.NoError(t, e) | |
| 152 | 152 | require.Equal(t, all, b) | |
| 153 | 153 | }) | |
| @@ -77,7 +77,7 @@ func Run(t *testing.T, newStore func(*testing.T) ports.BlobStore, opts ...Option | |||||
| 77 | require.NoError(t, e) | 77 | require.NoError(t, e) | ||
| 78 | b, e := io.ReadAll(rc) | 78 | b, e := io.ReadAll(rc) | ||
| 79 | require.NoError(t, e) | 79 | require.NoError(t, e) | ||
| 80 | - | rc.Close() | 80 | + | _ = rc.Close() |
| 81 | require.Equal(t, "new", string(b)) | 81 | require.Equal(t, "new", string(b)) | ||
| 82 | require.NoError(t, s.Delete(ctx, "ci/roundtrip")) | 82 | require.NoError(t, s.Delete(ctx, "ci/roundtrip")) | ||
| 83 | require.NoError(t, s.Delete(ctx, "ci/roundtrip")) | 83 | require.NoError(t, s.Delete(ctx, "ci/roundtrip")) | ||
| @@ -95,7 +95,7 @@ func Run(t *testing.T, newStore func(*testing.T) ports.BlobStore, opts ...Option | |||||
| 95 | r, _, e := s.Open(ctx, k, 0, -1) | 95 | r, _, e := s.Open(ctx, k, 0, -1) | ||
| 96 | require.NoError(t, e) | 96 | require.NoError(t, e) | ||
| 97 | b, e := io.ReadAll(r) | 97 | b, e := io.ReadAll(r) | ||
| 98 | - | r.Close() | 98 | + | _ = r.Close() |
| 99 | require.NoError(t, e) | 99 | require.NoError(t, e) | ||
| 100 | require.Equal(t, k, string(b)) | 100 | require.Equal(t, k, string(b)) | ||
| 101 | } | 101 | } | ||
| @@ -147,7 +147,7 @@ func Run(t *testing.T, newStore func(*testing.T) ports.BlobStore, opts ...Option | |||||
| 147 | r, _, e := s.Open(ctx, "ci/multi", 0, -1) | 147 | r, _, e := s.Open(ctx, "ci/multi", 0, -1) | ||
| 148 | require.NoError(t, e) | 148 | require.NoError(t, e) | ||
| 149 | b, e := io.ReadAll(r) | 149 | b, e := io.ReadAll(r) | ||
| 150 | - | r.Close() | 150 | + | _ = r.Close() |
| 151 | require.NoError(t, e) | 151 | require.NoError(t, e) | ||
| 152 | require.Equal(t, all, b) | 152 | require.Equal(t, all, b) | ||
| 153 | }) | 153 | }) | ||
M internal/adapters/kvstore/releases_test.go +1 -1
| @@ -106,7 +106,7 @@ func TestReleaseStorage(t *testing.T) { | |||
| 106 | 106 | require.NoError(t, s.Close(ctx)) | |
| 107 | 107 | db, err := kv.Open(ctx, dir, kv.Options{}) | |
| 108 | 108 | require.NoError(t, err) | |
| 109 | - | defer db.Close(ctx) | |
| 109 | + | defer func() { _ = db.Close(ctx) }() | |
| 110 | 110 | for _, prefix := range []string{"rel/", "reltag/", "relid/", "relasset/", "relassets/", "reluse/"} { | |
| 111 | 111 | for key := range db.Snapshot(ctx).Prefix(ctx, []byte(prefix)) { | |
| 112 | 112 | t.Errorf("repository deletion left release key %q", key) | |
| @@ -106,7 +106,7 @@ func TestReleaseStorage(t *testing.T) { | |||||
| 106 | require.NoError(t, s.Close(ctx)) | 106 | require.NoError(t, s.Close(ctx)) | ||
| 107 | db, err := kv.Open(ctx, dir, kv.Options{}) | 107 | db, err := kv.Open(ctx, dir, kv.Options{}) | ||
| 108 | require.NoError(t, err) | 108 | require.NoError(t, err) | ||
| 109 | - | defer db.Close(ctx) | 109 | + | defer func() { _ = db.Close(ctx) }() |
| 110 | for _, prefix := range []string{"rel/", "reltag/", "relid/", "relasset/", "relassets/", "reluse/"} { | 110 | for _, prefix := range []string{"rel/", "reltag/", "relid/", "relasset/", "relassets/", "reluse/"} { | ||
| 111 | for key := range db.Snapshot(ctx).Prefix(ctx, []byte(prefix)) { | 111 | for key := range db.Snapshot(ctx).Prefix(ctx, []byte(prefix)) { | ||
| 112 | t.Errorf("repository deletion left release key %q", key) | 112 | t.Errorf("repository deletion left release key %q", key) | ||
M internal/adapters/kvstore/store_test.go +1 -1
| @@ -405,7 +405,7 @@ func TestSchema6TokenUpgrade(t *testing.T) { | |||
| 405 | 405 | assert.Equal(t, uint32(kvstore.SchemaVersion), readSchema(t, dir)) | |
| 406 | 406 | db, err := kv.Open(ctx, dir, kv.Options{}) | |
| 407 | 407 | require.NoError(t, err) | |
| 408 | - | defer db.Close(ctx) | |
| 408 | + | defer func() { _ = db.Close(ctx) }() | |
| 409 | 409 | for _, id := range []string{"full", "partial", "missing-review", "repo", "branch"} { | |
| 410 | 410 | item, ok := db.Get(ctx, []byte("token/"+id)) | |
| 411 | 411 | require.True(t, ok) | |
| @@ -405,7 +405,7 @@ func TestSchema6TokenUpgrade(t *testing.T) { | |||||
| 405 | assert.Equal(t, uint32(kvstore.SchemaVersion), readSchema(t, dir)) | 405 | assert.Equal(t, uint32(kvstore.SchemaVersion), readSchema(t, dir)) | ||
| 406 | db, err := kv.Open(ctx, dir, kv.Options{}) | 406 | db, err := kv.Open(ctx, dir, kv.Options{}) | ||
| 407 | require.NoError(t, err) | 407 | require.NoError(t, err) | ||
| 408 | - | defer db.Close(ctx) | 408 | + | defer func() { _ = db.Close(ctx) }() |
| 409 | for _, id := range []string{"full", "partial", "missing-review", "repo", "branch"} { | 409 | for _, id := range []string{"full", "partial", "missing-review", "repo", "branch"} { | ||
| 410 | item, ok := db.Get(ctx, []byte("token/"+id)) | 410 | item, ok := db.Get(ctx, []byte("token/"+id)) | ||
| 411 | require.True(t, ok) | 411 | require.True(t, ok) | ||
M internal/adapters/rpc/release_test.go +5 -5
| @@ -256,7 +256,7 @@ func TestReleaseRPCDownload(t *testing.T) { | |||
| 256 | 256 | }).Once() | |
| 257 | 257 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(req)) | |
| 258 | 258 | require.NoError(t, err) | |
| 259 | - | defer stream.Close() | |
| 259 | + | defer func() { _ = stream.Close() }() | |
| 260 | 260 | require.True(t, stream.Receive()) | |
| 261 | 261 | assert.True(t, proto.Equal(assetToPB(a), stream.Msg().Asset)) | |
| 262 | 262 | assert.Empty(t, stream.Msg().Chunk) | |
| @@ -285,7 +285,7 @@ func TestReleaseRPCErrors(t *testing.T) { | |||
| 285 | 285 | rel.EXPECT().DownloadAsset(mock.Anything, domain.Anonymous(), mustRepoName(t, "demo"), ports.AssetRef{ID: 9}, int64(0), int64(-1), mock.Anything).Return(tt.err).Once() | |
| 286 | 286 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | |
| 287 | 287 | if err == nil { | |
| 288 | - | defer stream.Close() | |
| 288 | + | defer func() { _ = stream.Close() }() | |
| 289 | 289 | assert.False(t, stream.Receive()) | |
| 290 | 290 | err = stream.Err() | |
| 291 | 291 | } | |
| @@ -395,7 +395,7 @@ func TestReleaseRPCDownloadFullChunk(t *testing.T) { | |||
| 395 | 395 | }).Once() | |
| 396 | 396 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | |
| 397 | 397 | require.NoError(t, err) | |
| 398 | - | defer stream.Close() | |
| 398 | + | defer func() { _ = stream.Close() }() | |
| 399 | 399 | require.True(t, stream.Receive()) | |
| 400 | 400 | require.NotNil(t, stream.Msg().Asset) | |
| 401 | 401 | require.True(t, stream.Receive()) | |
| @@ -414,7 +414,7 @@ func TestReleaseRPCRejectsInvalidMasksAndSelectors(t *testing.T) { | |||
| 414 | 414 | requireCode(t, connect.CodeInvalidArgument, err) | |
| 415 | 415 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_Latest{Latest: &pb.ReleaseAssetLatest{Name: "a"}}})) | |
| 416 | 416 | if err == nil { | |
| 417 | - | defer stream.Close() | |
| 417 | + | defer func() { _ = stream.Close() }() | |
| 418 | 418 | assert.False(t, stream.Receive()) | |
| 419 | 419 | err = stream.Err() | |
| 420 | 420 | } | |
| @@ -464,7 +464,7 @@ func TestReleaseRPCDownloadZeroByteAsset(t *testing.T) { | |||
| 464 | 464 | }).Once() | |
| 465 | 465 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | |
| 466 | 466 | require.NoError(t, err) | |
| 467 | - | defer stream.Close() | |
| 467 | + | defer func() { _ = stream.Close() }() | |
| 468 | 468 | require.True(t, stream.Receive()) | |
| 469 | 469 | assert.True(t, proto.Equal(assetToPB(a), stream.Msg().Asset)) | |
| 470 | 470 | assert.False(t, stream.Receive()) | |
| @@ -256,7 +256,7 @@ func TestReleaseRPCDownload(t *testing.T) { | |||||
| 256 | }).Once() | 256 | }).Once() | ||
| 257 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(req)) | 257 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(req)) | ||
| 258 | require.NoError(t, err) | 258 | require.NoError(t, err) | ||
| 259 | - | defer stream.Close() | 259 | + | defer func() { _ = stream.Close() }() |
| 260 | require.True(t, stream.Receive()) | 260 | require.True(t, stream.Receive()) | ||
| 261 | assert.True(t, proto.Equal(assetToPB(a), stream.Msg().Asset)) | 261 | assert.True(t, proto.Equal(assetToPB(a), stream.Msg().Asset)) | ||
| 262 | assert.Empty(t, stream.Msg().Chunk) | 262 | assert.Empty(t, stream.Msg().Chunk) | ||
| @@ -285,7 +285,7 @@ func TestReleaseRPCErrors(t *testing.T) { | |||||
| 285 | rel.EXPECT().DownloadAsset(mock.Anything, domain.Anonymous(), mustRepoName(t, "demo"), ports.AssetRef{ID: 9}, int64(0), int64(-1), mock.Anything).Return(tt.err).Once() | 285 | rel.EXPECT().DownloadAsset(mock.Anything, domain.Anonymous(), mustRepoName(t, "demo"), ports.AssetRef{ID: 9}, int64(0), int64(-1), mock.Anything).Return(tt.err).Once() | ||
| 286 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | 286 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | ||
| 287 | if err == nil { | 287 | if err == nil { | ||
| 288 | - | defer stream.Close() | 288 | + | defer func() { _ = stream.Close() }() |
| 289 | assert.False(t, stream.Receive()) | 289 | assert.False(t, stream.Receive()) | ||
| 290 | err = stream.Err() | 290 | err = stream.Err() | ||
| 291 | } | 291 | } | ||
| @@ -395,7 +395,7 @@ func TestReleaseRPCDownloadFullChunk(t *testing.T) { | |||||
| 395 | }).Once() | 395 | }).Once() | ||
| 396 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | 396 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | ||
| 397 | require.NoError(t, err) | 397 | require.NoError(t, err) | ||
| 398 | - | defer stream.Close() | 398 | + | defer func() { _ = stream.Close() }() |
| 399 | require.True(t, stream.Receive()) | 399 | require.True(t, stream.Receive()) | ||
| 400 | require.NotNil(t, stream.Msg().Asset) | 400 | require.NotNil(t, stream.Msg().Asset) | ||
| 401 | require.True(t, stream.Receive()) | 401 | require.True(t, stream.Receive()) | ||
| @@ -414,7 +414,7 @@ func TestReleaseRPCRejectsInvalidMasksAndSelectors(t *testing.T) { | |||||
| 414 | requireCode(t, connect.CodeInvalidArgument, err) | 414 | requireCode(t, connect.CodeInvalidArgument, err) | ||
| 415 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_Latest{Latest: &pb.ReleaseAssetLatest{Name: "a"}}})) | 415 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_Latest{Latest: &pb.ReleaseAssetLatest{Name: "a"}}})) | ||
| 416 | if err == nil { | 416 | if err == nil { | ||
| 417 | - | defer stream.Close() | 417 | + | defer func() { _ = stream.Close() }() |
| 418 | assert.False(t, stream.Receive()) | 418 | assert.False(t, stream.Receive()) | ||
| 419 | err = stream.Err() | 419 | err = stream.Err() | ||
| 420 | } | 420 | } | ||
| @@ -464,7 +464,7 @@ func TestReleaseRPCDownloadZeroByteAsset(t *testing.T) { | |||||
| 464 | }).Once() | 464 | }).Once() | ||
| 465 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | 465 | stream, err := c.DownloadReleaseAsset(context.Background(), connect.NewRequest(&pb.DownloadReleaseAssetRequest{Repo: "demo", Selector: &pb.DownloadReleaseAssetRequest_AssetId{AssetId: 9}})) | ||
| 466 | require.NoError(t, err) | 466 | require.NoError(t, err) | ||
| 467 | - | defer stream.Close() | 467 | + | defer func() { _ = stream.Close() }() |
| 468 | require.True(t, stream.Receive()) | 468 | require.True(t, stream.Receive()) | ||
| 469 | assert.True(t, proto.Equal(assetToPB(a), stream.Msg().Asset)) | 469 | assert.True(t, proto.Equal(assetToPB(a), stream.Msg().Asset)) | ||
| 470 | assert.False(t, stream.Receive()) | 470 | assert.False(t, stream.Receive()) | ||
M internal/app/cli_release.go +1 -1
| @@ -589,7 +589,7 @@ func downloadReleaseAsset(ctx context.Context, c *client.Client, repo string, a | |||
| 589 | 589 | return ctx.Err() | |
| 590 | 590 | } | |
| 591 | 591 | code := connect.CodeOf(err) | |
| 592 | - | if attempt == 1 || !(code == connect.CodeUnavailable || code == connect.CodeInternal || errors.Is(err, io.ErrUnexpectedEOF)) { | |
| 592 | + | if attempt == 1 || (code != connect.CodeUnavailable && code != connect.CodeInternal && !errors.Is(err, io.ErrUnexpectedEOF)) { | |
| 593 | 593 | return c.Describe(err) | |
| 594 | 594 | } | |
| 595 | 595 | } | |
| @@ -589,7 +589,7 @@ func downloadReleaseAsset(ctx context.Context, c *client.Client, repo string, a | |||||
| 589 | return ctx.Err() | 589 | return ctx.Err() | ||
| 590 | } | 590 | } | ||
| 591 | code := connect.CodeOf(err) | 591 | code := connect.CodeOf(err) | ||
| 592 | - | if attempt == 1 || !(code == connect.CodeUnavailable || code == connect.CodeInternal || errors.Is(err, io.ErrUnexpectedEOF)) { | 592 | + | if attempt == 1 || (code != connect.CodeUnavailable && code != connect.CodeInternal && !errors.Is(err, io.ErrUnexpectedEOF)) { |
| 593 | return c.Describe(err) | 593 | return c.Describe(err) | ||
| 594 | } | 594 | } | ||
| 595 | } | 595 | } | ||
M internal/app/release_e2e_test.go +2 -2
| @@ -76,7 +76,7 @@ func TestReleaseBlobForge(t *testing.T) { | |||
| 76 | 76 | require.NoError(t, err) | |
| 77 | 77 | body, err := io.ReadAll(res.Body) | |
| 78 | 78 | require.NoError(t, err) | |
| 79 | - | res.Body.Close() | |
| 79 | + | _ = res.Body.Close() | |
| 80 | 80 | assert.Equal(t, 206, res.StatusCode) | |
| 81 | 81 | assert.Equal(t, "ayl", string(body)) | |
| 82 | 82 | assert.Empty(t, res.Header.Get("Location")) | |
| @@ -84,7 +84,7 @@ func TestReleaseBlobForge(t *testing.T) { | |||
| 84 | 84 | require.NoError(t, err) | |
| 85 | 85 | var obj map[string]any | |
| 86 | 86 | require.NoError(t, json.NewDecoder(res.Body).Decode(&obj)) | |
| 87 | - | res.Body.Close() | |
| 87 | + | _ = res.Body.Close() | |
| 88 | 88 | assert.Equal(t, 200, res.StatusCode) | |
| 89 | 89 | assert.Contains(t, obj["upload_url"], "http://example.test/-/github/api/uploads/") | |
| 90 | 90 | // New artifacts use the same production backend, not a test-local blob store. | |
| @@ -76,7 +76,7 @@ func TestReleaseBlobForge(t *testing.T) { | |||||
| 76 | require.NoError(t, err) | 76 | require.NoError(t, err) | ||
| 77 | body, err := io.ReadAll(res.Body) | 77 | body, err := io.ReadAll(res.Body) | ||
| 78 | require.NoError(t, err) | 78 | require.NoError(t, err) | ||
| 79 | - | res.Body.Close() | 79 | + | _ = res.Body.Close() |
| 80 | assert.Equal(t, 206, res.StatusCode) | 80 | assert.Equal(t, 206, res.StatusCode) | ||
| 81 | assert.Equal(t, "ayl", string(body)) | 81 | assert.Equal(t, "ayl", string(body)) | ||
| 82 | assert.Empty(t, res.Header.Get("Location")) | 82 | assert.Empty(t, res.Header.Get("Location")) | ||
| @@ -84,7 +84,7 @@ func TestReleaseBlobForge(t *testing.T) { | |||||
| 84 | require.NoError(t, err) | 84 | require.NoError(t, err) | ||
| 85 | var obj map[string]any | 85 | var obj map[string]any | ||
| 86 | require.NoError(t, json.NewDecoder(res.Body).Decode(&obj)) | 86 | require.NoError(t, json.NewDecoder(res.Body).Decode(&obj)) | ||
| 87 | - | res.Body.Close() | 87 | + | _ = res.Body.Close() |
| 88 | assert.Equal(t, 200, res.StatusCode) | 88 | assert.Equal(t, 200, res.StatusCode) | ||
| 89 | assert.Contains(t, obj["upload_url"], "http://example.test/-/github/api/uploads/") | 89 | assert.Contains(t, obj["upload_url"], "http://example.test/-/github/api/uploads/") | ||
| 90 | // New artifacts use the same production backend, not a test-local blob store. | 90 | // New artifacts use the same production backend, not a test-local blob store. | ||
M internal/app/web_release_test.go +1 -1
| @@ -44,7 +44,7 @@ func TestWebRelease(t *testing.T) { | |||
| 44 | 44 | } | |
| 45 | 45 | res, err := ts.Client().Do(req) | |
| 46 | 46 | require.NoError(t, err) | |
| 47 | - | defer res.Body.Close() | |
| 47 | + | defer func() { _ = res.Body.Close() }() | |
| 48 | 48 | body, err := io.ReadAll(res.Body) | |
| 49 | 49 | require.NoError(t, err) | |
| 50 | 50 | return res.StatusCode, res.Header, string(body) | |
| @@ -44,7 +44,7 @@ func TestWebRelease(t *testing.T) { | |||||
| 44 | } | 44 | } | ||
| 45 | res, err := ts.Client().Do(req) | 45 | res, err := ts.Client().Do(req) | ||
| 46 | require.NoError(t, err) | 46 | require.NoError(t, err) | ||
| 47 | - | defer res.Body.Close() | 47 | + | defer func() { _ = res.Body.Close() }() |
| 48 | body, err := io.ReadAll(res.Body) | 48 | body, err := io.ReadAll(res.Body) | ||
| 49 | require.NoError(t, err) | 49 | require.NoError(t, err) | ||
| 50 | return res.StatusCode, res.Header, string(body) | 50 | return res.StatusCode, res.Header, string(body) | ||
M internal/usecase/releases_assets.go +3 -3
| @@ -66,7 +66,7 @@ func (r *Releases) UploadAsset(ctx context.Context, p domain.Principal, name dom | |||
| 66 | 66 | if old.Name != a.Name { | |
| 67 | 67 | continue | |
| 68 | 68 | } | |
| 69 | - | if !(old.State == domain.ReleaseAssetUploading && r.clock.Now().Sub(old.UpdatedAt) > 60*time.Second) && !(old.State == domain.ReleaseAssetUploaded && params.Replace) { | |
| 69 | + | if (old.State != domain.ReleaseAssetUploading || r.clock.Now().Sub(old.UpdatedAt) <= 60*time.Second) && (old.State != domain.ReleaseAssetUploaded || !params.Replace) { | |
| 70 | 70 | return fmt.Errorf("%w: an asset named %q already exists", domain.ErrAlreadyExists, a.Name) | |
| 71 | 71 | } | |
| 72 | 72 | replaced = append(replaced, old) | |
| @@ -199,7 +199,7 @@ func validReleaseDigest(s string) bool { | |||
| 199 | 199 | return false | |
| 200 | 200 | } | |
| 201 | 201 | for _, c := range s[7:] { | |
| 202 | - | if !(c >= '0' && c <= '9' || c >= 'a' && c <= 'f') { | |
| 202 | + | if (c < '0' || c > '9') && (c < 'a' || c > 'f') { | |
| 203 | 203 | return false | |
| 204 | 204 | } | |
| 205 | 205 | } | |
| @@ -407,7 +407,7 @@ func (r *Releases) DownloadAsset(ctx context.Context, p domain.Principal, repo d | |||
| 407 | 407 | } | |
| 408 | 408 | return err | |
| 409 | 409 | } | |
| 410 | - | defer body.Close() | |
| 410 | + | defer func() { _ = body.Close() }() | |
| 411 | 411 | if err = send(ports.AssetChunk{Asset: &a}); err != nil { | |
| 412 | 412 | return err | |
| 413 | 413 | } | |
| @@ -66,7 +66,7 @@ func (r *Releases) UploadAsset(ctx context.Context, p domain.Principal, name dom | |||||
| 66 | if old.Name != a.Name { | 66 | if old.Name != a.Name { | ||
| 67 | continue | 67 | continue | ||
| 68 | } | 68 | } | ||
| 69 | - | if !(old.State == domain.ReleaseAssetUploading && r.clock.Now().Sub(old.UpdatedAt) > 60*time.Second) && !(old.State == domain.ReleaseAssetUploaded && params.Replace) { | 69 | + | if (old.State != domain.ReleaseAssetUploading || r.clock.Now().Sub(old.UpdatedAt) <= 60*time.Second) && (old.State != domain.ReleaseAssetUploaded || !params.Replace) { |
| 70 | return fmt.Errorf("%w: an asset named %q already exists", domain.ErrAlreadyExists, a.Name) | 70 | return fmt.Errorf("%w: an asset named %q already exists", domain.ErrAlreadyExists, a.Name) | ||
| 71 | } | 71 | } | ||
| 72 | replaced = append(replaced, old) | 72 | replaced = append(replaced, old) | ||
| @@ -199,7 +199,7 @@ func validReleaseDigest(s string) bool { | |||||
| 199 | return false | 199 | return false | ||
| 200 | } | 200 | } | ||
| 201 | for _, c := range s[7:] { | 201 | for _, c := range s[7:] { | ||
| 202 | - | if !(c >= '0' && c <= '9' || c >= 'a' && c <= 'f') { | 202 | + | if (c < '0' || c > '9') && (c < 'a' || c > 'f') { |
| 203 | return false | 203 | return false | ||
| 204 | } | 204 | } | ||
| 205 | } | 205 | } | ||
| @@ -407,7 +407,7 @@ func (r *Releases) DownloadAsset(ctx context.Context, p domain.Principal, repo d | |||||
| 407 | } | 407 | } | ||
| 408 | return err | 408 | return err | ||
| 409 | } | 409 | } | ||
| 410 | - | defer body.Close() | 410 | + | defer func() { _ = body.Close() }() |
| 411 | if err = send(ports.AssetChunk{Asset: &a}); err != nil { | 411 | if err = send(ports.AssetChunk{Asset: &a}); err != nil { | ||
| 412 | return err | 412 | return err | ||
| 413 | } | 413 | } | ||
M internal/usecase/releases_github_test.go +1 -1
| @@ -307,7 +307,7 @@ func TestGitHubReleaseHTTPWorkflow(t *testing.T) { | |||
| 307 | 307 | } | |
| 308 | 308 | resp, err := srv.Client().Do(req) | |
| 309 | 309 | require.NoError(t, err) | |
| 310 | - | defer resp.Body.Close() | |
| 310 | + | defer func() { _ = resp.Body.Close() }() | |
| 311 | 311 | b, err := io.ReadAll(resp.Body) | |
| 312 | 312 | require.NoError(t, err) | |
| 313 | 313 | return resp, string(b) | |
| @@ -307,7 +307,7 @@ func TestGitHubReleaseHTTPWorkflow(t *testing.T) { | |||||
| 307 | } | 307 | } | ||
| 308 | resp, err := srv.Client().Do(req) | 308 | resp, err := srv.Client().Do(req) | ||
| 309 | require.NoError(t, err) | 309 | require.NoError(t, err) | ||
| 310 | - | defer resp.Body.Close() | 310 | + | defer func() { _ = resp.Body.Close() }() |
| 311 | b, err := io.ReadAll(resp.Body) | 311 | b, err := io.ReadAll(resp.Body) | ||
| 312 | require.NoError(t, err) | 312 | require.NoError(t, err) | ||
| 313 | return resp, string(b) | 313 | return resp, string(b) | ||
M internal/usecase/releases_sweep.go +3 -2
| @@ -29,9 +29,10 @@ func (r *Releases) Sweep(ctx context.Context) { | |||
| 29 | 29 | for _, a := range all { | |
| 30 | 30 | seen[a.ID] = true | |
| 31 | 31 | remove := false | |
| 32 | - | if a.State == domain.ReleaseAssetUploading { | |
| 32 | + | switch a.State { | |
| 33 | + | case domain.ReleaseAssetUploading: | |
| 33 | 34 | remove = now.Sub(a.UpdatedAt) > domain.ReleaseAssetPendingMax | |
| 34 | - | } else if a.State == domain.ReleaseAssetUploaded { | |
| 35 | + | case domain.ReleaseAssetUploaded: | |
| 35 | 36 | _, err := r.blobs.Stat(ctx, a.BlobKey()) | |
| 36 | 37 | switch { | |
| 37 | 38 | case errors.Is(err, domain.ErrNotFound): | |
| @@ -29,9 +29,10 @@ func (r *Releases) Sweep(ctx context.Context) { | |||||
| 29 | for _, a := range all { | 29 | for _, a := range all { | ||
| 30 | seen[a.ID] = true | 30 | seen[a.ID] = true | ||
| 31 | remove := false | 31 | remove := false | ||
| 32 | - | if a.State == domain.ReleaseAssetUploading { | 32 | + | switch a.State { |
| 33 | + | case domain.ReleaseAssetUploading: | |||
| 33 | remove = now.Sub(a.UpdatedAt) > domain.ReleaseAssetPendingMax | 34 | remove = now.Sub(a.UpdatedAt) > domain.ReleaseAssetPendingMax | ||
| 34 | - | } else if a.State == domain.ReleaseAssetUploaded { | 35 | + | case domain.ReleaseAssetUploaded: |
| 35 | _, err := r.blobs.Stat(ctx, a.BlobKey()) | 36 | _, err := r.blobs.Stat(ctx, a.BlobKey()) | ||
| 36 | switch { | 37 | switch { | ||
| 37 | case errors.Is(err, domain.ErrNotFound): | 38 | case errors.Is(err, domain.ErrNotFound): | ||