From 57fc483dd9dfd9b4af14caf749b6ee92feb43b21 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 6 Oct 2023 00:53:40 +0900 Subject: [PATCH 1/4] refactor SuggestCmdUsecase --- cmd/config.go | 2 +- cmd/suggest.go | 16 ++--- go.mod | 8 +-- go.sum | 18 +++-- internal/entity/config.go | 24 +++++-- internal/gateway/ai_source_grpc.go | 65 ------------------- internal/gateway/ai_source_interface.go | 5 -- internal/gateway/grpc.go | 46 +++++++++++++ internal/gateway/input_output.go | 20 ++++++ .../{ai_source_openai.go => open_ai.go} | 0 internal/service/file_diff_service.go | 17 ----- internal/service/message.go | 41 ------------ internal/service/message_test.go | 46 ------------- internal/service/service.go | 13 ++++ internal/service/suggest_cmd.go | 53 --------------- internal/usecase/suggest_cmd.go | 47 ++++++++++++++ 16 files changed, 169 insertions(+), 252 deletions(-) delete mode 100644 internal/gateway/ai_source_grpc.go delete mode 100644 internal/gateway/ai_source_interface.go create mode 100644 internal/gateway/grpc.go create mode 100644 internal/gateway/input_output.go rename internal/gateway/{ai_source_openai.go => open_ai.go} (100%) delete mode 100644 internal/service/file_diff_service.go delete mode 100644 internal/service/message.go delete mode 100644 internal/service/message_test.go create mode 100644 internal/service/service.go delete mode 100644 internal/service/suggest_cmd.go create mode 100644 internal/usecase/suggest_cmd.go diff --git a/cmd/config.go b/cmd/config.go index e4c03f0..fb8b593 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -18,7 +18,7 @@ var ( {}, {int(entity.EN), int(entity.JP)}, {int(entity.NormalFormat), int(entity.EmojiFormat), int(entity.PrefixFormat)}, - {int(entity.WrapServer), int(entity.OpenAiAPI)}, + {int(entity.Server), int(entity.Local)}, } configOptionLabel = [][]string{ {}, diff --git a/cmd/suggest.go b/cmd/suggest.go index 13d6e16..5662539 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -2,6 +2,8 @@ package cmd import ( "fmt" + "github.com/cocoide/commitify/internal/gateway" + "github.com/cocoide/commitify/internal/usecase" "log" "os" "strings" @@ -12,8 +14,6 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/fatih/color" "github.com/spf13/cobra" - - "github.com/cocoide/commitify/internal/service" ) var ( @@ -29,7 +29,7 @@ type suggestModel struct { isEditing bool spinner spinner.Model textInput textinput.Model - scs *service.SuggestCmdService + scs *usecase.SuggestCmdUsecase } func (sm *suggestModel) Init() tea.Cmd { @@ -120,11 +120,9 @@ func NewSuggestModel() *suggestModel { ti.Focus() // suggestコマンドのサービスの取得 - scs, err := service.NewSuggestCmdService() - if err != nil { - log.Fatal(err) - os.Exit(-1) - } + inputOutput := gateway.NewInputOutputGateway() + grpcServer := gateway.NewGrpcServerGateway() + suggestCmdUsecase := usecase.NewSuggestCmdUsecase(grpcServer, inputOutput) return &suggestModel{ choices: []string{""}, @@ -133,7 +131,7 @@ func NewSuggestModel() *suggestModel { isLoading: true, isEditing: false, textInput: ti, - scs: scs, + scs: suggestCmdUsecase, } } diff --git a/go.mod b/go.mod index 154614d..c700d69 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,13 @@ require ( github.com/charmbracelet/bubbles v0.16.1 github.com/charmbracelet/bubbletea v0.24.2 github.com/charmbracelet/lipgloss v0.7.1 + github.com/cocoide/commitify-grpc-server v0.0.0-20230925123729-e460fb67f971 github.com/fatih/color v1.15.0 - github.com/golang/mock v1.4.4 - github.com/sashabaranov/go-openai v1.15.1 + github.com/golang/mock v1.6.0 + github.com/sashabaranov/go-openai v1.15.2 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 + golang.org/x/net v0.15.0 google.golang.org/grpc v1.58.0 google.golang.org/protobuf v1.31.0 ) @@ -35,7 +37,6 @@ require ( require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/lipgloss v0.7.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -47,7 +48,6 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.12.0 // indirect golang.org/x/term v0.12.0 // indirect diff --git a/go.sum b/go.sum index 900e963..62f959e 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cocoide/commitify-grpc-server v0.0.0-20230925123729-e460fb67f971 h1:u0ooNLw6PuHWUDLoVx5NiNt9858HvXqvvPNOpL+tpZw= +github.com/cocoide/commitify-grpc-server v0.0.0-20230925123729-e460fb67f971/go.mod h1:iDkIWp+CfRdHHSm4Nix6uS9dVzEgDsYPeCn+yklpCJc= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -86,8 +88,9 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -190,8 +193,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sashabaranov/go-openai v1.15.1 h1:BAV5LCVEzvZ3rN/Lh5NRVs2z6AahPt/jn5s2/cEEG0M= -github.com/sashabaranov/go-openai v1.15.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= +github.com/sashabaranov/go-openai v1.15.2 h1:0PW+ttxe+UNYKDkA1KTly7K6YhFBqnVBbblQ3t8AfY4= +github.com/sashabaranov/go-openai v1.15.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= @@ -213,14 +216,15 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -267,6 +271,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -298,6 +303,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= @@ -320,6 +326,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -354,8 +361,10 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -426,6 +435,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/entity/config.go b/internal/entity/config.go index 519e183..ca1f443 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -3,10 +3,9 @@ package entity import ( "encoding/json" "fmt" - "os" - - pb "github.com/cocoide/commitify/pkg/grpc" + "github.com/cocoide/commitify-grpc-server/pkg/pb" "github.com/spf13/viper" + "os" ) // コミットメッセージの言語の列挙型 @@ -26,12 +25,12 @@ const ( PrefixFormat ) -// AIのソースの列挙型 -type AISource int +// ChatGPTのAPIを叩く場所 +type GptRequestLocation int const ( - WrapServer AISource = iota - OpenAiAPI + Server GptRequestLocation = iota + Local ) type Config struct { @@ -133,3 +132,14 @@ func SaveConfig(configIndex, updateConfigParamInt int, updateConfigParamStr stri return nil } + +func (c *Config) WithGptRequestLocation() GptRequestLocation { + switch c.AISource { + case 0: + return Server + case 1: + return Local + default: + return Server + } +} diff --git a/internal/gateway/ai_source_grpc.go b/internal/gateway/ai_source_grpc.go deleted file mode 100644 index 612c542..0000000 --- a/internal/gateway/ai_source_grpc.go +++ /dev/null @@ -1,65 +0,0 @@ -package gateway - -import ( - "context" - "crypto/tls" - "fmt" - "log" - "os" - - "github.com/cocoide/commitify/internal/entity" - pb "github.com/cocoide/commitify/pkg/grpc" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -const ( - // serveAddress = "localhost:54322" - serveAddress = "commitify.fly.dev:443" -) - -type grpcServeGateway struct { - client pb.CommitMessageServiceClient -} - -func NewGrpcServeGateway() *grpcServeGateway { - gsg := new(grpcServeGateway) - - conn, err := grpc.Dial( - serveAddress, - grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), - ) - if err != nil { - log.Printf("Connection failed: %v", err) - os.Exit(-1) - return nil - } - - gsg.client = pb.NewCommitMessageServiceClient(conn) - - return gsg -} - -func (gsg grpcServeGateway) FetchCommitMessages(fileDiffStr string) ([]string, error) { - // 設定情報を取得 - conf, err := entity.ReadConfig() - if err != nil { - fmt.Printf("設定ファイルが開けません: %v", err) - } - cft, lt := conf.Config2PbVars() - - req := &pb.CommitMessageRequest{ - InputCode: fileDiffStr, - CodeFormat: cft, - Language: lt, - } - - res, err := gsg.client.GenerateCommitMessage(context.Background(), req) - if err != nil { - log.Fatal("gRPCの送信に失敗: ", err) - return nil, err - } - - return res.GetMessages(), nil - -} diff --git a/internal/gateway/ai_source_interface.go b/internal/gateway/ai_source_interface.go deleted file mode 100644 index 3dcd9a4..0000000 --- a/internal/gateway/ai_source_interface.go +++ /dev/null @@ -1,5 +0,0 @@ -package gateway - -type AISourceGatewayInterface interface { - FetchCommitMessages(fileDiffStr string) ([]string, error) -} diff --git a/internal/gateway/grpc.go b/internal/gateway/grpc.go new file mode 100644 index 0000000..d0391b1 --- /dev/null +++ b/internal/gateway/grpc.go @@ -0,0 +1,46 @@ +package gateway + +import ( + "crypto/tls" + "github.com/cocoide/commitify-grpc-server/pkg/pb" + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/service" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "log" +) + +const ( + serverAddress = "commitify.fly.dev:443" +) + +type grpcServerGateway struct { + client pb.CommitMessageServiceClient +} + +func NewGrpcServerGateway() service.CommitMessageService { + conn, err := grpc.Dial( + serverAddress, + grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), + ) + if err != nil { + log.Fatalf("Failed to setup grpc connection: %v", err) + } + client := pb.NewCommitMessageServiceClient(conn) + return &grpcServerGateway{client: client} +} + +func (g *grpcServerGateway) GenerateCommitMessageList(code string, conf entity.Config) ([]string, error) { + formatType, languageType := conf.Config2PbVars() + req := &pb.CommitMessageRequest{ + CodeFormat: formatType, + Language: languageType, + InputCode: code, + } + res, err := g.client.GenerateCommitMessage(context.Background(), req) + if err != nil { + return nil, err + } + return res.Messages, nil +} diff --git a/internal/gateway/input_output.go b/internal/gateway/input_output.go new file mode 100644 index 0000000..25bfbb7 --- /dev/null +++ b/internal/gateway/input_output.go @@ -0,0 +1,20 @@ +package gateway + +import ( + "github.com/cocoide/commitify/internal/service" + "os/exec" +) + +type inputOutputGateway struct { +} + +func NewInputOutputGateway() service.GithubService { + return &inputOutputGateway{} +} + +func (g *inputOutputGateway) GetStaginCodeDiff() (string, error) { + // Gitが入ってるかどうかのチェックも入れる + // 入っていないなら専用のエラーメッセージを生成 + diff, err := exec.Command("git", "diff", "--staged").Output() + return string(diff), err +} diff --git a/internal/gateway/ai_source_openai.go b/internal/gateway/open_ai.go similarity index 100% rename from internal/gateway/ai_source_openai.go rename to internal/gateway/open_ai.go diff --git a/internal/service/file_diff_service.go b/internal/service/file_diff_service.go deleted file mode 100644 index e9e2405..0000000 --- a/internal/service/file_diff_service.go +++ /dev/null @@ -1,17 +0,0 @@ -package service - -import "os/exec" - -type fileDiffService struct { -} - -func NewFileDiffService() fileDiffService { - fds := fileDiffService{} - return fds -} - -func (fds *fileDiffService) createFileDiffStr() (string, error) { - diff, err := exec.Command("git", "diff", "--staged").Output() - - return string(diff), err -} diff --git a/internal/service/message.go b/internal/service/message.go deleted file mode 100644 index c84bb83..0000000 --- a/internal/service/message.go +++ /dev/null @@ -1,41 +0,0 @@ -package service - -// import ( -// "fmt" -// "strings" - -// "github.com/cocoide/commitify/internal/gateway" -// ) - -// const ( -// CommitMessagePrompt = "Generate up to 5 commit messages for [%s]. Each message should be separated by only space" -// FormatNotice = ", format commit as:\n- feat: [feature description]\n- bugfix: [bugfix description]" -// ) - -// var PromptVariability float32 = 0.01 - -// // メッセージの生成、加工に関するクラス -// type MessageService interface { -// GenerateCommitMessage(stagingCode string) ([]string, error) -// } - -// type messageService struct { -// og gateway.OpenAIGateway -// } - -// func NewMessageService(og gateway.OpenAIGateway) MessageService { -// return &messageService{og: og} -// } - -// func (s *messageService) GenerateCommitMessage(stagingCode string) ([]string, error) { -// if len(stagingCode) < 1 { -// return nil, fmt.Errorf("There is no staging code") -// } -// prompt := fmt.Sprintf(CommitMessagePrompt, stagingCode) -// result, err := s.og.GetAnswerFromPrompt(prompt, PromptVariability) -// if err != nil { -// return nil, err -// } -// messages := strings.Split(result, "\n") -// return messages, nil -// } diff --git a/internal/service/message_test.go b/internal/service/message_test.go deleted file mode 100644 index bd6a82c..0000000 --- a/internal/service/message_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package service_test - -// import ( -// "fmt" -// "reflect" -// "testing" - -// "github.com/cocoide/commitify/internal/service" -// mock_gateway "github.com/cocoide/commitify/mock" -// "github.com/golang/mock/gomock" -// ) - -// func Test_GenerateCommitMessage(t *testing.T) { -// stagingCode := "test" -// type test struct { -// ErrorCaseName string -// ChatGptResult string -// ModifiedResult []string -// } -// tests := []test{ -// {"先頭にインデックスを含む", "1. test\n2. test", []string{"test", "test"}}, -// {"先頭にハイフンを含む", "- test\n- test", []string{"test", "test"}}, -// {"先頭にスペースを含む", " test\n test", []string{"test", "test"}}, -// {"改行ができていない", "Add A function. Update B", []string{"Add A function", "Update B"}}, -// // たまに, 改行せずピリオド『.』で文章を区切るパターンがある -// } -// ctrl := gomock.NewController(t) -// og := mock_gateway.NewMockOpenAIGateway(ctrl) -// ms := service.NewMessageService(og) - -// for _, test := range tests { -// prompt := fmt.Sprintf(service.CommitMessagePrompt, stagingCode) -// og.EXPECT(). -// GetAnswerFromPrompt(prompt, service.PromptVariability). -// Return(test.ChatGptResult, nil) - -// serviceResult, err := ms.GenerateCommitMessage(stagingCode) -// if err != nil { -// t.Error(err.Error()) -// } -// if !reflect.DeepEqual(test.ModifiedResult, serviceResult) { -// fmt.Printf("FAIL: %s\n", test.ErrorCaseName) -// t.Errorf("Exp: %v, Got: %v", test.ModifiedResult, serviceResult) -// } -// } -// } diff --git a/internal/service/service.go b/internal/service/service.go new file mode 100644 index 0000000..19fbb50 --- /dev/null +++ b/internal/service/service.go @@ -0,0 +1,13 @@ +package service + +import "github.com/cocoide/commitify/internal/entity" + +// 分割コミットの生成のクライアント側もここに入れていく +type CommitMessageService interface { + GenerateCommitMessageList(code string, config entity.Config) ([]string, error) +} + +// githubに関するデータのinput/output +type GithubService interface { + GetStaginCodeDiff() (string, error) +} diff --git a/internal/service/suggest_cmd.go b/internal/service/suggest_cmd.go deleted file mode 100644 index 389f4c3..0000000 --- a/internal/service/suggest_cmd.go +++ /dev/null @@ -1,53 +0,0 @@ -package service - -import ( - "log" - "os/exec" - - "github.com/cocoide/commitify/internal/entity" - "github.com/cocoide/commitify/internal/gateway" -) - -type SuggestCmdService struct { - ais gateway.AISourceGatewayInterface - fds fileDiffService -} - -func NewSuggestCmdService() (*SuggestCmdService, error) { - conf, err := entity.ReadConfig() - if err != nil { - return nil, err - } - - var aigi gateway.AISourceGatewayInterface - switch conf.AISource { - case int(entity.WrapServer): - aigi = gateway.NewGrpcServeGateway() - case int(entity.OpenAiAPI): - log.Fatal("現在、非対応の機能です。") - return nil, err - default: - aigi = gateway.NewGrpcServeGateway() - } - - fds := NewFileDiffService() - - return &SuggestCmdService{ais: aigi, fds: fds}, nil -} - -func (scs *SuggestCmdService) GenerateCommitMessages() ([]string, error) { - fileDiffStr, err := scs.fds.createFileDiffStr() - if err != nil { - return nil, err - } - - return scs.ais.FetchCommitMessages(fileDiffStr) -} - -func (scs *SuggestCmdService) SubmitCommit(commitMessage string) error { - cmd := exec.Command("git", "commit", "-m", commitMessage) - if err := cmd.Run(); err != nil { - return err - } - return nil -} diff --git a/internal/usecase/suggest_cmd.go b/internal/usecase/suggest_cmd.go new file mode 100644 index 0000000..92b6c00 --- /dev/null +++ b/internal/usecase/suggest_cmd.go @@ -0,0 +1,47 @@ +package usecase + +import ( + "fmt" + "github.com/cocoide/commitify/internal/service" + "log" + "os/exec" + + "github.com/cocoide/commitify/internal/entity" +) + +type SuggestCmdUsecase struct { + message service.CommitMessageService + github service.GithubService +} + +func NewSuggestCmdUsecase(message service.CommitMessageService, github service.GithubService) *SuggestCmdUsecase { + conf, err := entity.ReadConfig() + if err != nil { + log.Fatalf("設定の読み込みに失敗") + } + if conf.WithGptRequestLocation() == entity.Local { + log.Fatalf("現在、非対応の機能です。") + } + return &SuggestCmdUsecase{message: message, github: github} +} + +func (u *SuggestCmdUsecase) GenerateCommitMessages() ([]string, error) { + stagingCodeDiff, err := u.github.GetStaginCodeDiff() + // stagingCodeを取捨選択する処理をここに入れる + if err != nil { + return nil, err + } + conf, err := entity.ReadConfig() + if err != nil { + return nil, fmt.Errorf("Failed to open config file: %v", err) + } + return u.message.GenerateCommitMessageList(stagingCodeDiff, conf) +} + +func (u *SuggestCmdUsecase) SubmitCommit(commitMessage string) error { + cmd := exec.Command("git", "commit", "-m", commitMessage) + if err := cmd.Run(); err != nil { + return err + } + return nil +} From 62f9014830d0adf7f6a3f8a0b1e000ea7535ae1b Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 6 Oct 2023 02:15:02 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?= =?UTF-8?q?=E3=81=A7=E3=81=AE=E3=82=B3=E3=83=9F=E3=83=83=E3=83=88=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 18 ++++++++++++-- internal/gateway/local_message.go | 41 +++++++++++++++++++++++++++++++ internal/gateway/open_ai.go | 23 +++-------------- internal/service/service.go | 4 +++ internal/usecase/suggest_cmd.go | 8 ------ 5 files changed, 65 insertions(+), 29 deletions(-) create mode 100644 internal/gateway/local_message.go diff --git a/cmd/suggest.go b/cmd/suggest.go index 5662539..b221175 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -2,8 +2,11 @@ package cmd import ( "fmt" + "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/gateway" + "github.com/cocoide/commitify/internal/service" "github.com/cocoide/commitify/internal/usecase" + "golang.org/x/net/context" "log" "os" "strings" @@ -121,8 +124,19 @@ func NewSuggestModel() *suggestModel { // suggestコマンドのサービスの取得 inputOutput := gateway.NewInputOutputGateway() - grpcServer := gateway.NewGrpcServerGateway() - suggestCmdUsecase := usecase.NewSuggestCmdUsecase(grpcServer, inputOutput) + var commitMessageService service.CommitMessageService + config, err := entity.ReadConfig() + if err != nil { + log.Fatalf("設定ファイルの読み込みができませんでした") + } + nlp := gateway.NewOpenAIGateway(context.Background()) + switch config.WithGptRequestLocation() { + case entity.Local: + commitMessageService = gateway.NewLocalMessageService(nlp) + case entity.Server: + commitMessageService = gateway.NewGrpcServerGateway() + } + suggestCmdUsecase := usecase.NewSuggestCmdUsecase(commitMessageService, inputOutput) return &suggestModel{ choices: []string{""}, diff --git a/internal/gateway/local_message.go b/internal/gateway/local_message.go new file mode 100644 index 0000000..7d9e84d --- /dev/null +++ b/internal/gateway/local_message.go @@ -0,0 +1,41 @@ +package gateway + +import ( + "fmt" + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/service" + "regexp" + "strings" +) + +const ( + NormalMessagePrompt = "Generate up to 5 commit messages for [%s]. Each message should be separated by only space" +) + +var CommitMessageRegex = regexp.MustCompile(`^(\d.\s+)|^(-\s+)|^(\s+)`) + +type localMessageService struct { + nlp service.NLPService +} + +func NewLocalMessageService(nlp service.NLPService) service.CommitMessageService { + return &localMessageService{nlp: nlp} +} + +func (l *localMessageService) GenerateCommitMessageList(code string, conf entity.Config) ([]string, error) { + prompt := fmt.Sprintf(NormalMessagePrompt, code) + result, err := l.nlp.GetAnswerFromPrompt(prompt) + if err != nil { + return nil, err + } + messages := strings.Split(result, "\n") + messages = l.removeFromArrayByRegex(messages, CommitMessageRegex) + return messages, nil +} + +func (l *localMessageService) removeFromArrayByRegex(array []string, pattern *regexp.Regexp) []string { + for i, msg := range array { + array[i] = pattern.ReplaceAllString(msg, "") + } + return array +} diff --git a/internal/gateway/open_ai.go b/internal/gateway/open_ai.go index c543f7f..0aa5c7c 100644 --- a/internal/gateway/open_ai.go +++ b/internal/gateway/open_ai.go @@ -2,23 +2,19 @@ package gateway import ( "context" + "github.com/cocoide/commitify/internal/service" "log" "github.com/cocoide/commitify/internal/entity" "github.com/sashabaranov/go-openai" ) -type OpenAIGateway interface { - GetAnswerFromPrompt(prompt string, variability float32) (string, error) - AsyncGetAnswerFromPrompt(prompt string, variability float32) <-chan string -} - type openAIGateway struct { client *openai.Client ctx context.Context } -func NewOpenAIGateway(ctx context.Context) OpenAIGateway { +func NewOpenAIGateway(ctx context.Context) service.NLPService { config, err := entity.ReadConfig() if err != nil { log.Fatalf("Failed to read config: %v", err) @@ -27,7 +23,7 @@ func NewOpenAIGateway(ctx context.Context) OpenAIGateway { return &openAIGateway{client: client, ctx: ctx} } -func (og *openAIGateway) GetAnswerFromPrompt(prompt string, variability float32) (string, error) { +func (og *openAIGateway) GetAnswerFromPrompt(prompt string) (string, error) { req := openai.ChatCompletionRequest{ Model: openai.GPT3Dot5Turbo, Messages: []openai.ChatCompletionMessage{ @@ -36,7 +32,7 @@ func (og *openAIGateway) GetAnswerFromPrompt(prompt string, variability float32) Content: prompt, }, }, - Temperature: variability, + Temperature: 0.001, } res, err := og.client.CreateChatCompletion(og.ctx, req) if err != nil { @@ -45,14 +41,3 @@ func (og *openAIGateway) GetAnswerFromPrompt(prompt string, variability float32) answer := res.Choices[0].Message.Content return answer, nil } - -func (og *openAIGateway) AsyncGetAnswerFromPrompt(prompt string, variability float32) <-chan string { - responseCh := make(chan string, 1) - - go func() { - answer, _ := og.GetAnswerFromPrompt(prompt, variability) - responseCh <- answer - }() - - return responseCh -} diff --git a/internal/service/service.go b/internal/service/service.go index 19fbb50..0fb0bc0 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -11,3 +11,7 @@ type CommitMessageService interface { type GithubService interface { GetStaginCodeDiff() (string, error) } + +type NLPService interface { + GetAnswerFromPrompt(prompt string) (string, error) +} diff --git a/internal/usecase/suggest_cmd.go b/internal/usecase/suggest_cmd.go index 92b6c00..2682011 100644 --- a/internal/usecase/suggest_cmd.go +++ b/internal/usecase/suggest_cmd.go @@ -3,7 +3,6 @@ package usecase import ( "fmt" "github.com/cocoide/commitify/internal/service" - "log" "os/exec" "github.com/cocoide/commitify/internal/entity" @@ -15,13 +14,6 @@ type SuggestCmdUsecase struct { } func NewSuggestCmdUsecase(message service.CommitMessageService, github service.GithubService) *SuggestCmdUsecase { - conf, err := entity.ReadConfig() - if err != nil { - log.Fatalf("設定の読み込みに失敗") - } - if conf.WithGptRequestLocation() == entity.Local { - log.Fatalf("現在、非対応の機能です。") - } return &SuggestCmdUsecase{message: message, github: github} } From 9250ee18f7ca126affef2a269073557c7b92cfb8 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 6 Oct 2023 02:20:24 +0900 Subject: [PATCH 3/4] chore --- cmd/suggest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index b221175..088e76f 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -129,9 +129,9 @@ func NewSuggestModel() *suggestModel { if err != nil { log.Fatalf("設定ファイルの読み込みができませんでした") } - nlp := gateway.NewOpenAIGateway(context.Background()) switch config.WithGptRequestLocation() { case entity.Local: + nlp := gateway.NewOpenAIGateway(context.Background()) commitMessageService = gateway.NewLocalMessageService(nlp) case entity.Server: commitMessageService = gateway.NewGrpcServerGateway() From adf9b2a12338ae87214ca1e02ecbcb2f83a21401 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 6 Oct 2023 02:31:56 +0900 Subject: [PATCH 4/4] chore --- cmd/suggest.go | 4 ++-- internal/entity/config.go | 4 ++-- internal/gateway/{local_message.go => clinet.go} | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) rename internal/gateway/{local_message.go => clinet.go} (64%) diff --git a/cmd/suggest.go b/cmd/suggest.go index 088e76f..b5bdfd2 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -130,9 +130,9 @@ func NewSuggestModel() *suggestModel { log.Fatalf("設定ファイルの読み込みができませんでした") } switch config.WithGptRequestLocation() { - case entity.Local: + case entity.Client: nlp := gateway.NewOpenAIGateway(context.Background()) - commitMessageService = gateway.NewLocalMessageService(nlp) + commitMessageService = gateway.NewClientCommitMessageGateway(nlp) case entity.Server: commitMessageService = gateway.NewGrpcServerGateway() } diff --git a/internal/entity/config.go b/internal/entity/config.go index ca1f443..a11a39b 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -30,7 +30,7 @@ type GptRequestLocation int const ( Server GptRequestLocation = iota - Local + Client ) type Config struct { @@ -138,7 +138,7 @@ func (c *Config) WithGptRequestLocation() GptRequestLocation { case 0: return Server case 1: - return Local + return Client default: return Server } diff --git a/internal/gateway/local_message.go b/internal/gateway/clinet.go similarity index 64% rename from internal/gateway/local_message.go rename to internal/gateway/clinet.go index 7d9e84d..329a818 100644 --- a/internal/gateway/local_message.go +++ b/internal/gateway/clinet.go @@ -14,15 +14,15 @@ const ( var CommitMessageRegex = regexp.MustCompile(`^(\d.\s+)|^(-\s+)|^(\s+)`) -type localMessageService struct { +type clientCommitMessageGateway struct { nlp service.NLPService } -func NewLocalMessageService(nlp service.NLPService) service.CommitMessageService { - return &localMessageService{nlp: nlp} +func NewClientCommitMessageGateway(nlp service.NLPService) service.CommitMessageService { + return &clientCommitMessageGateway{nlp: nlp} } -func (l *localMessageService) GenerateCommitMessageList(code string, conf entity.Config) ([]string, error) { +func (l *clientCommitMessageGateway) GenerateCommitMessageList(code string, conf entity.Config) ([]string, error) { prompt := fmt.Sprintf(NormalMessagePrompt, code) result, err := l.nlp.GetAnswerFromPrompt(prompt) if err != nil { @@ -33,7 +33,7 @@ func (l *localMessageService) GenerateCommitMessageList(code string, conf entity return messages, nil } -func (l *localMessageService) removeFromArrayByRegex(array []string, pattern *regexp.Regexp) []string { +func (l *clientCommitMessageGateway) removeFromArrayByRegex(array []string, pattern *regexp.Regexp) []string { for i, msg := range array { array[i] = pattern.ReplaceAllString(msg, "") }