diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 78cb96ef..23703b47 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -30,7 +30,7 @@ jobs: target: [linebot, screenshot] steps: - uses: actions/checkout@v6.0.2 - - uses: actions/cache@v4.0.2 + - uses: actions/cache@v5.0.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -65,7 +65,7 @@ jobs: target: [linebot, screenshot] steps: - uses: actions/checkout@v6.0.2 - - uses: actions/cache@v4.0.2 + - uses: actions/cache@v5.0.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -136,7 +136,7 @@ jobs: target: [linebot, screenshot] steps: - uses: actions/checkout@v6.0.2 - - uses: actions/cache@v4.0.2 + - uses: actions/cache@v5.0.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c7e7f3ea..a69acc2e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -6,7 +6,7 @@ on: golangci_lint_version: type: string required: false - default: "v1.58.1" + default: "v2.8.0" jobs: lint: @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v6.0.2 with: fetch-depth: 0 - - uses: reviewdog/action-golangci-lint@v2.6.2 + - uses: reviewdog/action-golangci-lint@v2.8.0 with: go_version_file: go.mod github_token: ${{ secrets.github_token }} @@ -54,7 +54,7 @@ jobs: --health-retries 5 steps: - uses: actions/checkout@v6.0.2 - - uses: actions/cache@v4.0.2 + - uses: actions/cache@v5.0.3 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} diff --git a/.github/workflows/test_and_build.yml b/.github/workflows/test_and_build.yml index 0df28a9b..c3f0d19e 100644 --- a/.github/workflows/test_and_build.yml +++ b/.github/workflows/test_and_build.yml @@ -21,10 +21,10 @@ jobs: matrix: target: [firestore-emulator] env: - GCLOUD_VERSION: "406.0.0" + GCLOUD_VERSION: "554.0.0" steps: - uses: actions/checkout@v6.0.2 - - uses: actions/cache@v4.0.2 + - uses: actions/cache@v5.0.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -58,7 +58,7 @@ jobs: contents: read packages: read checks: write - uses: ww24/linebot/.github/workflows/test.yaml@73705893378fa4d1f1bfa0bc76e55de0e7ad9283 + uses: ww24/linebot/.github/workflows/test.yaml@014e186748c76fde2d0a7b5401f77a47062e940f docker: needs: [test] @@ -67,7 +67,7 @@ jobs: packages: write id-token: write security-events: write - uses: ww24/linebot/.github/workflows/docker.yml@73705893378fa4d1f1bfa0bc76e55de0e7ad9283 + uses: ww24/linebot/.github/workflows/docker.yml@014e186748c76fde2d0a7b5401f77a47062e940f with: image_tag: latest push: ${{ github.event_name == 'push' }} diff --git a/.golangci.yml b/.golangci.yml index 8737484a..d2c516d6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,112 +1,30 @@ +version: "2" + run: timeout: 3m -issues: - exclude-rules: - - linters: - - exhaustivestruct - - errcheck - - err113 - - wrapcheck - - gochecknoglobals - - exhaustruct - - goconst - path: _test\.go$ - - linters: - - gochecknoglobals - source: "Set = wire.NewSet" - - linters: - - gochecknoglobals - source: "var tracer = otel.Tracer" - - linters: - - mnd - source: "time." - - linters: - - mnd - source: "strconv.Parse" - - linters: - - wrapcheck - source: "code.With\\(" - - linters: - - gocritic - text: "hugeParam:" - source: "slog.Record" - -linters-settings: - gocyclo: - min-complexity: 15 - gocritic: - enabled-checks: - - appendCombine - - boolExprSimplify - - builtinShadow - - commentedOutCode - - commentedOutImport - - docStub - - dupImport - - emptyFallthrough - - emptyStringTest - - equalFold - - hexLiteral - - hugeParam - - importShadow - - indexAlloc - - initClause - - methodExprCall - - nestingReduce - - nilValReturn - - octalLiteral - - paramTypeCombine - - ptrToRefParam - - rangeExprCopy - - rangeValCopy - - sloppyReassign - - stringXbytes - - typeAssertChain - - typeUnparen - - unnecessaryBlock - - weakCond - - yodaStyleExpr - gci: - sections: - - standard - - default - - prefix(github.com/ww24/linebot) - exhaustive: - default-signifies-exhaustive: true - exhaustruct: - include: - - "github.com/ww24/linebot/domain" - linters: - disable-all: true enable: - bodyclose - errcheck - errorlint - - exportloopref - gochecknoglobals - goconst - gocritic - gocyclo - err113 - - goimports - - gci - mnd - - gosimple - govet - ineffassign - misspell - noctx - staticcheck - - typecheck - unconvert - unparam - unused - nolintlint - wrapcheck - tparallel - - stylecheck - prealloc - exhaustive - exhaustruct @@ -116,3 +34,88 @@ linters: - gosec - nestif - nakedret + settings: + gocyclo: + min-complexity: 15 + gocritic: + enabled-checks: + - appendCombine + - boolExprSimplify + - builtinShadow + - commentedOutCode + - commentedOutImport + - docStub + - dupImport + - emptyFallthrough + - emptyStringTest + - equalFold + - hexLiteral + - hugeParam + - importShadow + - indexAlloc + - initClause + - methodExprCall + - nestingReduce + - nilValReturn + - octalLiteral + - paramTypeCombine + - ptrToRefParam + - rangeExprCopy + - rangeValCopy + - sloppyReassign + - stringXbytes + - typeAssertChain + - typeUnparen + - unnecessaryBlock + - weakCond + - yodaStyleExpr + exhaustive: + default-signifies-exhaustive: true + exhaustruct: + include: + - "github.com/ww24/linebot/domain" + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - exhaustivestruct + - errcheck + - err113 + - wrapcheck + - gochecknoglobals + - exhaustruct + - goconst + path: _test\.go$ + - linters: + - gochecknoglobals + source: "Set = wire.NewSet" + - linters: + - gochecknoglobals + source: "var tracer = otel.Tracer" + - linters: + - mnd + source: "time." + - linters: + - mnd + source: "strconv.Parse" + - linters: + - wrapcheck + source: "code.With\\(" + - linters: + - gocritic + text: "hugeParam:" + source: "slog.Record" +formatters: + enable: + - gci + settings: + gci: + sections: + - standard + - default + - prefix(github.com/ww24/linebot) diff --git a/cmd/linebot/main.go b/cmd/linebot/main.go index 720d0616..59f8a4cb 100644 --- a/cmd/linebot/main.go +++ b/cmd/linebot/main.go @@ -13,7 +13,6 @@ import ( "time" "cloud.google.com/go/profiler" - "go.uber.org/automaxprocs/maxprocs" "google.golang.org/grpc/grpclog" "github.com/ww24/linebot/internal/buildinfo" @@ -37,7 +36,7 @@ func main() { projectID, err := gcp.ProjectID() if err != nil { - log.Printf("ERROR gcp.ProjectID: %+v", err) + panic(fmt.Errorf("ERROR gcp.ProjectID: %w", err)) } if err := llog.SetOption( @@ -47,18 +46,10 @@ func main() { llog.RevisionID(buildinfo.Revision()), llog.GCPProjectID(projectID), ); err != nil { - log.Printf("ERROR log.SetOption: %+v", err) - stop() - os.Exit(1) + panic(fmt.Errorf("ERROR log.SetOption: %w", err)) } grpclog.SetLoggerV2(llog.NewGRPCLogger(slog.Default().Handler())) - // set GOMAXPROCS - infof := func(format string, args ...interface{}) { slog.Info(fmt.Sprintf(format, args...)) } - if _, err := maxprocs.Set(maxprocs.Logger(infof)); err != nil { - slog.WarnContext(ctx, "failed to set GOMAXPROCS", llog.Err(err)) - } - bot, cleanup, err := register(ctx) if err != nil { slog.Error("main: register", llog.Err(err)) diff --git a/cmd/linebot/wire.go b/cmd/linebot/wire.go index 1a933542..a545ca1c 100644 --- a/cmd/linebot/wire.go +++ b/cmd/linebot/wire.go @@ -1,5 +1,4 @@ //go:build wireinject -// +build wireinject package main diff --git a/cmd/screenshot/main.go b/cmd/screenshot/main.go index adc39536..e13cfbbe 100644 --- a/cmd/screenshot/main.go +++ b/cmd/screenshot/main.go @@ -11,7 +11,6 @@ import ( "cloud.google.com/go/profiler" "go.opentelemetry.io/otel" - "go.uber.org/automaxprocs/maxprocs" "google.golang.org/grpc/grpclog" "github.com/ww24/linebot/internal/buildinfo" @@ -31,7 +30,14 @@ func init() { } func main() { - ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) + if err := execute(context.Background()); err != nil { + log.Printf("main: %+v", err) + os.Exit(1) + } +} + +func execute(ctx context.Context) error { + ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM) defer stop() ctx, span := tr.Start(ctx, "start job") @@ -39,7 +45,7 @@ func main() { projectID, err := gcp.ProjectID() if err != nil { - log.Printf("ERROR gcp.ProjectID: %+v", err) + return fmt.Errorf("ERROR gcp.ProjectID: %w", err) } if err := llog.SetOption( @@ -49,23 +55,14 @@ func main() { llog.RevisionID(buildinfo.Revision()), llog.GCPProjectID(projectID), ); err != nil { - log.Printf("ERROR log.SetOption: %+v", err) - stop() - os.Exit(1) + return fmt.Errorf("ERROR log.SetOption: %w", err) } grpclog.SetLoggerV2(llog.NewGRPCLogger(slog.Default().Handler())) - // set GOMAXPROCS - infof := func(format string, args ...interface{}) { slog.Info(fmt.Sprintf(format, args...)) } - if _, err := maxprocs.Set(maxprocs.Logger(infof)); err != nil { - slog.WarnContext(ctx, "main: failed to set GOMAXPROCS", llog.Err(err)) - } - job, cleanup, err := register(ctx) if err != nil { - stop() slog.ErrorContext(ctx, "main: register", llog.Err(err)) - os.Exit(1) + return fmt.Errorf("ERROR register: %w", err) } defer cleanup() @@ -85,11 +82,10 @@ func main() { slog.InfoContext(ctx, "main: start job") if err := job.run(ctx); err != nil { - stop() - cleanup() slog.ErrorContext(ctx, "main: failed to exec job", llog.Err(err)) - os.Exit(1) + return fmt.Errorf("ERROR failed to exec job: %w", err) } slog.InfoContext(ctx, "main: done") + return nil } diff --git a/cmd/screenshot/wire.go b/cmd/screenshot/wire.go index 5758ce01..5a6ddf1d 100644 --- a/cmd/screenshot/wire.go +++ b/cmd/screenshot/wire.go @@ -1,5 +1,4 @@ //go:build wireinject -// +build wireinject package main diff --git a/domain/model/conversation_test.go b/domain/model/conversation_test.go index 498fa443..a5786505 100644 --- a/domain/model/conversation_test.go +++ b/domain/model/conversation_test.go @@ -39,7 +39,6 @@ func TestConversationStatus_Validate(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() err := tt.status.Validate() diff --git a/domain/model/item_test.go b/domain/model/item_test.go index a5cd39df..ef629de6 100644 --- a/domain/model/item_test.go +++ b/domain/model/item_test.go @@ -42,7 +42,6 @@ func TestItem_UniqueIndexes(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got := tt.item.UniqueIndexes() diff --git a/domain/model/reminder_test.go b/domain/model/reminder_test.go index e84583e8..497956e2 100644 --- a/domain/model/reminder_test.go +++ b/domain/model/reminder_test.go @@ -78,7 +78,6 @@ func TestReminderItems_FilterNextSchedule(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got := tt.items.FilterNextSchedule(testTime, tt.d) diff --git a/domain/model/scheduler.go b/domain/model/scheduler.go index 8c80fb0c..e374b0c3 100644 --- a/domain/model/scheduler.go +++ b/domain/model/scheduler.go @@ -111,8 +111,8 @@ func (s *DailyScheduler) UIText() string { func (s *DailyScheduler) Next(t time.Time) (time.Time, error) { loc := s.Time.Location() year, month, day := t.In(loc).Date() - hour, min, sec := s.Time.Clock() - target := time.Date(year, month, day, hour, min, sec, 0, loc) + hour, minute, sec := s.Time.Clock() + target := time.Date(year, month, day, hour, minute, sec, 0, loc) if t.Before(target) { return target, nil } diff --git a/domain/model/scheduler_test.go b/domain/model/scheduler_test.go index 01ad0710..46f21e50 100644 --- a/domain/model/scheduler_test.go +++ b/domain/model/scheduler_test.go @@ -33,7 +33,6 @@ func TestOneshotScheduler_Next(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run("", func(t *testing.T) { t.Parallel() got, err := tt.scheduler.Next(tt.now) @@ -75,7 +74,6 @@ func TestDailyScheduler_Next(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run("", func(t *testing.T) { t.Parallel() got, err := tt.scheduler.Next(tt.now) @@ -111,7 +109,6 @@ func TestParseScheduler(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run("", func(t *testing.T) { t.Parallel() got, err := ParseScheduler(tt.serialized) diff --git a/domain/service/reminder_test.go b/domain/service/reminder_test.go index 0d61071f..d63f928f 100644 --- a/domain/service/reminder_test.go +++ b/domain/service/reminder_test.go @@ -77,7 +77,6 @@ func TestReminderImpl_SyncSchedule(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() require.True(t, testtime.SetTime(t, testTime)) diff --git a/domain/service/weather_test.go b/domain/service/weather_test.go index e685a70d..9689c084 100644 --- a/domain/service/weather_test.go +++ b/domain/service/weather_test.go @@ -89,7 +89,6 @@ func TestWeatherImpl_LatestImage(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() require.True(t, testtime.SetTime(t, tt.time)) diff --git a/go.mod b/go.mod index 858544ba..ae90a503 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/ww24/linebot -go 1.22 +go 1.25 -toolchain go1.22.3 +toolchain go1.25.6 require ( cloud.google.com/go/cloudtasks v1.13.0 @@ -17,7 +17,7 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-oss/scheduler v0.1.0 github.com/google/go-jsonnet v0.20.0 - github.com/google/wire v0.6.0 + github.com/google/wire v0.7.0 github.com/ikawaha/kagome-dict/ipa v1.2.0 github.com/ikawaha/kagome/v2 v2.10.0 github.com/jba/slog v0.2.0 @@ -34,7 +34,7 @@ require ( go.uber.org/automaxprocs v1.5.3 go.uber.org/mock v0.4.0 golang.org/x/oauth2 v0.23.0 - golang.org/x/text v0.18.0 + golang.org/x/text v0.33.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 google.golang.org/api v0.196.0 google.golang.org/grpc v1.66.0 @@ -74,13 +74,13 @@ require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/tools v0.40.0 // indirect google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect diff --git a/go.sum b/go.sum index 7431366f..21eeff40 100644 --- a/go.sum +++ b/go.sum @@ -117,6 +117,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4= +github.com/google/wire v0.7.0/go.mod h1:n6YbUQD9cPKTnHXEBN2DXlOp/mVADhVErcMFb0v3J18= github.com/googleapis/enterprise-certificate-proxy v0.3.3 h1:QRje2j5GZimBzlbhGA2V2QlGNgL8G6e+wGo/+/2bWI0= github.com/googleapis/enterprise-certificate-proxy v0.3.3/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= @@ -202,6 +204,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -212,6 +216,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -227,6 +233,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -239,6 +247,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -255,6 +265,8 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -270,6 +282,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -284,6 +298,8 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58 golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= diff --git a/infra/external/linebot/flex_test.go b/infra/external/linebot/flex_test.go index f34cedec..ead6c749 100644 --- a/infra/external/linebot/flex_test.go +++ b/infra/external/linebot/flex_test.go @@ -87,7 +87,6 @@ func TestToReminderItem(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run("", func(t *testing.T) { t.Parallel() got := toReminderItem(tt.item, testTime) diff --git a/infra/external/linebot/message.go b/infra/external/linebot/message.go index 65b78a73..f2308fdf 100644 --- a/infra/external/linebot/message.go +++ b/infra/external/linebot/message.go @@ -156,16 +156,11 @@ func (r *ReminderMenu) ToMessage() linebot.SendingMessage { msg = linebot.NewTextMessage(r.text) } - switch r.replyType { - default: - msg = msg.WithQuickReplies(&linebot.QuickReplyItems{ - Items: []*linebot.QuickReplyButton{ - {Action: linebot.NewPostbackAction("追加", "Reminder#add", "", "追加", "", "")}, - }, - }) - } - - return msg + return msg.WithQuickReplies(&linebot.QuickReplyItems{ + Items: []*linebot.QuickReplyButton{ + {Action: linebot.NewPostbackAction("追加", "Reminder#add", "", "追加", "", "")}, + }, + }) } type ReminderChoices struct { diff --git a/infra/firestore/conversation_test.go b/infra/firestore/conversation_test.go index 30f2ce7e..ab783659 100644 --- a/infra/firestore/conversation_test.go +++ b/infra/firestore/conversation_test.go @@ -46,7 +46,6 @@ func TestConversation_SetStatus(t *testing.T) { } conv := NewConversation(testCli) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() err := conv.SetStatus(ctx, tt.status) @@ -101,7 +100,6 @@ func TestConversation_GetStatus(t *testing.T) { } conv := NewConversation(testCli) for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := conv.GetStatus(ctx, tt.id) diff --git a/infra/firestore/firestore_test.go b/infra/firestore/firestore_test.go index 3d4db23c..b69dad21 100644 --- a/infra/firestore/firestore_test.go +++ b/infra/firestore/firestore_test.go @@ -3,7 +3,7 @@ package firestore import ( "context" "errors" - "log" + "fmt" "testing" "time" @@ -22,7 +22,7 @@ func TestMain(m *testing.M) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() if err := setupTestCli(ctx); err != nil { - log.Fatalf("failed to setup firestore client: %v", err) + panic(fmt.Sprintf("failed to setup firestore client: %v", err)) } m.Run() diff --git a/infra/firestore/reminder_test.go b/infra/firestore/reminder_test.go index 23da32be..d59b9002 100644 --- a/infra/firestore/reminder_test.go +++ b/infra/firestore/reminder_test.go @@ -53,7 +53,6 @@ func TestReminder_Add(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() err := r.Add(ctx, tt.item) @@ -143,7 +142,6 @@ func TestReminder_List(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := r.List(ctx, tt.conversationID) @@ -202,7 +200,6 @@ func TestReminder_Get(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := r.Get(ctx, conversationID, tt.itemID) @@ -246,7 +243,6 @@ func TestReminder_Delete(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() err := r.Delete(ctx, conversationID, tt.itemID) @@ -292,7 +288,6 @@ func TestReminder_ListAll(t *testing.T) { wantErr error }{} for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() reminders, err := r.ListAll(ctx) diff --git a/infra/firestore/shopping_test.go b/infra/firestore/shopping_test.go index 17352bc2..ed9d097a 100644 --- a/infra/firestore/shopping_test.go +++ b/infra/firestore/shopping_test.go @@ -113,7 +113,6 @@ func TestShopping_Add(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -195,7 +194,6 @@ func TestShopping_Find(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -248,7 +246,6 @@ func TestShopping_BatchDelete(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -300,7 +297,6 @@ func TestShopping_DeleteAll(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() diff --git a/infra/scheduler/scheduler.go b/infra/scheduler/scheduler.go index 459ab16d..5c5a5ff6 100644 --- a/infra/scheduler/scheduler.go +++ b/infra/scheduler/scheduler.go @@ -78,7 +78,7 @@ func (s *Scheduler) Sync(ctx context.Context, conversationID model.ConversationI tasks := make([]*scheduler.Task, 0, len(items)) for _, item := range items { - task, err := s.reminderItemToTask(prefix, item, t) + task, err := s.reminderItemToTask(ctx, prefix, item, t) if err != nil { return err } @@ -95,7 +95,7 @@ func (s *Scheduler) Sync(ctx context.Context, conversationID model.ConversationI func (s *Scheduler) Create(ctx context.Context, conversationID model.ConversationID, item *model.ReminderItem, t time.Time) error { prefix := s.prefix(conversationID) sc := scheduler.New(s.cli, s.projectID, s.location, s.queue, prefix) - task, err := s.reminderItemToTask(prefix, item, t) + task, err := s.reminderItemToTask(ctx, prefix, item, t) if err != nil { return err } @@ -108,7 +108,7 @@ func (s *Scheduler) Create(ctx context.Context, conversationID model.Conversatio func (s *Scheduler) Delete(ctx context.Context, conversationID model.ConversationID, item *model.ReminderItem, t time.Time) error { prefix := s.prefix(conversationID) sc := scheduler.New(s.cli, s.projectID, s.location, s.queue, prefix) - task, err := s.reminderItemToTask(prefix, item, t) + task, err := s.reminderItemToTask(ctx, prefix, item, t) if err != nil { return err } @@ -118,7 +118,7 @@ func (s *Scheduler) Delete(ctx context.Context, conversationID model.Conversatio return nil } -func (s *Scheduler) reminderItemToTask(prefix string, item *model.ReminderItem, t time.Time) (*scheduler.Task, error) { +func (s *Scheduler) reminderItemToTask(ctx context.Context, prefix string, item *model.ReminderItem, t time.Time) (*scheduler.Task, error) { next, err := item.Scheduler.Next(t) if err != nil { return nil, xerrors.New("failed to get next schedule") @@ -127,7 +127,7 @@ func (s *Scheduler) reminderItemToTask(prefix string, item *model.ReminderItem, if err != nil { return nil, xerrors.Errorf("failed to marshal json: %w", err) } - req, err := http.NewRequest(http.MethodPost, s.endpoint.String(), bytes.NewReader(data)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.endpoint.String(), bytes.NewReader(data)) if err != nil { return nil, xerrors.Errorf("failed to create http request: %w", err) } diff --git a/internal/code/code_test.go b/internal/code/code_test.go index 77fa9a76..1f3ff904 100644 --- a/internal/code/code_test.go +++ b/internal/code/code_test.go @@ -52,7 +52,6 @@ func TestInternalError_From(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got := From(tt.err) diff --git a/log/cloud_logging.go b/log/cloud_logging.go index 7858f57b..805c015e 100644 --- a/log/cloud_logging.go +++ b/log/cloud_logging.go @@ -116,13 +116,13 @@ func severity(level slog.Level) string { case level < slog.LevelInfo: return "DEBUG" case level == slog.LevelInfo: - return "INFO" + return "INFO" //nolint: goconst case level < slog.LevelWarn: return "NOTICE" case level < slog.LevelError: return "WARNING" case level == slog.LevelError: - return "ERROR" + return "ERROR" //nolint: goconst case level > slog.LevelError: return "CRITICAL" default: diff --git a/log/log_test.go b/log/log_test.go index d014f5a4..5281a772 100644 --- a/log/log_test.go +++ b/log/log_test.go @@ -171,7 +171,6 @@ net/http.(*conn).serve(0xc0085bc6c0, {0x2a21fc479120, 0xc0014ad260}) }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got := chopStack(tt.args.s, tt.args.target) diff --git a/nl/nl.go b/nl/nl.go index ffe3e943..57094ab5 100644 --- a/nl/nl.go +++ b/nl/nl.go @@ -87,8 +87,7 @@ func (p *Parser) Parse(str string) *model.Item { } pos := token.POS() - switch pos[0] { - case posNoun: + if pos[0] == posNoun { if pos[1] == posNumeral { idx, err := p.parseNumber(token.Surface) if err != nil { diff --git a/nl/nl_test.go b/nl/nl_test.go index 0b0a32cd..bd08c2fb 100644 --- a/nl/nl_test.go +++ b/nl/nl_test.go @@ -125,7 +125,6 @@ func TestParser_Parse(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run("", func(t *testing.T) { t.Parallel() got := p.Parse(tt.src) diff --git a/presentation/http/handler_test.go b/presentation/http/handler_test.go index 7a13021f..3353e626 100644 --- a/presentation/http/handler_test.go +++ b/presentation/http/handler_test.go @@ -79,7 +79,6 @@ func TestIsCanceledByClient(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() result := newSetter(1) diff --git a/presentation/http/middleware.go b/presentation/http/middleware.go index ea8d8795..03b3fd3e 100644 --- a/presentation/http/middleware.go +++ b/presentation/http/middleware.go @@ -49,7 +49,7 @@ func accessLogHandler(publisher accesslog.Publisher, cfg *config.AccessLog) func Query: &avro.UnionNullString{String: strings.ToValidUTF8(r.URL.RawQuery, ""), UnionType: avro.UnionNullStringTypeEnumString}, Status: nil, Duration: nil, - RequestSize: &avro.UnionNullInt{Int: int32(r.ContentLength), UnionType: avro.UnionNullIntTypeEnumInt}, + RequestSize: &avro.UnionNullInt{Int: int32(r.ContentLength), UnionType: avro.UnionNullIntTypeEnumInt}, //nolint: gosec ResponseSize: nil, } @@ -69,9 +69,9 @@ func accessLogHandler(publisher accesslog.Publisher, cfg *config.AccessLog) func rw := newResponseWriter(w) next.ServeHTTP(rw, r) - accessLog.Status = &avro.UnionNullInt{Int: int32(rw.status), UnionType: avro.UnionNullIntTypeEnumInt} - accessLog.Duration = &avro.UnionNullInt{Int: int32(time.Since(start).Microseconds()), UnionType: avro.UnionNullIntTypeEnumInt} - accessLog.ResponseSize = &avro.UnionNullInt{Int: int32(rw.size), UnionType: avro.UnionNullIntTypeEnumInt} + accessLog.Status = &avro.UnionNullInt{Int: int32(rw.status), UnionType: avro.UnionNullIntTypeEnumInt} //nolint: gosec + accessLog.Duration = &avro.UnionNullInt{Int: int32(time.Since(start).Microseconds()), UnionType: avro.UnionNullIntTypeEnumInt} //nolint: gosec + accessLog.ResponseSize = &avro.UnionNullInt{Int: int32(rw.size), UnionType: avro.UnionNullIntTypeEnumInt} //nolint: gosec publisher.Publish(context.Background(), accessLog) }) diff --git a/presentation/http/middleware_test.go b/presentation/http/middleware_test.go index 7a089e30..7c7ab848 100644 --- a/presentation/http/middleware_test.go +++ b/presentation/http/middleware_test.go @@ -37,7 +37,6 @@ func TestPanicHandler(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() w := httptest.NewRecorder()