From a602fd06c08e09519c87bf48749ef66f86f37cc5 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 3 Sep 2023 13:53:01 +0900 Subject: [PATCH 01/89] Refactor read and write config file and apply it for gpt gateway --- .gitignore | 3 ++- cmd/settings.go | 32 +++++++++++++++------------ config.yaml | 3 +-- internal/entity/config.go | 5 +++++ internal/gateway/openai.go | 10 ++++++--- util/config.go | 45 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 internal/entity/config.go create mode 100644 util/config.go diff --git a/.gitignore b/.gitignore index 0127b4b..8682f2c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ go.work # Environment variables -.env \ No newline at end of file +.env +config.yaml \ No newline at end of file diff --git a/cmd/settings.go b/cmd/settings.go index e8c7ea5..e7adf54 100644 --- a/cmd/settings.go +++ b/cmd/settings.go @@ -3,33 +3,37 @@ package cmd import ( "fmt" "log" + + "github.com/cocoide/commitify/util" "github.com/spf13/cobra" - "github.com/spf13/viper" ) var setAPIKeyCmd = &cobra.Command{ Use: "set-apikey [api_key]", Short: "API Key settings for ChatGPT", - Args: cobra.ExactArgs(1), - Run: func (cmd *cobra.Command, args [] string) { - apikey := args[0] - viper.Set("chatgpt.api_key", apikey) - if err := viper.WriteConfig(); err != nil { - log.Fatal("An error occurred while writing the configuration file:", err) + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + config, _ := util.ReadConfig() + config.ChatGptToken = args[0] + if err := util.WriteConfig(config); err != nil { + log.Fatal("Failed to write into config", err) } - fmt.Println("ChatGPT API key has been set") + fmt.Println("ChatGPT Token has been set") }, } var showAPIKeyCmd = &cobra.Command{ - Use: "show-apikey", + Use: "show-apikey", Short: "Display ChatGPT API key", - Run: func (cmd *cobra.Command, args [] string) { - apikey := viper.GetString("chatgpt.api_key") - if apikey == "" { + Run: func(cmd *cobra.Command, args []string) { + config, err := util.ReadConfig() + if err != nil { + log.Fatal("Failed to read config:", err) + } + if config.ChatGptToken == "" { fmt.Println("API key is not set") } else { - fmt.Println("ChatGPT APIKey:", apikey) + fmt.Println("ChatGPT APIKey:", config.ChatGptToken) } }, } @@ -37,4 +41,4 @@ var showAPIKeyCmd = &cobra.Command{ func init() { rootCmd.AddCommand(setAPIKeyCmd) rootCmd.AddCommand(showAPIKeyCmd) -} \ No newline at end of file +} diff --git a/config.yaml b/config.yaml index 65f1a49..ad76b5a 100644 --- a/config.yaml +++ b/config.yaml @@ -1,2 +1 @@ -chatgpt: - api_key: apikey +chatgpttoken: diff --git a/internal/entity/config.go b/internal/entity/config.go new file mode 100644 index 0000000..5494020 --- /dev/null +++ b/internal/entity/config.go @@ -0,0 +1,5 @@ +package entity + +type Config struct { + ChatGptToken string `json:"chatGptToken"` +} diff --git a/internal/gateway/openai.go b/internal/gateway/openai.go index a68d6c0..ebd70e8 100644 --- a/internal/gateway/openai.go +++ b/internal/gateway/openai.go @@ -2,8 +2,9 @@ package gateway import ( "context" - "os" + "log" + "github.com/cocoide/commitify/util" "github.com/sashabaranov/go-openai" ) @@ -18,8 +19,11 @@ type openAIGateway struct { } func NewOpenAIGateway(ctx context.Context) OpenAIGateway { - OPENAI_SECRET := os.Getenv("OPENAI_SECRET") - client := openai.NewClient(OPENAI_SECRET) + config, err := util.ReadConfig() + if err != nil { + log.Fatalf("Failed to read config: %v", err) + } + client := openai.NewClient(config.ChatGptToken) return &openAIGateway{client: client, ctx: ctx} } diff --git a/util/config.go b/util/config.go new file mode 100644 index 0000000..8fcaed5 --- /dev/null +++ b/util/config.go @@ -0,0 +1,45 @@ +package util + +import ( + "encoding/json" + "fmt" + + "github.com/cocoide/commitify/internal/entity" + "github.com/spf13/viper" +) + +func ReadConfig() (*entity.Config, error) { + var result entity.Config + viper.AddConfigPath(".") + viper.SetConfigName("config") + viper.SetConfigType("yaml") + if err := viper.ReadInConfig(); err != nil { + return &result, fmt.Errorf("Error reading config file, %s", err.Error()) + } + if err := viper.Unmarshal(&result); err != nil { + return &result, fmt.Errorf("Unable to decode into struct, %v", err.Error()) + } + return &result, nil +} + +func WriteConfig(config *entity.Config) error { + viper.AddConfigPath(".") + viper.SetConfigName("config") + viper.SetConfigType("yaml") + configMap := make(map[string]interface{}) + configBytes, err := json.Marshal(config) + if err != nil { + return fmt.Errorf("Error marshalling config: %s", err.Error()) + } + err = json.Unmarshal(configBytes, &configMap) + if err != nil { + return fmt.Errorf("Error unmarshalling config: %s", err.Error()) + } + if err := viper.MergeConfigMap(configMap); err != nil { + return err + } + if err := viper.WriteConfig(); err != nil { + return fmt.Errorf("Error saving config file, %s", err.Error()) + } + return nil +} From acca189127aa8bcab43f407a09c8813ba95c1cb2 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sun, 3 Sep 2023 19:08:45 +0900 Subject: [PATCH 02/89] =?UTF-8?q?fix:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E8=A8=98=E8=BF=B0=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 15847cd..d277b14 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,5 @@ go.work # Environment variables .env -config.yaml dist/ config.yaml \ No newline at end of file From eadd802f5bf8586f9174dc28a8de384131245c48 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sun, 3 Sep 2023 19:46:54 +0900 Subject: [PATCH 03/89] =?UTF-8?q?doc:=20=E3=82=B3=E3=83=9E=E3=83=B3?= =?UTF-8?q?=E3=83=89=E3=83=AA=E3=82=B9=E3=83=88=E3=81=AE=E3=83=89=E3=82=AD?= =?UTF-8?q?=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/command_list.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 doc/command_list.md diff --git a/doc/command_list.md b/doc/command_list.md new file mode 100644 index 0000000..754f615 --- /dev/null +++ b/doc/command_list.md @@ -0,0 +1,12 @@ +## コマンドリスト + +### コマンド +- `suggest`:コミットメッセージの生成 +- `config`:各種の設定 + - 選択肢を出して設定項目を選んでもらう + - 設定項目はAPIキー、日本語/英語、など + +### フラッグ +- `--help` `-h`:CLIのコマンドとオプション一覧を表示 +- `--docs` `-d`:コミットメッセージに関するドキュメント +- `--version` `-v`:アプリのバージョン表示 From 20400acd01b79562dd87441d275e4d2f217000d0 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Mon, 4 Sep 2023 23:42:09 +0900 Subject: [PATCH 04/89] =?UTF-8?q?fix:=20=E8=A8=AD=E5=AE=9A=E9=A0=85?= =?UTF-8?q?=E7=9B=AE=E3=82=92Toke=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8FApiKe?= =?UTF-8?q?y=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/settings.go | 6 +++--- internal/entity/config.go | 2 +- internal/gateway/openai.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/settings.go b/cmd/settings.go index e7adf54..d953b43 100644 --- a/cmd/settings.go +++ b/cmd/settings.go @@ -14,7 +14,7 @@ var setAPIKeyCmd = &cobra.Command{ Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { config, _ := util.ReadConfig() - config.ChatGptToken = args[0] + config.ChatGptApiKey = args[0] if err := util.WriteConfig(config); err != nil { log.Fatal("Failed to write into config", err) } @@ -30,10 +30,10 @@ var showAPIKeyCmd = &cobra.Command{ if err != nil { log.Fatal("Failed to read config:", err) } - if config.ChatGptToken == "" { + if config.ChatGptApiKey == "" { fmt.Println("API key is not set") } else { - fmt.Println("ChatGPT APIKey:", config.ChatGptToken) + fmt.Println("ChatGPT APIKey:", config.ChatGptApiKey) } }, } diff --git a/internal/entity/config.go b/internal/entity/config.go index 5494020..1456ce4 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -1,5 +1,5 @@ package entity type Config struct { - ChatGptToken string `json:"chatGptToken"` + ChatGptApiKey string `json:"chatGptApiKey"` } diff --git a/internal/gateway/openai.go b/internal/gateway/openai.go index ebd70e8..d86d304 100644 --- a/internal/gateway/openai.go +++ b/internal/gateway/openai.go @@ -23,7 +23,7 @@ func NewOpenAIGateway(ctx context.Context) OpenAIGateway { if err != nil { log.Fatalf("Failed to read config: %v", err) } - client := openai.NewClient(config.ChatGptToken) + client := openai.NewClient(config.ChatGptApiKey) return &openAIGateway{client: client, ctx: ctx} } From 14d5afe4c70471bc263a5feb7f4b723ee5a3bfd4 Mon Sep 17 00:00:00 2001 From: Akira_0809 <102137735+Akira0809@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:41:20 +0900 Subject: [PATCH 05/89] =?UTF-8?q?loading=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index 1ba365b..26517a8 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -18,6 +18,7 @@ type model struct { currentIdx int errorMsg string isLoading bool + animationIdx int messages []string } @@ -70,6 +71,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyCtrlC, tea.KeyEsc: return m, tea.Quit } + case tea.Cmd: + if m.isLoading { + m.animationIdx = (m.animationIdx + 1) % 3 + } } return m, nil } @@ -80,7 +85,9 @@ func (m model) View() string { return fmt.Sprintf(red(m.errorMsg)) } if m.isLoading { - return "🌎 Generating commit messages ..." + AnimationEarth := []string{"🌎","🌍","🌏"} + AnimationPoint := []string{".","..","..."} + return fmt.Sprintf("%s Generating commit messages %s", AnimationEarth[m.animationIdx], AnimationPoint[m.animationIdx]) } var b strings.Builder if m.errorMsg != "" { From a62741bde935a82299c2905d4a3689c8deaea256 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 01:38:07 +0900 Subject: [PATCH 06/89] =?UTF-8?q?feat:=20`config.yaml`=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=8C=E7=84=A1=E3=81=91=E3=82=8C=E3=81=B0?= =?UTF-8?q?=E6=96=B0=E8=A6=8F=E3=81=A7=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.yaml | 1 - util/config.go | 28 +++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) delete mode 100644 config.yaml diff --git a/config.yaml b/config.yaml deleted file mode 100644 index ad76b5a..0000000 --- a/config.yaml +++ /dev/null @@ -1 +0,0 @@ -chatgpttoken: diff --git a/util/config.go b/util/config.go index 8fcaed5..6342ac3 100644 --- a/util/config.go +++ b/util/config.go @@ -3,6 +3,7 @@ package util import ( "encoding/json" "fmt" + "os" "github.com/cocoide/commitify/internal/entity" "github.com/spf13/viper" @@ -10,36 +11,53 @@ import ( func ReadConfig() (*entity.Config, error) { var result entity.Config + + // configファイルがあるかどうかを確認 + _, err := os.Stat("config.yaml") + if os.IsNotExist(err) { + if _, err := os.Create("config.yaml"); err != nil { + return &result, fmt.Errorf("error creating config file, %s", err.Error()) + } + } + viper.AddConfigPath(".") viper.SetConfigName("config") viper.SetConfigType("yaml") if err := viper.ReadInConfig(); err != nil { - return &result, fmt.Errorf("Error reading config file, %s", err.Error()) + return &result, fmt.Errorf("error reading config file, %s", err.Error()) } if err := viper.Unmarshal(&result); err != nil { - return &result, fmt.Errorf("Unable to decode into struct, %v", err.Error()) + return &result, fmt.Errorf("unable to decode into struct, %v", err.Error()) } return &result, nil } func WriteConfig(config *entity.Config) error { + // configファイルがあるかどうかを確認 + _, err := os.Stat("config.yaml") + if !os.IsNotExist(err) { + if _, err := os.Create("config.yaml"); err != nil { + return fmt.Errorf("error creating config file, %s", err.Error()) + } + } + viper.AddConfigPath(".") viper.SetConfigName("config") viper.SetConfigType("yaml") configMap := make(map[string]interface{}) configBytes, err := json.Marshal(config) if err != nil { - return fmt.Errorf("Error marshalling config: %s", err.Error()) + return fmt.Errorf("error marshalling config: %s", err.Error()) } err = json.Unmarshal(configBytes, &configMap) if err != nil { - return fmt.Errorf("Error unmarshalling config: %s", err.Error()) + return fmt.Errorf("error unmarshalling config: %s", err.Error()) } if err := viper.MergeConfigMap(configMap); err != nil { return err } if err := viper.WriteConfig(); err != nil { - return fmt.Errorf("Error saving config file, %s", err.Error()) + return fmt.Errorf("error saving config file, %s", err.Error()) } return nil } From 6f5d1eb04bbbea5d8861425ce4ea9d30bde82d4b Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 01:39:29 +0900 Subject: [PATCH 07/89] =?UTF-8?q?fix:=20=E8=A8=AD=E5=AE=9A=E5=91=A8?= =?UTF-8?q?=E3=82=8A=E3=81=AE=E4=B8=8D=E8=A6=81=E3=81=AA=E9=A0=85=E7=9B=AE?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 1 - main.go | 12 ------------ util/loadenv.go | 17 ----------------- 3 files changed, 30 deletions(-) delete mode 100644 util/loadenv.go diff --git a/cmd/suggest.go b/cmd/suggest.go index 1ba365b..c63bcfa 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -28,7 +28,6 @@ type generateMessages struct { func (m model) Init() tea.Cmd { return func() tea.Msg { - util.LoadEnv() ctx := context.Background() og := gateway.NewOpenAIGateway(ctx) ms := service.NewMessageService(og) diff --git a/main.go b/main.go index 7539cc2..829c11e 100644 --- a/main.go +++ b/main.go @@ -1,21 +1,9 @@ package main import ( - "log" - "github.com/cocoide/commitify/cmd" - "github.com/spf13/viper" ) func main() { - viper.SetConfigName("config") - viper.AddConfigPath(".") - viper.SetConfigType("yaml") - viper.AutomaticEnv() - - if err := viper.ReadInConfig(); err != nil { - log.Println("An error occurred while reading the configuration file:", err) - } - cmd.Execute() } diff --git a/util/loadenv.go b/util/loadenv.go deleted file mode 100644 index ccc7892..0000000 --- a/util/loadenv.go +++ /dev/null @@ -1,17 +0,0 @@ -package util - -import ( - "log" - - "github.com/joho/godotenv" -) - -// Viperを導入したらgodotenvのコードは削除する -func LoadEnv() { - err := godotenv.Load(".env") - if err != nil { - log.Printf("failed to load .env file: %v" + err.Error()) - } else { - // log.Print("success to load .env file") - } -} From 681ba9934265b6defb2c8ba9156dc8e5f9792b2d Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 01:39:45 +0900 Subject: [PATCH 08/89] =?UTF-8?q?feat:=20config=E9=A0=85=E7=9B=AE=E3=81=AE?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/entity/config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/entity/config.go b/internal/entity/config.go index 1456ce4..226ac5a 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -2,4 +2,6 @@ package entity type Config struct { ChatGptApiKey string `json:"chatGptApiKey"` + UseLanguage string `json:"UseLanguage"` + CommitFormat string `json:"CommitFormat"` } From 91190ba93faa654774833a2e2254a37a0b08a1f3 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 01:40:20 +0900 Subject: [PATCH 09/89] =?UTF-8?q?feat:=20`config`=E3=82=B3=E3=83=9E?= =?UTF-8?q?=E3=83=B3=E3=83=89=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config.go | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 +- go.sum | 6 ++ 3 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 cmd/config.go diff --git a/cmd/config.go b/cmd/config.go new file mode 100644 index 0000000..6da51ad --- /dev/null +++ b/cmd/config.go @@ -0,0 +1,203 @@ +package cmd + +import ( + "fmt" + "strings" + + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/cocoide/commitify/util" + "github.com/fatih/color" + "github.com/spf13/cobra" +) + +var ( + configKey = [...]string{"api-key", "language", "format"} + configOption = [][]string{ + {}, + {"Japanese", "English"}, + {"Format 1", "Format 2"}, + } +) + +type configModel struct { + configKeyIndex int + configOptionIndex int + configKeySelected bool + err error + textInput textinput.Model +} + +func initConfigModel() configModel { + ti := textinput.New() + ti.Focus() + + return configModel{ + textInput: ti, + err: nil, + } +} + +func (cm configModel) Init() tea.Cmd { + return textinput.Blink +} + +func (cm configModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch cm.configKeySelected { + // 設定項目を選択する + case false: + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyUp: + if cm.configKeyIndex > 0 { + cm.configKeyIndex-- + } + case tea.KeyDown: + if cm.configKeyIndex < len(configKey)-1 { + cm.configKeyIndex++ + } + case tea.KeyEnter: + cm.configKeySelected = true + return cm, nil + case tea.KeyCtrlC, tea.KeyEsc: + return cm, tea.Quit + } + } + + // 設定項目に値をセットする + case true: + switch len(configOption[cm.configKeyIndex]) { + // 選択肢のない項目は入力を受け付ける + case 0: + var cmd tea.Cmd + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyEnter: + saveConfig(cm) + return cm, tea.Quit + case tea.KeyCtrlC, tea.KeyEsc: + return cm, tea.Quit + } + case error: + cm.err = msg + return cm, nil + } + + cm.textInput, cmd = cm.textInput.Update(msg) + return cm, cmd + + // 選択肢がある場合はセレクターで表示する + default: + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyUp: + if cm.configOptionIndex > 0 { + cm.configOptionIndex-- + } + case tea.KeyDown: + if cm.configOptionIndex < len(configOption[cm.configKeyIndex])-1 { + cm.configOptionIndex++ + } + case tea.KeyEnter: + saveConfig(cm) + return cm, tea.Quit + case tea.KeyCtrlC, tea.KeyEsc: + return cm, tea.Quit + } + } + } + } + + return cm, nil +} + +func (cm configModel) View() string { + var b strings.Builder + + switch cm.configKeySelected { + // 設定項目を選んでいない時 + case false: + white := color.New(color.FgWhite).SprintFunc() + b.WriteString(white("設定項目を選んでください:\n")) + b.WriteString(white(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) + + for i, choice := range configKey { + cyan := color.New(color.FgCyan).SprintFunc() + hiCyan := color.New(color.FgHiCyan).SprintFunc() + if i == cm.configKeyIndex { + b.WriteString(fmt.Sprintf(hiCyan("➡️ %s\n"), choice)) + } else { + b.WriteString(fmt.Sprintf(cyan(" %s\n"), choice)) + } + } + + // 設定項目に値をセットする + case true: + // 選択肢のない項目はテキストエリアを表示 + switch len(configOption[cm.configKeyIndex]) { + case 0: + white := color.New(color.FgWhite).SprintFunc() + b.WriteString(white(fmt.Sprintf( + "ここに%sを入力: %s\n", + configKey[cm.configKeyIndex], + cm.textInput.View(), + ))) + b.WriteString(white(" Enterキーで確定")) + + default: + white := color.New(color.FgWhite).SprintFunc() + b.WriteString(white("設定内容を選んでください:\n")) + b.WriteString(white(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) + + for i, option := range configOption[cm.configKeyIndex] { + cyan := color.New(color.FgCyan).SprintFunc() + hiCyan := color.New(color.FgHiCyan).SprintFunc() + if i == cm.configOptionIndex { + b.WriteString(fmt.Sprintf(hiCyan("➡️ %s\n"), option)) + } else { + b.WriteString(fmt.Sprintf(cyan(" %s\n"), option)) + } + } + } + } + + return b.String() +} + +var configCmd = &cobra.Command{ + Use: "config", + Short: "設定を変更します", + Long: `設定を変更します。設定項目はコマンドを実行すると表示されます。`, + Run: func(cmd *cobra.Command, args []string) { + p := tea.NewProgram(initConfigModel()) + p.Run() + }, +} + +func init() { + rootCmd.AddCommand(configCmd) +} + +func saveConfig(cm configModel) { + currentConfig, err := util.ReadConfig() + if err != nil { + fmt.Println(err) + } + + switch cm.configKeyIndex { + case 0: + currentConfig.ChatGptApiKey = cm.textInput.Value() + case 1: + currentConfig.UseLanguage = configOption[cm.configKeyIndex][cm.configOptionIndex] + case 2: + currentConfig.CommitFormat = configOption[cm.configKeyIndex][cm.configOptionIndex] + } + + err = util.WriteConfig(currentConfig) + if err != nil { + fmt.Println(err) + } +} diff --git a/go.mod b/go.mod index 5c207dc..824f8f7 100644 --- a/go.mod +++ b/go.mod @@ -29,9 +29,11 @@ require ( ) require ( + github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/bubbles v0.16.1 // indirect + github.com/charmbracelet/lipgloss v0.7.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-localereader v0.0.1 // indirect @@ -41,7 +43,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 - github.com/spf13/pflag v1.0.5 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.6.0 // indirect diff --git a/go.sum b/go.sum index 8ad886b..274f97b 100644 --- a/go.sum +++ b/go.sum @@ -38,11 +38,17 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= +github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= +github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= +github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= From 5c02115f963d76355def35e4825a9997540d377c Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 01:40:43 +0900 Subject: [PATCH 10/89] =?UTF-8?q?fix:=20setting=E3=82=B3=E3=83=9E=E3=83=B3?= =?UTF-8?q?=E3=83=89=E3=82=92revert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/settings.go | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 cmd/settings.go diff --git a/cmd/settings.go b/cmd/settings.go deleted file mode 100644 index d953b43..0000000 --- a/cmd/settings.go +++ /dev/null @@ -1,44 +0,0 @@ -package cmd - -import ( - "fmt" - "log" - - "github.com/cocoide/commitify/util" - "github.com/spf13/cobra" -) - -var setAPIKeyCmd = &cobra.Command{ - Use: "set-apikey [api_key]", - Short: "API Key settings for ChatGPT", - Args: cobra.ExactArgs(1), - Run: func(cmd *cobra.Command, args []string) { - config, _ := util.ReadConfig() - config.ChatGptApiKey = args[0] - if err := util.WriteConfig(config); err != nil { - log.Fatal("Failed to write into config", err) - } - fmt.Println("ChatGPT Token has been set") - }, -} - -var showAPIKeyCmd = &cobra.Command{ - Use: "show-apikey", - Short: "Display ChatGPT API key", - Run: func(cmd *cobra.Command, args []string) { - config, err := util.ReadConfig() - if err != nil { - log.Fatal("Failed to read config:", err) - } - if config.ChatGptApiKey == "" { - fmt.Println("API key is not set") - } else { - fmt.Println("ChatGPT APIKey:", config.ChatGptApiKey) - } - }, -} - -func init() { - rootCmd.AddCommand(setAPIKeyCmd) - rootCmd.AddCommand(showAPIKeyCmd) -} From 993a71563001d5ade4eb9fc1b48b3320947f020c Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 02:19:38 +0900 Subject: [PATCH 11/89] =?UTF-8?q?fix:=20config.yaml=E3=82=92git=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E4=B8=8B=E3=81=8B=E3=82=89=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 config.yaml diff --git a/config.yaml b/config.yaml deleted file mode 100644 index ad76b5a..0000000 --- a/config.yaml +++ /dev/null @@ -1 +0,0 @@ -chatgpttoken: From c1706129d1aa7a9373d8804e48a7b71fa3ad7001 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 02:20:08 +0900 Subject: [PATCH 12/89] =?UTF-8?q?fix:=20config.yaml=E3=82=92git=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E4=B8=8B=E3=81=8B=E3=82=89=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 config.yaml diff --git a/config.yaml b/config.yaml deleted file mode 100644 index ad76b5a..0000000 --- a/config.yaml +++ /dev/null @@ -1 +0,0 @@ -chatgpttoken: From 354b9e84d12e3db2f4dc32d616a9065bb2da6ea2 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Tue, 5 Sep 2023 02:27:10 +0900 Subject: [PATCH 13/89] =?UTF-8?q?fix:=20=E8=A8=AD=E5=AE=9A=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=8C=E3=81=82=E3=82=8B=E3=81=8B?= =?UTF-8?q?=E3=81=A9=E3=81=86=E3=81=8B=E3=81=AE=E7=A2=BA=E8=AA=8D=E3=82=92?= =?UTF-8?q?=E3=80=81=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AB=E8=A1=8C=E3=81=86?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 11 +++++++++++ util/config.go | 17 ----------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/main.go b/main.go index 829c11e..fbd7bac 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,20 @@ package main import ( + "fmt" + "os" + "github.com/cocoide/commitify/cmd" ) func main() { + // configファイルがあるかどうかを確認 + _, err := os.Stat("config.yaml") + if os.IsNotExist(err) { + if _, err := os.Create("config.yaml"); err != nil { + fmt.Printf("error creating config file, %s", err.Error()) + } + } + cmd.Execute() } diff --git a/util/config.go b/util/config.go index 6342ac3..ba9e8ca 100644 --- a/util/config.go +++ b/util/config.go @@ -3,7 +3,6 @@ package util import ( "encoding/json" "fmt" - "os" "github.com/cocoide/commitify/internal/entity" "github.com/spf13/viper" @@ -12,14 +11,6 @@ import ( func ReadConfig() (*entity.Config, error) { var result entity.Config - // configファイルがあるかどうかを確認 - _, err := os.Stat("config.yaml") - if os.IsNotExist(err) { - if _, err := os.Create("config.yaml"); err != nil { - return &result, fmt.Errorf("error creating config file, %s", err.Error()) - } - } - viper.AddConfigPath(".") viper.SetConfigName("config") viper.SetConfigType("yaml") @@ -33,14 +24,6 @@ func ReadConfig() (*entity.Config, error) { } func WriteConfig(config *entity.Config) error { - // configファイルがあるかどうかを確認 - _, err := os.Stat("config.yaml") - if !os.IsNotExist(err) { - if _, err := os.Create("config.yaml"); err != nil { - return fmt.Errorf("error creating config file, %s", err.Error()) - } - } - viper.AddConfigPath(".") viper.SetConfigName("config") viper.SetConfigType("yaml") From 8b41a149b8e8f4a856a0e41721d57d7ee13e0048 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 8 Sep 2023 00:18:50 +0900 Subject: [PATCH 14/89] Remove config.yaml --- config.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 config.yaml diff --git a/config.yaml b/config.yaml deleted file mode 100644 index ad76b5a..0000000 --- a/config.yaml +++ /dev/null @@ -1 +0,0 @@ -chatgpttoken: From ef35f8d8a23efe81a33b84f7fae845784ae9d14f Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 01:20:45 +0900 Subject: [PATCH 15/89] Add test of message service --- Makefile | 5 +++ cmd/suggest.go | 3 +- go.mod | 4 +- go.sum | 3 +- internal/gateway/openai.go | 1 + internal/service/message.go | 18 +++++---- internal/service/message_test.go | 46 +++++++++++++++++++++++ mock/openai.go | 63 ++++++++++++++++++++++++++++++++ 8 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 Makefile create mode 100644 internal/service/message_test.go create mode 100644 mock/openai.go diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9846501 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +.PHONY: test + +test: + go generate ./... + go test -v ./internal/service \ No newline at end of file diff --git a/cmd/suggest.go b/cmd/suggest.go index c63bcfa..b1dac8c 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -31,7 +31,8 @@ func (m model) Init() tea.Cmd { ctx := context.Background() og := gateway.NewOpenAIGateway(ctx) ms := service.NewMessageService(og) - messages, err := ms.GenerateCommitMessage() + stagingCode := util.ExecGetStagingCode() + messages, err := ms.GenerateCommitMessage(stagingCode) if err != nil { return generateMessages{errorMsg: "メッセージの生成に失敗: " + err.Error()} } diff --git a/go.mod b/go.mod index 824f8f7..6ccdc72 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,10 @@ module github.com/cocoide/commitify go 1.19 require ( + github.com/charmbracelet/bubbles v0.16.1 github.com/charmbracelet/bubbletea v0.24.2 github.com/fatih/color v1.15.0 - github.com/joho/godotenv v1.5.1 + github.com/golang/mock v1.4.4 github.com/sashabaranov/go-openai v1.15.1 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 @@ -31,7 +32,6 @@ require ( require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/bubbles v0.16.1 // indirect github.com/charmbracelet/lipgloss v0.7.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect diff --git a/go.sum b/go.sum index 274f97b..d9699e7 100644 --- a/go.sum +++ b/go.sum @@ -86,6 +86,7 @@ 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/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -139,8 +140,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= diff --git a/internal/gateway/openai.go b/internal/gateway/openai.go index d86d304..18df70c 100644 --- a/internal/gateway/openai.go +++ b/internal/gateway/openai.go @@ -8,6 +8,7 @@ import ( "github.com/sashabaranov/go-openai" ) +//go:generate mockgen -source=openai.go -destination=../../mock/openai.go type OpenAIGateway interface { GetAnswerFromPrompt(prompt string, variability float32) (string, error) AsyncGetAnswerFromPrompt(prompt string, variability float32) <-chan string diff --git a/internal/service/message.go b/internal/service/message.go index 80a9b8d..bfc234f 100644 --- a/internal/service/message.go +++ b/internal/service/message.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/cocoide/commitify/internal/gateway" - "github.com/cocoide/commitify/util" ) const ( @@ -13,9 +12,11 @@ const ( FormatNotice = ", format commit as:\n- feat: [feature description]\n- bugfix: [bugfix description]" ) +var PromptVariability float32 = 0.01 + // メッセージの生成、加工に関するクラス type MessageService interface { - GenerateCommitMessage() ([]string, error) + GenerateCommitMessage(stagingCode string) ([]string, error) } type messageService struct { @@ -26,14 +27,15 @@ func NewMessageService(og gateway.OpenAIGateway) MessageService { return &messageService{og: og} } -func (s *messageService) GenerateCommitMessage() ([]string, error) { - var result <-chan string - stagingCode := util.ExecGetStagingCode() +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, string(stagingCode)) - result = s.og.AsyncGetAnswerFromPrompt(prompt, 0.01) - messages := strings.Split(<-result, "\n") + 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 new file mode 100644 index 0000000..e94b913 --- /dev/null +++ b/internal/service/message_test.go @@ -0,0 +1,46 @@ +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/mock/openai.go b/mock/openai.go new file mode 100644 index 0000000..78f7b68 --- /dev/null +++ b/mock/openai.go @@ -0,0 +1,63 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: openai.go + +// Package mock_gateway is a generated GoMock package. +package mock_gateway + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockOpenAIGateway is a mock of OpenAIGateway interface. +type MockOpenAIGateway struct { + ctrl *gomock.Controller + recorder *MockOpenAIGatewayMockRecorder +} + +// MockOpenAIGatewayMockRecorder is the mock recorder for MockOpenAIGateway. +type MockOpenAIGatewayMockRecorder struct { + mock *MockOpenAIGateway +} + +// NewMockOpenAIGateway creates a new mock instance. +func NewMockOpenAIGateway(ctrl *gomock.Controller) *MockOpenAIGateway { + mock := &MockOpenAIGateway{ctrl: ctrl} + mock.recorder = &MockOpenAIGatewayMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockOpenAIGateway) EXPECT() *MockOpenAIGatewayMockRecorder { + return m.recorder +} + +// AsyncGetAnswerFromPrompt mocks base method. +func (m *MockOpenAIGateway) AsyncGetAnswerFromPrompt(prompt string, variability float32) <-chan string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AsyncGetAnswerFromPrompt", prompt, variability) + ret0, _ := ret[0].(<-chan string) + return ret0 +} + +// AsyncGetAnswerFromPrompt indicates an expected call of AsyncGetAnswerFromPrompt. +func (mr *MockOpenAIGatewayMockRecorder) AsyncGetAnswerFromPrompt(prompt, variability interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AsyncGetAnswerFromPrompt", reflect.TypeOf((*MockOpenAIGateway)(nil).AsyncGetAnswerFromPrompt), prompt, variability) +} + +// GetAnswerFromPrompt mocks base method. +func (m *MockOpenAIGateway) GetAnswerFromPrompt(prompt string, variability float32) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAnswerFromPrompt", prompt, variability) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAnswerFromPrompt indicates an expected call of GetAnswerFromPrompt. +func (mr *MockOpenAIGatewayMockRecorder) GetAnswerFromPrompt(prompt, variability interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAnswerFromPrompt", reflect.TypeOf((*MockOpenAIGateway)(nil).GetAnswerFromPrompt), prompt, variability) +} From 71720a7cef0f72ea439eac4858326b51c83051d0 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 14:07:03 +0900 Subject: [PATCH 16/89] =?UTF-8?q?Add=20=E3=82=A2=E3=82=B9=E3=82=AD?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=83=AD=E3=82=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/docs.go | 28 ++++++++++++++++++++++++++++ static/embed.go | 6 ++++++ static/logo.txt | 8 ++++++++ 3 files changed, 42 insertions(+) create mode 100644 cmd/docs.go create mode 100644 static/embed.go create mode 100644 static/logo.txt diff --git a/cmd/docs.go b/cmd/docs.go new file mode 100644 index 0000000..5391fd3 --- /dev/null +++ b/cmd/docs.go @@ -0,0 +1,28 @@ +/* +Copyright © 2023 NAME HERE +*/ +package cmd + +import ( + "fmt" + + "github.com/cocoide/commitify/static" + "github.com/fatih/color" + "github.com/spf13/cobra" +) + +// docsCmd represents the docs command +var docsCmd = &cobra.Command{ + Use: "docs", + Short: "Document of committify", + Run: func(cmd *cobra.Command, args []string) { + b, _ := static.Logo.ReadFile("logo.txt") + cyan := color.New(color.FgCyan).SprintFunc() + logo := cyan(string(b)) + fmt.Println(logo) + }, +} + +func init() { + rootCmd.AddCommand(docsCmd) +} diff --git a/static/embed.go b/static/embed.go new file mode 100644 index 0000000..bddeeb5 --- /dev/null +++ b/static/embed.go @@ -0,0 +1,6 @@ +package static + +import "embed" + +//go:embed logo.txt +var Logo embed.FS diff --git a/static/logo.txt b/static/logo.txt new file mode 100644 index 0000000..2184f16 --- /dev/null +++ b/static/logo.txt @@ -0,0 +1,8 @@ +  ■■■■   ■■■■    ■■    ■■  ■■    ■■  ■ ■■■■■■ ■  ■■■■ ■    ■  + ■■     ■■   ■   ■■    ■■  ■■    ■■  ■   ■■   ■  ■     ■  ■   + ■      ■     ■  ■■   ■ ■  ■■   ■ ■  ■   ■■   ■  ■     ■  ■   + ■      ■     ■  ■ ■  ■ ■  ■ ■  ■ ■  ■   ■■   ■  ■      ■■    + ■      ■     ■  ■ ■  ■ ■  ■ ■  ■ ■  ■   ■■   ■  ■■■■   ■■    + ■      ■     ■  ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    + ■■     ■■   ■   ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    +  ■■■■   ■■■■    ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    \ No newline at end of file From 70c26a883d70165a366574319f26a19123d9cb1a Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 14:40:06 +0900 Subject: [PATCH 17/89] Typo --- cmd/docs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/docs.go b/cmd/docs.go index 5391fd3..d7e40f9 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -14,7 +14,7 @@ import ( // docsCmd represents the docs command var docsCmd = &cobra.Command{ Use: "docs", - Short: "Document of committify", + Short: "Document of commitify", Run: func(cmd *cobra.Command, args []string) { b, _ := static.Logo.ReadFile("logo.txt") cyan := color.New(color.FgCyan).SprintFunc() From 8c357c767435fa737d3cf414691d1f5474315f75 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 14:41:03 +0900 Subject: [PATCH 18/89] =?UTF-8?q?O=E3=82=92=E5=B7=A6=E5=8F=B3=E5=AF=BE?= =?UTF-8?q?=E7=A7=B0=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/logo.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/static/logo.txt b/static/logo.txt index 2184f16..7cd8b68 100644 --- a/static/logo.txt +++ b/static/logo.txt @@ -1,8 +1,8 @@ -  ■■■■   ■■■■    ■■    ■■  ■■    ■■  ■ ■■■■■■ ■  ■■■■ ■    ■  - ■■     ■■   ■   ■■    ■■  ■■    ■■  ■   ■■   ■  ■     ■  ■   +  ■■■■    ■■■    ■■    ■■  ■■    ■■  ■ ■■■■■■ ■  ■■■■ ■    ■  + ■■      ■   ■   ■■    ■■  ■■    ■■  ■   ■■   ■  ■     ■  ■    ■      ■     ■  ■■   ■ ■  ■■   ■ ■  ■   ■■   ■  ■     ■  ■    ■      ■     ■  ■ ■  ■ ■  ■ ■  ■ ■  ■   ■■   ■  ■      ■■     ■      ■     ■  ■ ■  ■ ■  ■ ■  ■ ■  ■   ■■   ■  ■■■■   ■■     ■      ■     ■  ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    - ■■     ■■   ■   ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    -  ■■■■   ■■■■    ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    \ No newline at end of file + ■■      ■   ■   ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    +  ■■■■    ■■■    ■  ■■  ■  ■  ■■  ■  ■   ■■   ■  ■       ■    \ No newline at end of file From 58c2eea2d9fb6143b20c55a35ea1d22cd74b7e4f Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 16:07:41 +0900 Subject: [PATCH 19/89] Add pb generated files --- go.mod | 7 +- go.sum | 18 +- pb/commit_message_service.pb.go | 352 +++++++++++++++++++++++++++ pb/commit_message_service_grpc.pb.go | 109 +++++++++ 4 files changed, 483 insertions(+), 3 deletions(-) create mode 100644 pb/commit_message_service.pb.go create mode 100644 pb/commit_message_service_grpc.pb.go diff --git a/go.mod b/go.mod index 6ccdc72..3ec8675 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,8 @@ require ( github.com/sashabaranov/go-openai v1.15.1 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 + google.golang.org/grpc v1.55.0 + google.golang.org/protobuf v1.30.0 ) require ( @@ -34,6 +36,7 @@ require ( 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 github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-localereader v0.0.1 // indirect @@ -43,8 +46,10 @@ 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.10.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.6.0 // indirect + golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect ) diff --git a/go.sum b/go.sum index d9699e7..124cadd 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -113,6 +116,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -295,6 +299,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -358,8 +364,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -486,6 +492,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -502,6 +510,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -512,6 +522,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pb/commit_message_service.pb.go b/pb/commit_message_service.pb.go new file mode 100644 index 0000000..fe6d734 --- /dev/null +++ b/pb/commit_message_service.pb.go @@ -0,0 +1,352 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.2 +// source: commit_message_service.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// CodeFormatType specifies the type of commit message to generate +type CodeFormatType int32 + +const ( + CodeFormatType_EMOJI CodeFormatType = 0 + CodeFormatType_PREFIX CodeFormatType = 1 + CodeFormatType_NORMAL CodeFormatType = 2 +) + +// Enum value maps for CodeFormatType. +var ( + CodeFormatType_name = map[int32]string{ + 0: "EMOJI", + 1: "PREFIX", + 2: "NORMAL", + } + CodeFormatType_value = map[string]int32{ + "EMOJI": 0, + "PREFIX": 1, + "NORMAL": 2, + } +) + +func (x CodeFormatType) Enum() *CodeFormatType { + p := new(CodeFormatType) + *p = x + return p +} + +func (x CodeFormatType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CodeFormatType) Descriptor() protoreflect.EnumDescriptor { + return file_commit_message_service_proto_enumTypes[0].Descriptor() +} + +func (CodeFormatType) Type() protoreflect.EnumType { + return &file_commit_message_service_proto_enumTypes[0] +} + +func (x CodeFormatType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CodeFormatType.Descriptor instead. +func (CodeFormatType) EnumDescriptor() ([]byte, []int) { + return file_commit_message_service_proto_rawDescGZIP(), []int{0} +} + +// LanguageType specifies the language of the commit message to generate +type LanguageType int32 + +const ( + LanguageType_ENGLISH LanguageType = 0 + LanguageType_JAPANESE LanguageType = 1 +) + +// Enum value maps for LanguageType. +var ( + LanguageType_name = map[int32]string{ + 0: "ENGLISH", + 1: "JAPANESE", + } + LanguageType_value = map[string]int32{ + "ENGLISH": 0, + "JAPANESE": 1, + } +) + +func (x LanguageType) Enum() *LanguageType { + p := new(LanguageType) + *p = x + return p +} + +func (x LanguageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (LanguageType) Descriptor() protoreflect.EnumDescriptor { + return file_commit_message_service_proto_enumTypes[1].Descriptor() +} + +func (LanguageType) Type() protoreflect.EnumType { + return &file_commit_message_service_proto_enumTypes[1] +} + +func (x LanguageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use LanguageType.Descriptor instead. +func (LanguageType) EnumDescriptor() ([]byte, []int) { + return file_commit_message_service_proto_rawDescGZIP(), []int{1} +} + +// CommitMessageRequest is the request format for generating messages +type CommitMessageRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InputCode string `protobuf:"bytes,1,opt,name=inputCode,proto3" json:"inputCode,omitempty"` + CodeFormat CodeFormatType `protobuf:"varint,2,opt,name=codeFormat,proto3,enum=commit_message.CodeFormatType" json:"codeFormat,omitempty"` + Language LanguageType `protobuf:"varint,3,opt,name=language,proto3,enum=commit_message.LanguageType" json:"language,omitempty"` +} + +func (x *CommitMessageRequest) Reset() { + *x = CommitMessageRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_commit_message_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommitMessageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommitMessageRequest) ProtoMessage() {} + +func (x *CommitMessageRequest) ProtoReflect() protoreflect.Message { + mi := &file_commit_message_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommitMessageRequest.ProtoReflect.Descriptor instead. +func (*CommitMessageRequest) Descriptor() ([]byte, []int) { + return file_commit_message_service_proto_rawDescGZIP(), []int{0} +} + +func (x *CommitMessageRequest) GetInputCode() string { + if x != nil { + return x.InputCode + } + return "" +} + +func (x *CommitMessageRequest) GetCodeFormat() CodeFormatType { + if x != nil { + return x.CodeFormat + } + return CodeFormatType_EMOJI +} + +func (x *CommitMessageRequest) GetLanguage() LanguageType { + if x != nil { + return x.Language + } + return LanguageType_ENGLISH +} + +// CommitMessageResponse returns generated commit messages +type CommitMessageResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Messages []string `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` +} + +func (x *CommitMessageResponse) Reset() { + *x = CommitMessageResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_commit_message_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommitMessageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommitMessageResponse) ProtoMessage() {} + +func (x *CommitMessageResponse) ProtoReflect() protoreflect.Message { + mi := &file_commit_message_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommitMessageResponse.ProtoReflect.Descriptor instead. +func (*CommitMessageResponse) Descriptor() ([]byte, []int) { + return file_commit_message_service_proto_rawDescGZIP(), []int{1} +} + +func (x *CommitMessageResponse) GetMessages() []string { + if x != nil { + return x.Messages + } + return nil +} + +var File_commit_message_service_proto protoreflect.FileDescriptor + +var file_commit_message_service_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xae, + 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x38, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, + 0x33, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2a, 0x33, 0x0a, 0x0e, 0x43, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x4f, 0x4a, 0x49, 0x10, + 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x10, 0x01, 0x12, 0x0a, 0x0a, + 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x02, 0x2a, 0x29, 0x0a, 0x0c, 0x4c, 0x61, 0x6e, + 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x47, + 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4a, 0x41, 0x50, 0x41, 0x4e, 0x45, + 0x53, 0x45, 0x10, 0x01, 0x32, 0x7c, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x64, 0x0a, 0x15, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_commit_message_service_proto_rawDescOnce sync.Once + file_commit_message_service_proto_rawDescData = file_commit_message_service_proto_rawDesc +) + +func file_commit_message_service_proto_rawDescGZIP() []byte { + file_commit_message_service_proto_rawDescOnce.Do(func() { + file_commit_message_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_commit_message_service_proto_rawDescData) + }) + return file_commit_message_service_proto_rawDescData +} + +var file_commit_message_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_commit_message_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_commit_message_service_proto_goTypes = []interface{}{ + (CodeFormatType)(0), // 0: commit_message.CodeFormatType + (LanguageType)(0), // 1: commit_message.LanguageType + (*CommitMessageRequest)(nil), // 2: commit_message.CommitMessageRequest + (*CommitMessageResponse)(nil), // 3: commit_message.CommitMessageResponse +} +var file_commit_message_service_proto_depIdxs = []int32{ + 0, // 0: commit_message.CommitMessageRequest.codeFormat:type_name -> commit_message.CodeFormatType + 1, // 1: commit_message.CommitMessageRequest.language:type_name -> commit_message.LanguageType + 2, // 2: commit_message.CommitMessageService.GenerateCommitMessage:input_type -> commit_message.CommitMessageRequest + 3, // 3: commit_message.CommitMessageService.GenerateCommitMessage:output_type -> commit_message.CommitMessageResponse + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_commit_message_service_proto_init() } +func file_commit_message_service_proto_init() { + if File_commit_message_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_commit_message_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommitMessageRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_commit_message_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommitMessageResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_commit_message_service_proto_rawDesc, + NumEnums: 2, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_commit_message_service_proto_goTypes, + DependencyIndexes: file_commit_message_service_proto_depIdxs, + EnumInfos: file_commit_message_service_proto_enumTypes, + MessageInfos: file_commit_message_service_proto_msgTypes, + }.Build() + File_commit_message_service_proto = out.File + file_commit_message_service_proto_rawDesc = nil + file_commit_message_service_proto_goTypes = nil + file_commit_message_service_proto_depIdxs = nil +} diff --git a/pb/commit_message_service_grpc.pb.go b/pb/commit_message_service_grpc.pb.go new file mode 100644 index 0000000..65a91f3 --- /dev/null +++ b/pb/commit_message_service_grpc.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.2 +// source: commit_message_service.proto + +package pb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + CommitMessageService_GenerateCommitMessage_FullMethodName = "/commit_message.CommitMessageService/GenerateCommitMessage" +) + +// CommitMessageServiceClient is the client API for CommitMessageService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type CommitMessageServiceClient interface { + GenerateCommitMessage(ctx context.Context, in *CommitMessageRequest, opts ...grpc.CallOption) (*CommitMessageResponse, error) +} + +type commitMessageServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCommitMessageServiceClient(cc grpc.ClientConnInterface) CommitMessageServiceClient { + return &commitMessageServiceClient{cc} +} + +func (c *commitMessageServiceClient) GenerateCommitMessage(ctx context.Context, in *CommitMessageRequest, opts ...grpc.CallOption) (*CommitMessageResponse, error) { + out := new(CommitMessageResponse) + err := c.cc.Invoke(ctx, CommitMessageService_GenerateCommitMessage_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CommitMessageServiceServer is the server API for CommitMessageService service. +// All implementations must embed UnimplementedCommitMessageServiceServer +// for forward compatibility +type CommitMessageServiceServer interface { + GenerateCommitMessage(context.Context, *CommitMessageRequest) (*CommitMessageResponse, error) + mustEmbedUnimplementedCommitMessageServiceServer() +} + +// UnimplementedCommitMessageServiceServer must be embedded to have forward compatible implementations. +type UnimplementedCommitMessageServiceServer struct { +} + +func (UnimplementedCommitMessageServiceServer) GenerateCommitMessage(context.Context, *CommitMessageRequest) (*CommitMessageResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GenerateCommitMessage not implemented") +} +func (UnimplementedCommitMessageServiceServer) mustEmbedUnimplementedCommitMessageServiceServer() {} + +// UnsafeCommitMessageServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CommitMessageServiceServer will +// result in compilation errors. +type UnsafeCommitMessageServiceServer interface { + mustEmbedUnimplementedCommitMessageServiceServer() +} + +func RegisterCommitMessageServiceServer(s grpc.ServiceRegistrar, srv CommitMessageServiceServer) { + s.RegisterService(&CommitMessageService_ServiceDesc, srv) +} + +func _CommitMessageService_GenerateCommitMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CommitMessageRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CommitMessageServiceServer).GenerateCommitMessage(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CommitMessageService_GenerateCommitMessage_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CommitMessageServiceServer).GenerateCommitMessage(ctx, req.(*CommitMessageRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CommitMessageService_ServiceDesc is the grpc.ServiceDesc for CommitMessageService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CommitMessageService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "commit_message.CommitMessageService", + HandlerType: (*CommitMessageServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GenerateCommitMessage", + Handler: _CommitMessageService_GenerateCommitMessage_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "commit_message_service.proto", +} From 399b06dbeec2f1f5c3300d3ae1a0e656964f7516 Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sat, 9 Sep 2023 17:03:58 +0900 Subject: [PATCH 20/89] =?UTF-8?q?fix:=20protobuf=E3=81=8B=E3=82=89?= =?UTF-8?q?=E3=81=AE=E8=87=AA=E5=8B=95=E7=94=9F=E6=88=90=E3=82=B3=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E3=80=81=E3=83=87?= =?UTF-8?q?=E3=82=A3=E3=83=AC=E3=82=AF=E3=83=88=E3=83=AA=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {pb => pkg/grpc}/commit_message_service.pb.go | 0 {pb => pkg/grpc}/commit_message_service_grpc.pb.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {pb => pkg/grpc}/commit_message_service.pb.go (100%) rename {pb => pkg/grpc}/commit_message_service_grpc.pb.go (100%) diff --git a/pb/commit_message_service.pb.go b/pkg/grpc/commit_message_service.pb.go similarity index 100% rename from pb/commit_message_service.pb.go rename to pkg/grpc/commit_message_service.pb.go diff --git a/pb/commit_message_service_grpc.pb.go b/pkg/grpc/commit_message_service_grpc.pb.go similarity index 100% rename from pb/commit_message_service_grpc.pb.go rename to pkg/grpc/commit_message_service_grpc.pb.go From 6296819d9d614a791d749ed70bec7355304de88b Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 17:07:16 +0900 Subject: [PATCH 21/89] =?UTF-8?q?fix:=20githubaction=E3=81=A7gomock?= =?UTF-8?q?=E3=81=AE=E3=82=A4=E3=83=B3=E3=82=B9=E3=83=88=E3=83=BC=E3=83=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0024a26..ed04421 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,10 @@ jobs: with: fetch-depth: 0 # Changelog を正しく動作させるために必要 + - name: Install GoReleaser and mockgen + run: go get github.com/golang/mock/mockgen + env: + GO111MODULE: on # Go をセットアップ - uses: actions/setup-go@v3 with: From 9a8b69c46eecee86e385b2fc8315b22b122934c3 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 9 Sep 2023 17:12:20 +0900 Subject: [PATCH 22/89] =?UTF-8?q?=F0=9F=90=9B=20Install=20goreleaser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed04421..807e3da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,11 @@ jobs: fetch-depth: 0 # Changelog を正しく動作させるために必要 - name: Install GoReleaser and mockgen - run: go get github.com/golang/mock/mockgen + run: | + wget https://github.com/goreleaser/goreleaser/releases/latest/download/goreleaser_amd64 -O /tmp/goreleaser + chmod +x /tmp/goreleaser + sudo mv /tmp/goreleaser /usr/local/bin/goreleaser + go get github.com/golang/mock/mockgen env: GO111MODULE: on # Go をセットアップ From 294138d150c1695ba3207e58ab4964a5487ba1cc Mon Sep 17 00:00:00 2001 From: Akira_0809 <102137735+Akira0809@users.noreply.github.com> Date: Sat, 9 Sep 2023 17:51:22 +0900 Subject: [PATCH 23/89] wip --- cmd/config.go | 27 ++++++++++----------------- cmd/docs.go | 6 +----- cmd/suggest.go | 17 ++++++----------- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index 6da51ad..1f949d3 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -120,17 +120,14 @@ func (cm configModel) View() string { switch cm.configKeySelected { // 設定項目を選んでいない時 case false: - white := color.New(color.FgWhite).SprintFunc() - b.WriteString(white("設定項目を選んでください:\n")) - b.WriteString(white(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) + b.WriteString(color.WhiteString("設定項目を選んでください:\n")) + b.WriteString(color.WhiteString(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) for i, choice := range configKey { - cyan := color.New(color.FgCyan).SprintFunc() - hiCyan := color.New(color.FgHiCyan).SprintFunc() if i == cm.configKeyIndex { - b.WriteString(fmt.Sprintf(hiCyan("➡️ %s\n"), choice)) + b.WriteString(fmt.Sprintf(color.HiCyanString("➡️ %s\n"), choice)) } else { - b.WriteString(fmt.Sprintf(cyan(" %s\n"), choice)) + b.WriteString(fmt.Sprintf(color.CyanString(" %s\n"), choice)) } } @@ -139,26 +136,22 @@ func (cm configModel) View() string { // 選択肢のない項目はテキストエリアを表示 switch len(configOption[cm.configKeyIndex]) { case 0: - white := color.New(color.FgWhite).SprintFunc() - b.WriteString(white(fmt.Sprintf( + b.WriteString(color.WhiteString(fmt.Sprintf( "ここに%sを入力: %s\n", configKey[cm.configKeyIndex], cm.textInput.View(), ))) - b.WriteString(white(" Enterキーで確定")) + b.WriteString(color.WhiteString(" Enterキーで確定")) default: - white := color.New(color.FgWhite).SprintFunc() - b.WriteString(white("設定内容を選んでください:\n")) - b.WriteString(white(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) + b.WriteString(color.WhiteString("設定内容を選んでください:\n")) + b.WriteString(color.WhiteString(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) for i, option := range configOption[cm.configKeyIndex] { - cyan := color.New(color.FgCyan).SprintFunc() - hiCyan := color.New(color.FgHiCyan).SprintFunc() if i == cm.configOptionIndex { - b.WriteString(fmt.Sprintf(hiCyan("➡️ %s\n"), option)) + b.WriteString(fmt.Sprintf(color.HiCyanString("➡️ %s\n"), option)) } else { - b.WriteString(fmt.Sprintf(cyan(" %s\n"), option)) + b.WriteString(fmt.Sprintf(color.CyanString(" %s\n"), option)) } } } diff --git a/cmd/docs.go b/cmd/docs.go index d7e40f9..4fe1125 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -4,8 +4,6 @@ Copyright © 2023 NAME HERE package cmd import ( - "fmt" - "github.com/cocoide/commitify/static" "github.com/fatih/color" "github.com/spf13/cobra" @@ -17,9 +15,7 @@ var docsCmd = &cobra.Command{ Short: "Document of commitify", Run: func(cmd *cobra.Command, args []string) { b, _ := static.Logo.ReadFile("logo.txt") - cyan := color.New(color.FgCyan).SprintFunc() - logo := cyan(string(b)) - fmt.Println(logo) + color.Cyan(string(b)) }, } diff --git a/cmd/suggest.go b/cmd/suggest.go index b1dac8c..a471aa7 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -76,28 +76,23 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m model) View() string { if m.errorMsg != "" { - red := color.New(color.FgRed).SprintFunc() - return fmt.Sprintf(red(m.errorMsg)) + return color.RedString(m.errorMsg) } if m.isLoading { return "🌎 Generating commit messages ..." } var b strings.Builder if m.errorMsg != "" { - red := color.New(color.FgRed).SprintFunc() - b.WriteString(red(m.errorMsg) + "\n\n") + b.WriteString(color.RedString(m.errorMsg) + "\n\n") } - white := color.New(color.FgWhite).SprintFunc() - b.WriteString(white("🍕Please select an option:")) - b.WriteString(white("\n Use arrow ↑↓ to navigate and press Enter to select.\n\n")) + b.WriteString(color.WhiteString("🍕Please select an option:")) + b.WriteString(color.WhiteString("\n Use arrow ↑↓ to navigate and press Enter to select.\n\n")) for i, choice := range m.choices { - cyan := color.New(color.FgCyan).SprintFunc() - hiCyan := color.New(color.FgHiCyan).SprintFunc() if i == m.currentIdx { - b.WriteString(fmt.Sprintf(hiCyan("➡️ %s\n"), choice)) + b.WriteString(fmt.Sprintf(color.HiCyanString("➡️ %s\n"), choice)) } else { - b.WriteString(fmt.Sprintf(cyan(" %s\n"), choice)) + b.WriteString(fmt.Sprintf(color.CyanString(" %s\n"), choice)) } } return b.String() From 2eec2c867c598eb455c4739fcc89b216a1806e80 Mon Sep 17 00:00:00 2001 From: Akira_0809 <102137735+Akira0809@users.noreply.github.com> Date: Sat, 9 Sep 2023 18:37:23 +0900 Subject: [PATCH 24/89] loading --- cmd/example.go | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd/suggest.go | 32 +++++++++------ go.mod | 4 +- go.sum | 4 ++ 4 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 cmd/example.go diff --git a/cmd/example.go b/cmd/example.go new file mode 100644 index 0000000..a7f2c03 --- /dev/null +++ b/cmd/example.go @@ -0,0 +1,107 @@ +package cmd + +import ( + "fmt" + + "github.com/charmbracelet/bubbles/spinner" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/spf13/cobra" + +) + +var ( + // Available spinners + spinners = []spinner.Spinner{ + spinner.Line, + spinner.Dot, + spinner.MiniDot, + spinner.Jump, + spinner.Pulse, + spinner.Points, + spinner.Globe, + spinner.Moon, + spinner.Monkey, + } + + textStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("252")).Render + spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) + helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render +) + +type exampleModel struct { + index int + spinner spinner.Model +} + +func (m exampleModel) Init() tea.Cmd { + return m.spinner.Tick +} + +func (m exampleModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "ctrl+c", "q", "esc": + return m, tea.Quit + case "h", "left": + m.index-- + if m.index < 0 { + m.index = len(spinners) - 1 + } + m.resetSpinner() + return m, m.spinner.Tick + case "l", "right": + m.index++ + if m.index >= len(spinners) { + m.index = 0 + } + m.resetSpinner() + return m, m.spinner.Tick + default: + return m, nil + } + case spinner.TickMsg: + var cmd tea.Cmd + m.spinner, cmd = m.spinner.Update(msg) + return m, cmd + default: + return m, nil + } +} + +func (m *exampleModel) resetSpinner() { + m.spinner = spinner.New() + m.spinner.Style = spinnerStyle + m.spinner.Spinner = spinners[m.index] +} + +func (m exampleModel) View() (s string) { + var gap string + switch m.index { + case 1: + gap = "" + default: + gap = " " + } + + s += fmt.Sprintf("\n %s%s%s\n\n", m.spinner.View(), gap, textStyle("Spinning...")) + s += helpStyle("h/l, ←/→: change spinner • q: exit\n") + return +} + +var exampleCmd = &cobra.Command{ + Use: "ex", + Short: "Suggestion of commit message for staging repository", + Aliases: []string{"e", "exx"}, + Run: func(cmd *cobra.Command, args []string) { + m := exampleModel{} + m.resetSpinner() + p := tea.NewProgram(m) + p.Run() + }, +} + +func init() { + rootCmd.AddCommand(exampleCmd) +} diff --git a/cmd/suggest.go b/cmd/suggest.go index 26517a8..3d7b752 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" "github.com/cocoide/commitify/internal/gateway" "github.com/cocoide/commitify/internal/service" @@ -14,12 +15,13 @@ import ( ) type model struct { - choices []string - currentIdx int - errorMsg string - isLoading bool + choices []string + currentIdx int + errorMsg string + isLoading bool animationIdx int - messages []string + messages []string + spinner spinner.Model } type generateMessages struct { @@ -71,23 +73,28 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyCtrlC, tea.KeyEsc: return m, tea.Quit } - case tea.Cmd: - if m.isLoading { - m.animationIdx = (m.animationIdx + 1) % 3 - } + case spinner.TickMsg: + var cmd tea.Cmd + m.spinner, cmd = m.spinner.Update(msg) + return m, cmd } return m, nil } +func (m *model) resetSpinner() { + m.spinner = spinner.New() + m.spinner.Style = spinnerStyle + m.spinner.Spinner = spinner.Globe +} + func (m model) View() string { if m.errorMsg != "" { red := color.New(color.FgRed).SprintFunc() return fmt.Sprintf(red(m.errorMsg)) } if m.isLoading { - AnimationEarth := []string{"🌎","🌍","🌏"} - AnimationPoint := []string{".","..","..."} - return fmt.Sprintf("%s Generating commit messages %s", AnimationEarth[m.animationIdx], AnimationPoint[m.animationIdx]) + s := fmt.Sprintf("\n %s %s\n\n", m.spinner.View(), textStyle("Generating commit messages...")) + return s } var b strings.Builder if m.errorMsg != "" { @@ -116,6 +123,7 @@ var suggestCmd = &cobra.Command{ Aliases: []string{"s", "suggest"}, Run: func(cmd *cobra.Command, args []string) { m := model{isLoading: true} + m.resetSpinner() p := tea.NewProgram(m) p.Run() }, diff --git a/go.mod b/go.mod index 5c207dc..9af7324 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,9 @@ module github.com/cocoide/commitify go 1.19 require ( + github.com/charmbracelet/bubbles v0.16.1 github.com/charmbracelet/bubbletea v0.24.2 + github.com/charmbracelet/lipgloss v0.7.1 github.com/fatih/color v1.15.0 github.com/joho/godotenv v1.5.1 github.com/sashabaranov/go-openai v1.15.1 @@ -31,7 +33,6 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-localereader v0.0.1 // indirect @@ -41,7 +42,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 - github.com/spf13/pflag v1.0.5 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.6.0 // indirect diff --git a/go.sum b/go.sum index 8ad886b..cd80fa2 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,12 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= +github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= +github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= +github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= From 2bbc39e5c01d68ed1d1b67413325576d4d6451cd Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 03:07:49 +0900 Subject: [PATCH 25/89] =?UTF-8?q?feat:=20grpc=E3=82=B5=E3=83=BC=E3=83=90?= =?UTF-8?q?=E3=81=B8=E3=81=AE=E6=8E=A5=E7=B6=9A=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 53 ++++++++---------- go.mod | 16 +++--- go.sum | 32 +++++------ internal/gateway/grpc_serve.go | 70 +++++++++++++++++++++++ internal/service/file_diff_service.go | 17 ++++++ internal/service/message.go | 78 +++++++++++++------------- internal/service/message_test.go | 80 +++++++++++++-------------- 7 files changed, 213 insertions(+), 133 deletions(-) create mode 100644 internal/gateway/grpc_serve.go create mode 100644 internal/service/file_diff_service.go diff --git a/cmd/suggest.go b/cmd/suggest.go index b1dac8c..e85ea42 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -1,13 +1,13 @@ package cmd import ( - "context" "fmt" + "log" + "os" "strings" tea "github.com/charmbracelet/bubbletea" "github.com/cocoide/commitify/internal/gateway" - "github.com/cocoide/commitify/internal/service" "github.com/cocoide/commitify/util" "github.com/fatih/color" "github.com/spf13/cobra" @@ -18,39 +18,32 @@ type model struct { currentIdx int errorMsg string isLoading bool - messages []string } -type generateMessages struct { - messages []string - errorMsg string -} +func (m *model) Init() tea.Cmd { + // 本当はこう書きたい。今は一旦全てgrpcサーバに呼び出し + // switch conf.endpoint { + // case openai: + // ~~~ + // case grpc_serve: + // ~~~ + // } + // var gateway gatewayInterface -func (m model) Init() tea.Cmd { - return func() tea.Msg { - ctx := context.Background() - og := gateway.NewOpenAIGateway(ctx) - ms := service.NewMessageService(og) - stagingCode := util.ExecGetStagingCode() - messages, err := ms.GenerateCommitMessage(stagingCode) - if err != nil { - return generateMessages{errorMsg: "メッセージの生成に失敗: " + err.Error()} - } - return generateMessages{messages: messages} + gsg := gateway.NewGrpcServeGateway() + messages, err := gsg.FetchCommitMessages() + if err != nil { + log.Fatal("コミットメッセージの生成に失敗: ", err) + os.Exit(-1) } + m.choices = messages + m.isLoading = false + + return nil } -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { - case generateMessages: - if msg.errorMsg != "" { - m.errorMsg = msg.errorMsg - m.isLoading = false - return m, nil - } - m.choices = msg.messages - m.isLoading = false - return m, nil case tea.KeyMsg: switch msg.Type { case tea.KeyUp: @@ -74,7 +67,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } -func (m model) View() string { +func (m *model) View() string { if m.errorMsg != "" { red := color.New(color.FgRed).SprintFunc() return fmt.Sprintf(red(m.errorMsg)) @@ -109,7 +102,7 @@ var suggestCmd = &cobra.Command{ Aliases: []string{"s", "suggest"}, Run: func(cmd *cobra.Command, args []string) { m := model{isLoading: true} - p := tea.NewProgram(m) + p := tea.NewProgram(&m) p.Run() }, } diff --git a/go.mod b/go.mod index 3ec8675..9167c14 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ require ( github.com/sashabaranov/go-openai v1.15.1 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 - google.golang.org/grpc v1.55.0 - google.golang.org/protobuf v1.30.0 + google.golang.org/grpc v1.58.0 + google.golang.org/protobuf v1.31.0 ) require ( @@ -46,10 +46,10 @@ 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.10.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // 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 + golang.org/x/text v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect ) diff --git a/go.sum b/go.sum index 124cadd..900e963 100644 --- a/go.sum +++ b/go.sum @@ -299,8 +299,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -320,8 +320,8 @@ 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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/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= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -361,11 +361,11 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -374,8 +374,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -492,8 +492,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -510,8 +510,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o= +google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -524,8 +524,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/gateway/grpc_serve.go b/internal/gateway/grpc_serve.go new file mode 100644 index 0000000..379971a --- /dev/null +++ b/internal/gateway/grpc_serve.go @@ -0,0 +1,70 @@ +package gateway + +import ( + "context" + "crypto/tls" + "log" + "os" + + "github.com/cocoide/commitify/internal/service" + 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() ([]string, error) { + // 設定情報からOpenAIへのアクセス方法の変更 + // if conf, err := util.ReadConfig(); err != nil { + // fmt.Printf("設定ファイルが開けません: %v", err) + // } + + fds := service.NewFileDiffService() + + diffStr, err := fds.CreateFileDiffStr() + if err != nil { + log.Fatal("差分の取得に失敗: ", err) + return nil, err + } + + req := &pb.CommitMessageRequest{ + InputCode: diffStr, + CodeFormat: pb.CodeFormatType_PREFIX, + Language: pb.LanguageType_ENGLISH, + } + + 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/service/file_diff_service.go b/internal/service/file_diff_service.go new file mode 100644 index 0000000..c171a90 --- /dev/null +++ b/internal/service/file_diff_service.go @@ -0,0 +1,17 @@ +package service + +import "os/exec" + +type fileDiffService struct { +} + +func NewFileDiffService() *fileDiffService { + ps := new(fileDiffService) + return ps +} + +func (ps 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 index bfc234f..c84bb83 100644 --- a/internal/service/message.go +++ b/internal/service/message.go @@ -1,41 +1,41 @@ 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 -} +// 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 index e94b913..bd6a82c 100644 --- a/internal/service/message_test.go +++ b/internal/service/message_test.go @@ -1,46 +1,46 @@ package service_test -import ( - "fmt" - "reflect" - "testing" +// import ( +// "fmt" +// "reflect" +// "testing" - "github.com/cocoide/commitify/internal/service" - mock_gateway "github.com/cocoide/commitify/mock" - "github.com/golang/mock/gomock" -) +// "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) +// 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) +// 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) - } - } -} +// 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) +// } +// } +// } From 7ce15a06da3007f1b4621184b8f66f1c65bdaf4d Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 09:12:56 +0900 Subject: [PATCH 26/89] =?UTF-8?q?feat:=20=E8=A8=AD=E5=AE=9A=E6=83=85?= =?UTF-8?q?=E5=A0=B1=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=82=92entity=E5=B1=A4=E3=81=AB=E7=A7=BB?= =?UTF-8?q?=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config.go | 6 ++--- internal/entity/config.go | 44 ++++++++++++++++++++++++++++++++ internal/gateway/grpc_serve.go | 2 +- internal/gateway/openai.go | 4 +-- util/config.go | 46 ---------------------------------- 5 files changed, 50 insertions(+), 52 deletions(-) delete mode 100644 util/config.go diff --git a/cmd/config.go b/cmd/config.go index 6da51ad..b59611a 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -6,7 +6,7 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" - "github.com/cocoide/commitify/util" + "github.com/cocoide/commitify/internal/entity" "github.com/fatih/color" "github.com/spf13/cobra" ) @@ -182,7 +182,7 @@ func init() { } func saveConfig(cm configModel) { - currentConfig, err := util.ReadConfig() + currentConfig, err := entity.ReadConfig() if err != nil { fmt.Println(err) } @@ -196,7 +196,7 @@ func saveConfig(cm configModel) { currentConfig.CommitFormat = configOption[cm.configKeyIndex][cm.configOptionIndex] } - err = util.WriteConfig(currentConfig) + err = entity.WriteConfig(currentConfig) if err != nil { fmt.Println(err) } diff --git a/internal/entity/config.go b/internal/entity/config.go index 226ac5a..e04dfc4 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -1,7 +1,51 @@ package entity +import ( + "encoding/json" + "fmt" + + "github.com/spf13/viper" +) + type Config struct { ChatGptApiKey string `json:"chatGptApiKey"` UseLanguage string `json:"UseLanguage"` CommitFormat string `json:"CommitFormat"` } + +func ReadConfig() (*Config, error) { + var result Config + + viper.AddConfigPath(".") + viper.SetConfigName("config") + viper.SetConfigType("yaml") + if err := viper.ReadInConfig(); err != nil { + return &result, fmt.Errorf("error reading config file, %s", err.Error()) + } + if err := viper.Unmarshal(&result); err != nil { + return &result, fmt.Errorf("unable to decode into struct, %v", err.Error()) + } + return &result, nil +} + +func WriteConfig(config *Config) error { + viper.AddConfigPath(".") + viper.SetConfigName("config") + viper.SetConfigType("yaml") + configMap := make(map[string]interface{}) + configBytes, err := json.Marshal(config) + if err != nil { + return fmt.Errorf("error marshalling config: %s", err.Error()) + } + err = json.Unmarshal(configBytes, &configMap) + if err != nil { + return fmt.Errorf("error unmarshalling config: %s", err.Error()) + } + if err := viper.MergeConfigMap(configMap); err != nil { + return err + } + if err := viper.WriteConfig(); err != nil { + return fmt.Errorf("error saving config file, %s", err.Error()) + } + return nil +} diff --git a/internal/gateway/grpc_serve.go b/internal/gateway/grpc_serve.go index 379971a..c23c8ef 100644 --- a/internal/gateway/grpc_serve.go +++ b/internal/gateway/grpc_serve.go @@ -41,7 +41,7 @@ func NewGrpcServeGateway() *grpcServeGateway { func (gsg grpcServeGateway) FetchCommitMessages() ([]string, error) { // 設定情報からOpenAIへのアクセス方法の変更 - // if conf, err := util.ReadConfig(); err != nil { + // if conf, err := entity.ReadConfig(); err != nil { // fmt.Printf("設定ファイルが開けません: %v", err) // } diff --git a/internal/gateway/openai.go b/internal/gateway/openai.go index 18df70c..8bf17df 100644 --- a/internal/gateway/openai.go +++ b/internal/gateway/openai.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/cocoide/commitify/util" + "github.com/cocoide/commitify/internal/entity" "github.com/sashabaranov/go-openai" ) @@ -20,7 +20,7 @@ type openAIGateway struct { } func NewOpenAIGateway(ctx context.Context) OpenAIGateway { - config, err := util.ReadConfig() + config, err := entity.ReadConfig() if err != nil { log.Fatalf("Failed to read config: %v", err) } diff --git a/util/config.go b/util/config.go deleted file mode 100644 index ba9e8ca..0000000 --- a/util/config.go +++ /dev/null @@ -1,46 +0,0 @@ -package util - -import ( - "encoding/json" - "fmt" - - "github.com/cocoide/commitify/internal/entity" - "github.com/spf13/viper" -) - -func ReadConfig() (*entity.Config, error) { - var result entity.Config - - viper.AddConfigPath(".") - viper.SetConfigName("config") - viper.SetConfigType("yaml") - if err := viper.ReadInConfig(); err != nil { - return &result, fmt.Errorf("error reading config file, %s", err.Error()) - } - if err := viper.Unmarshal(&result); err != nil { - return &result, fmt.Errorf("unable to decode into struct, %v", err.Error()) - } - return &result, nil -} - -func WriteConfig(config *entity.Config) error { - viper.AddConfigPath(".") - viper.SetConfigName("config") - viper.SetConfigType("yaml") - configMap := make(map[string]interface{}) - configBytes, err := json.Marshal(config) - if err != nil { - return fmt.Errorf("error marshalling config: %s", err.Error()) - } - err = json.Unmarshal(configBytes, &configMap) - if err != nil { - return fmt.Errorf("error unmarshalling config: %s", err.Error()) - } - if err := viper.MergeConfigMap(configMap); err != nil { - return err - } - if err := viper.WriteConfig(); err != nil { - return fmt.Errorf("error saving config file, %s", err.Error()) - } - return nil -} From 58b57ddb1bf036d118840cc466174ef582c1747e Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 09:53:48 +0900 Subject: [PATCH 27/89] =?UTF-8?q?fix:=20config=E3=82=92=E5=88=97=E6=8C=99?= =?UTF-8?q?=E5=9E=8B=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config.go | 17 ++++++++--- internal/entity/config.go | 62 ++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index b59611a..4000817 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -12,11 +12,18 @@ import ( ) var ( - configKey = [...]string{"api-key", "language", "format"} - configOption = [][]string{ + configKey = [...]string{"api-key", "language", "format", "ai-source"} + configOption = [][]int{ + {}, + {int(entity.JP), int(entity.EN)}, + {int(entity.NormalFormat), int(entity.EmojiFormat), int(entity.PrefixFormat)}, + {int(entity.WrapServer), int(entity.OpenAiAPI)}, + } + configOptionLabel = [][]string{ {}, {"Japanese", "English"}, - {"Format 1", "Format 2"}, + {"Normal Format", "Emoji Format", "PrefixFormat"}, + {"Wrap Server", "OpenAI API"}, } ) @@ -152,7 +159,7 @@ func (cm configModel) View() string { b.WriteString(white("設定内容を選んでください:\n")) b.WriteString(white(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) - for i, option := range configOption[cm.configKeyIndex] { + for i, option := range configOptionLabel[cm.configKeyIndex] { cyan := color.New(color.FgCyan).SprintFunc() hiCyan := color.New(color.FgHiCyan).SprintFunc() if i == cm.configOptionIndex { @@ -194,6 +201,8 @@ func saveConfig(cm configModel) { currentConfig.UseLanguage = configOption[cm.configKeyIndex][cm.configOptionIndex] case 2: currentConfig.CommitFormat = configOption[cm.configKeyIndex][cm.configOptionIndex] + case 3: + currentConfig.AISource = configOption[cm.configKeyIndex][cm.configOptionIndex] } err = entity.WriteConfig(currentConfig) diff --git a/internal/entity/config.go b/internal/entity/config.go index e04dfc4..69c071f 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -4,31 +4,77 @@ import ( "encoding/json" "fmt" + pb "github.com/cocoide/commitify/pkg/grpc" "github.com/spf13/viper" ) +type Language int + +const ( + JP Language = iota + EN +) + +type CodeFormat int + +const ( + EmojiFormat CodeFormat = iota + PrefixFormat + NormalFormat +) + +type AISource int + +const ( + WrapServer AISource = iota + OpenAiAPI +) + type Config struct { - ChatGptApiKey string `json:"chatGptApiKey"` - UseLanguage string `json:"UseLanguage"` - CommitFormat string `json:"CommitFormat"` + ChatGptApiKey string `json:"chatGpt_ApiKey"` + UseLanguage int `json:"Use_Language"` + CommitFormat int `json:"Commit_Format"` + AISource int `json:"AI_Source"` +} + +func (c *Config) Config2PbVars() (pb.CodeFormatType, pb.LanguageType) { + var codeFormatType pb.CodeFormatType + switch c.CommitFormat { + case int(EmojiFormat): + codeFormatType = pb.CodeFormatType_EMOJI + case int(PrefixFormat): + codeFormatType = pb.CodeFormatType_PREFIX + default: + codeFormatType = pb.CodeFormatType_NORMAL + } + + var languageType pb.LanguageType + switch c.UseLanguage { + case int(JP): + languageType = pb.LanguageType_JAPANESE + default: + languageType = pb.LanguageType_JAPANESE + } + + return codeFormatType, languageType } -func ReadConfig() (*Config, error) { +func ReadConfig() (Config, error) { var result Config viper.AddConfigPath(".") viper.SetConfigName("config") viper.SetConfigType("yaml") if err := viper.ReadInConfig(); err != nil { - return &result, fmt.Errorf("error reading config file, %s", err.Error()) + return result, fmt.Errorf("error reading config file, %s", err.Error()) } if err := viper.Unmarshal(&result); err != nil { - return &result, fmt.Errorf("unable to decode into struct, %v", err.Error()) + return result, fmt.Errorf("unable to decode into struct, %v", err.Error()) } - return &result, nil + return result, nil } -func WriteConfig(config *Config) error { +func WriteConfig(config Config) error { viper.AddConfigPath(".") viper.SetConfigName("config") viper.SetConfigType("yaml") From 91ded33f44d963b8d602324a559ee7d72d2efba2 Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 09:54:12 +0900 Subject: [PATCH 28/89] =?UTF-8?q?feat:=20gRPC=E3=81=AE=E5=91=BC=E3=81=B3?= =?UTF-8?q?=E5=87=BA=E3=81=97=E3=81=AB=E3=80=81=E8=A8=AD=E5=AE=9A=E6=83=85?= =?UTF-8?q?=E5=A0=B1=E3=82=92=E5=8F=8D=E6=98=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gateway/grpc_serve.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/gateway/grpc_serve.go b/internal/gateway/grpc_serve.go index c23c8ef..b76bdd2 100644 --- a/internal/gateway/grpc_serve.go +++ b/internal/gateway/grpc_serve.go @@ -3,9 +3,11 @@ package gateway import ( "context" "crypto/tls" + "fmt" "log" "os" + "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/service" pb "github.com/cocoide/commitify/pkg/grpc" "google.golang.org/grpc" @@ -40,10 +42,12 @@ func NewGrpcServeGateway() *grpcServeGateway { } func (gsg grpcServeGateway) FetchCommitMessages() ([]string, error) { - // 設定情報からOpenAIへのアクセス方法の変更 - // if conf, err := entity.ReadConfig(); err != nil { - // fmt.Printf("設定ファイルが開けません: %v", err) - // } + // 設定情報を取得 + conf, err := entity.ReadConfig() + if err != nil { + fmt.Printf("設定ファイルが開けません: %v", err) + } + cft, lt := conf.Config2PbVars() fds := service.NewFileDiffService() @@ -55,8 +59,8 @@ func (gsg grpcServeGateway) FetchCommitMessages() ([]string, error) { req := &pb.CommitMessageRequest{ InputCode: diffStr, - CodeFormat: pb.CodeFormatType_PREFIX, - Language: pb.LanguageType_ENGLISH, + CodeFormat: cft, + Language: lt, } res, err := gsg.client.GenerateCommitMessage(context.Background(), req) From d6ef59d26e9091c98e2628019f19c572415457dd Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 09:58:59 +0900 Subject: [PATCH 29/89] =?UTF-8?q?feat:=20AI=E3=81=AE=E3=83=AA=E3=82=BD?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=82=92=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88?= =?UTF-8?q?=E3=82=89=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *今はgRPCのサーバのみ実装 --- cmd/suggest.go | 24 ++++++++++++++---------- internal/gateway/gateway_interface.go | 5 +++++ 2 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 internal/gateway/gateway_interface.go diff --git a/cmd/suggest.go b/cmd/suggest.go index e85ea42..53371be 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -7,6 +7,7 @@ import ( "strings" tea "github.com/charmbracelet/bubbletea" + "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/gateway" "github.com/cocoide/commitify/util" "github.com/fatih/color" @@ -21,17 +22,20 @@ type model struct { } func (m *model) Init() tea.Cmd { - // 本当はこう書きたい。今は一旦全てgrpcサーバに呼び出し - // switch conf.endpoint { - // case openai: - // ~~~ - // case grpc_serve: - // ~~~ - // } - // var gateway gatewayInterface + conf, err := entity.ReadConfig() + if err != nil { + log.Fatal("設定情報の取得に失敗: ", err) + } + + var gi gateway.GatewayInterface + switch conf.AISource { + case int(entity.WrapServer): + gi = gateway.NewGrpcServeGateway() + default: + gi = gateway.NewGrpcServeGateway() + } - gsg := gateway.NewGrpcServeGateway() - messages, err := gsg.FetchCommitMessages() + messages, err := gi.FetchCommitMessages() if err != nil { log.Fatal("コミットメッセージの生成に失敗: ", err) os.Exit(-1) diff --git a/internal/gateway/gateway_interface.go b/internal/gateway/gateway_interface.go new file mode 100644 index 0000000..8d2f8fd --- /dev/null +++ b/internal/gateway/gateway_interface.go @@ -0,0 +1,5 @@ +package gateway + +type GatewayInterface interface { + FetchCommitMessages() ([]string, error) +} From 6e73618686492f470eaa5fea617290d4cfd005f2 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Sep 2023 11:04:12 +0900 Subject: [PATCH 30/89] =?UTF-8?q?=F0=9F=90=9B=20Delete=20mockgen=20logic?= =?UTF-8?q?=20for=20CI/CD=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 8 -------- Makefile | 1 - internal/gateway/openai.go | 1 - 3 files changed, 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 807e3da..0024a26 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,14 +15,6 @@ jobs: with: fetch-depth: 0 # Changelog を正しく動作させるために必要 - - name: Install GoReleaser and mockgen - run: | - wget https://github.com/goreleaser/goreleaser/releases/latest/download/goreleaser_amd64 -O /tmp/goreleaser - chmod +x /tmp/goreleaser - sudo mv /tmp/goreleaser /usr/local/bin/goreleaser - go get github.com/golang/mock/mockgen - env: - GO111MODULE: on # Go をセットアップ - uses: actions/setup-go@v3 with: diff --git a/Makefile b/Makefile index 9846501..c407b7e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,4 @@ .PHONY: test test: - go generate ./... go test -v ./internal/service \ No newline at end of file diff --git a/internal/gateway/openai.go b/internal/gateway/openai.go index 18df70c..d86d304 100644 --- a/internal/gateway/openai.go +++ b/internal/gateway/openai.go @@ -8,7 +8,6 @@ import ( "github.com/sashabaranov/go-openai" ) -//go:generate mockgen -source=openai.go -destination=../../mock/openai.go type OpenAIGateway interface { GetAnswerFromPrompt(prompt string, variability float32) (string, error) AsyncGetAnswerFromPrompt(prompt string, variability float32) <-chan string From 3bb264d894eeb68693f489708e8127eb6b9cf24e Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 11:18:40 +0900 Subject: [PATCH 31/89] =?UTF-8?q?fix:=20config=E3=81=AE=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jsonのkeyとしてアンダースコアを用いていると、うまくデコードできないもよう。 --- cmd/config.go | 4 ++-- internal/entity/config.go | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index 4000817..020b69f 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -15,13 +15,13 @@ var ( configKey = [...]string{"api-key", "language", "format", "ai-source"} configOption = [][]int{ {}, - {int(entity.JP), int(entity.EN)}, + {int(entity.EN), int(entity.JP)}, {int(entity.NormalFormat), int(entity.EmojiFormat), int(entity.PrefixFormat)}, {int(entity.WrapServer), int(entity.OpenAiAPI)}, } configOptionLabel = [][]string{ {}, - {"Japanese", "English"}, + {"English", "Japanese"}, {"Normal Format", "Emoji Format", "PrefixFormat"}, {"Wrap Server", "OpenAI API"}, } diff --git a/internal/entity/config.go b/internal/entity/config.go index 69c071f..c88b672 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -11,16 +11,16 @@ import ( type Language int const ( - JP Language = iota - EN + EN Language = iota + JP ) type CodeFormat int const ( - EmojiFormat CodeFormat = iota + NormalFormat CodeFormat = iota + EmojiFormat PrefixFormat - NormalFormat ) type AISource int @@ -31,10 +31,10 @@ const ( ) type Config struct { - ChatGptApiKey string `json:"chatGpt_ApiKey"` - UseLanguage int `json:"Use_Language"` - CommitFormat int `json:"Commit_Format"` - AISource int `json:"AI_Source"` + ChatGptApiKey string `json:"chatGptApiKey"` + UseLanguage int `json:"UseLanguage"` + CommitFormat int `json:"CommitFormat"` + AISource int `json:"AISource"` } func (c *Config) Config2PbVars() (pb.CodeFormatType, pb.LanguageType) { From dd1dbd315ddcbb3323cc979dac6ec5d4b8ca8141 Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 11:49:56 +0900 Subject: [PATCH 32/89] =?UTF-8?q?bugfix:=20=E3=83=9E=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=81=AE=E3=83=9F=E3=82=B9=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/config.go b/cmd/config.go index dccebbb..2386dfc 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -154,7 +154,7 @@ func (cm configModel) View() string { b.WriteString(color.WhiteString("設定内容を選んでください:\n")) b.WriteString(color.WhiteString(" ↑↓の矢印キーで項目を移動、Enterで選択\n")) - for i, option := range configOption[cm.configKeyIndex] { + for i, option := range configOptionLabel[cm.configKeyIndex] { if i == cm.configOptionIndex { b.WriteString(fmt.Sprintf(color.HiCyanString("➡️ %s\n"), option)) } else { From 1624e0f80254b2524a04d2a0ec2d36de4fdd5df0 Mon Sep 17 00:00:00 2001 From: Akira_0809 <102137735+Akira0809@users.noreply.github.com> Date: Sun, 10 Sep 2023 12:42:36 +0900 Subject: [PATCH 33/89] =?UTF-8?q?=E2=9C=A8=20"github.com/charmbracelet/bub?= =?UTF-8?q?bles/t=20"=E3=81=AEimport=E6=96=87=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index 53371be..7229ceb 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -6,6 +6,7 @@ import ( "os" "strings" + "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/gateway" @@ -19,6 +20,8 @@ type model struct { currentIdx int errorMsg string isLoading bool + isEditing bool + textInput textinput.Model } func (m *model) Init() tea.Cmd { @@ -42,14 +45,22 @@ func (m *model) Init() tea.Cmd { } m.choices = messages m.isLoading = false - - return nil + return textinput.Blink } func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + m.textInput, cmd = m.textInput.Update(msg) switch msg := msg.(type) { case tea.KeyMsg: switch msg.Type { + case tea.KeyTab: + m.isEditing = true + m.textInput.Focus() + m.textInput.SetValue(m.choices[m.currentIdx]) + m.textInput.CharLimit = 100 + m.textInput.Width = 100 + return m, cmd case tea.KeyUp: if m.currentIdx > 0 { m.currentIdx-- @@ -84,6 +95,10 @@ func (m *model) View() string { red := color.New(color.FgRed).SprintFunc() b.WriteString(red(m.errorMsg) + "\n\n") } + if m.isEditing{ + return m.textInput.View() + } + white := color.New(color.FgWhite).SprintFunc() b.WriteString(white("🍕Please select an option:")) b.WriteString(white("\n Use arrow ↑↓ to navigate and press Enter to select.\n\n")) @@ -100,12 +115,27 @@ func (m *model) View() string { return b.String() } +func initialModel() model { + ti := textinput.New() + ti.Focus() + + return model{ + choices :[]string{""}, + currentIdx :0, + errorMsg :"", + isLoading: true, + isEditing: false, + textInput: ti, + } +} + + var suggestCmd = &cobra.Command{ Use: "suggest", Short: "Suggestion of commit message for staging repository", Aliases: []string{"s", "suggest"}, Run: func(cmd *cobra.Command, args []string) { - m := model{isLoading: true} + m := initialModel() p := tea.NewProgram(&m) p.Run() }, From aac56167250a1dd3a79c65ca6cf325b1f689abb5 Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 13:52:06 +0900 Subject: [PATCH 34/89] =?UTF-8?q?feat:=20=E3=82=B3=E3=83=9F=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=AE?= =?UTF-8?q?=E7=94=9F=E6=88=90=E3=82=92=E4=B8=A6=E5=88=97=E5=8C=96=E3=81=97?= =?UTF-8?q?=E3=80=81=E3=83=AD=E3=83=BC=E3=83=87=E3=82=A3=E3=83=B3=E3=82=B0?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index 69daa6e..f7cd532 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -17,14 +17,13 @@ import ( ) type model struct { - choices []string - currentIdx int - errorMsg string - isLoading bool - animationIdx int - isEditing bool - spinner spinner.Model - textInput textinput.Model + choices []string + currentIdx int + errorMsg string + isLoading bool + isEditing bool + spinner spinner.Model + textInput textinput.Model } func (m *model) Init() tea.Cmd { @@ -41,13 +40,16 @@ func (m *model) Init() tea.Cmd { gi = gateway.NewGrpcServeGateway() } - messages, err := gi.FetchCommitMessages() - if err != nil { - log.Fatal("コミットメッセージの生成に失敗: ", err) - os.Exit(-1) - } - m.choices = messages - m.isLoading = false + go func() { + messages, err := gi.FetchCommitMessages() + if err != nil { + log.Fatal("コミットメッセージの生成に失敗: ", err) + os.Exit(-1) + } + m.choices = messages + m.isLoading = false + }() + return textinput.Blink } @@ -86,7 +88,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.spinner, cmd = m.spinner.Update(msg) return m, cmd } - return m, nil + return m, m.spinner.Tick } func (m *model) resetSpinner() { From 97ebd54ff22bfb516561b907c5aed428d8ae059d Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 13:56:56 +0900 Subject: [PATCH 35/89] =?UTF-8?q?fix:=20=E5=8B=95=E4=BD=9C=E7=A2=BA?= =?UTF-8?q?=E8=AA=8D=E7=94=A8=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/example.go | 107 ------------------------------------------------- 1 file changed, 107 deletions(-) delete mode 100644 cmd/example.go diff --git a/cmd/example.go b/cmd/example.go deleted file mode 100644 index a7f2c03..0000000 --- a/cmd/example.go +++ /dev/null @@ -1,107 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/charmbracelet/bubbles/spinner" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/spf13/cobra" - -) - -var ( - // Available spinners - spinners = []spinner.Spinner{ - spinner.Line, - spinner.Dot, - spinner.MiniDot, - spinner.Jump, - spinner.Pulse, - spinner.Points, - spinner.Globe, - spinner.Moon, - spinner.Monkey, - } - - textStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("252")).Render - spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) - helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render -) - -type exampleModel struct { - index int - spinner spinner.Model -} - -func (m exampleModel) Init() tea.Cmd { - return m.spinner.Tick -} - -func (m exampleModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "ctrl+c", "q", "esc": - return m, tea.Quit - case "h", "left": - m.index-- - if m.index < 0 { - m.index = len(spinners) - 1 - } - m.resetSpinner() - return m, m.spinner.Tick - case "l", "right": - m.index++ - if m.index >= len(spinners) { - m.index = 0 - } - m.resetSpinner() - return m, m.spinner.Tick - default: - return m, nil - } - case spinner.TickMsg: - var cmd tea.Cmd - m.spinner, cmd = m.spinner.Update(msg) - return m, cmd - default: - return m, nil - } -} - -func (m *exampleModel) resetSpinner() { - m.spinner = spinner.New() - m.spinner.Style = spinnerStyle - m.spinner.Spinner = spinners[m.index] -} - -func (m exampleModel) View() (s string) { - var gap string - switch m.index { - case 1: - gap = "" - default: - gap = " " - } - - s += fmt.Sprintf("\n %s%s%s\n\n", m.spinner.View(), gap, textStyle("Spinning...")) - s += helpStyle("h/l, ←/→: change spinner • q: exit\n") - return -} - -var exampleCmd = &cobra.Command{ - Use: "ex", - Short: "Suggestion of commit message for staging repository", - Aliases: []string{"e", "exx"}, - Run: func(cmd *cobra.Command, args []string) { - m := exampleModel{} - m.resetSpinner() - p := tea.NewProgram(m) - p.Run() - }, -} - -func init() { - rootCmd.AddCommand(exampleCmd) -} From 7b2a9eb2262f90357127e7e53445316de1a85337 Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 14:01:26 +0900 Subject: [PATCH 36/89] =?UTF-8?q?suggest.go=E3=82=92=E6=96=B0=E3=81=97?= =?UTF-8?q?=E3=81=84=E3=82=B9=E3=83=94=E3=83=8A=E3=83=BC=E3=83=BB=E3=83=91?= =?UTF-8?q?=E3=83=83=E3=82=B1=E3=83=BC=E3=82=B8=E3=81=A7=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/suggest.go b/cmd/suggest.go index f7cd532..48f11f8 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -9,6 +9,7 @@ import ( "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/gateway" "github.com/cocoide/commitify/util" @@ -16,6 +17,12 @@ import ( "github.com/spf13/cobra" ) +var ( + textStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("252")).Render + spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) + helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render +) + type model struct { choices []string currentIdx int From 6b54f44079aea086a666a53b393e421034506683 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Sep 2023 14:24:00 +0900 Subject: [PATCH 37/89] Update view --- cmd/root.go | 8 +------- cmd/version.go | 35 ----------------------------------- 2 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 cmd/version.go diff --git a/cmd/root.go b/cmd/root.go index f85848f..b8c3e55 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -8,13 +8,7 @@ import ( var rootCmd = &cobra.Command{ Use: "commitify", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, + Short: "CLI for thinking commit message", } func Execute() { diff --git a/cmd/version.go b/cmd/version.go deleted file mode 100644 index af2b3fe..0000000 --- a/cmd/version.go +++ /dev/null @@ -1,35 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -var versionCmd = &cobra.Command{ - Use: "version", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("version 0.9 -- HEAD") - }, -} - -func init() { - rootCmd.AddCommand(versionCmd) - rootCmd.Flags().BoolP("version", "v", false, "アプリのVersion") - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // versionCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -} From cf01395555baf5662c31d9caf47d05a7a28d9ada Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Sep 2023 14:55:24 +0900 Subject: [PATCH 38/89] Update view --- cmd/docs.go | 4 +++- cmd/root.go | 2 ++ cmd/suggest.go | 7 ++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cmd/docs.go b/cmd/docs.go index 4fe1125..7e34f08 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -4,6 +4,8 @@ Copyright © 2023 NAME HERE package cmd import ( + "fmt" + "github.com/cocoide/commitify/static" "github.com/fatih/color" "github.com/spf13/cobra" @@ -15,7 +17,7 @@ var docsCmd = &cobra.Command{ Short: "Document of commitify", Run: func(cmd *cobra.Command, args []string) { b, _ := static.Logo.ReadFile("logo.txt") - color.Cyan(string(b)) + fmt.Print(color.CyanString(string(b)) + "\n\n ・Languageは日本語と英語が選択できます\n\n ・CodeFormatはPrefix (例: feat: A)とEmoji (例: 🐛 Bugix), Normal (例: Feat A)が選べます") }, } diff --git a/cmd/root.go b/cmd/root.go index b8c3e55..70fd15b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,6 +9,8 @@ import ( var rootCmd = &cobra.Command{ Use: "commitify", Short: "CLI for thinking commit message", + Long: `By "commitify config" command, you can change commit message format or language, + ( To know details about format or language, enter commitify docs )`, } func Execute() { diff --git a/cmd/suggest.go b/cmd/suggest.go index 48f11f8..1ae9c60 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -109,7 +109,7 @@ func (m *model) View() string { return color.RedString(m.errorMsg) } if m.isLoading { - s := fmt.Sprintf("\n %s %s\n\n", m.spinner.View(), textStyle("Generating commit messages...")) + s := fmt.Sprintf("\n %s %s\n\n", m.spinner.View(), textStyle("コミットメッセージ生成中")) return s } var b strings.Builder @@ -120,8 +120,9 @@ func (m *model) View() string { return m.textInput.View() } - b.WriteString(color.WhiteString("🍕Please select an option:")) - b.WriteString(color.WhiteString("\n Use arrow ↑↓ to navigate and press Enter to select.\n\n")) + b.WriteString(color.WhiteString("🍕 Please select and enter to commit")) + b.WriteString(color.WhiteString("\n Use arrow ↑↓ to navigate and press Enter to select.")) + b.WriteString(color.WhiteString("\n ( enter Tab key to edit message )\n\n")) for i, choice := range m.choices { if i == m.currentIdx { From 649cb18d4d32368d8d9dea4d7820dad3118b5aba Mon Sep 17 00:00:00 2001 From: yuta mochizuki Date: Sun, 10 Sep 2023 14:55:42 +0900 Subject: [PATCH 39/89] =?UTF-8?q?fix:=20=E8=A8=AD=E5=AE=9A=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=AE=E3=83=91=E3=82=B9=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/entity/config.go | 4 ++-- main.go | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/entity/config.go b/internal/entity/config.go index c88b672..cbbfe26 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -62,7 +62,7 @@ func (c *Config) Config2PbVars() (pb.CodeFormatType, pb.LanguageType) { func ReadConfig() (Config, error) { var result Config - viper.AddConfigPath(".") + viper.AddConfigPath("$HOME/.commitify") viper.SetConfigName("config") viper.SetConfigType("yaml") if err := viper.ReadInConfig(); err != nil { @@ -75,7 +75,7 @@ func ReadConfig() (Config, error) { } func WriteConfig(config Config) error { - viper.AddConfigPath(".") + viper.AddConfigPath("$HOME/.commitify") viper.SetConfigName("config") viper.SetConfigType("yaml") configMap := make(map[string]interface{}) diff --git a/main.go b/main.go index fbd7bac..18a6557 100644 --- a/main.go +++ b/main.go @@ -9,9 +9,14 @@ import ( func main() { // configファイルがあるかどうかを確認 - _, err := os.Stat("config.yaml") + homePath := os.Getenv("HOME") + + _, err := os.Stat(homePath + "/.commitify/config.yaml") if os.IsNotExist(err) { - if _, err := os.Create("config.yaml"); err != nil { + if err := os.MkdirAll(homePath+"/.commitify", 0755); err != nil { + fmt.Printf("error of make directory, %v", err) + } + if _, err := os.Create(homePath + "/.commitify/config.yaml"); err != nil { fmt.Printf("error creating config file, %s", err.Error()) } } From 34532f4fc7657b44f40c12798e4624896cd9dbc9 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Sep 2023 15:29:05 +0900 Subject: [PATCH 40/89] =?UTF-8?q?suggest.go=E3=81=A7=E3=83=A1=E3=83=83?= =?UTF-8?q?=E3=82=BB=E3=83=BC=E3=82=B8=E5=87=A6=E7=90=86=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/suggest.go b/cmd/suggest.go index 1ae9c60..8bc7cc8 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -77,6 +77,10 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if m.currentIdx > 0 { m.currentIdx-- } + case tea.KeyLeft: + if m.currentIdx > 0 { + m.currentIdx-- + } case tea.KeyDown: if m.currentIdx < len(m.choices)-1 { m.currentIdx++ From 29e7cc4c1fe49573b9cb38edb8565d32353c564a Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Sep 2023 22:50:03 +0900 Subject: [PATCH 41/89] Fix unexpected commit --- cmd/suggest.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index 8bc7cc8..1ae9c60 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -77,10 +77,6 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if m.currentIdx > 0 { m.currentIdx-- } - case tea.KeyLeft: - if m.currentIdx > 0 { - m.currentIdx-- - } case tea.KeyDown: if m.currentIdx < len(m.choices)-1 { m.currentIdx++ From cc99bd9d149560df26cadd5f203032f7a0ae52d7 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 15:14:50 +0900 Subject: [PATCH 42/89] =?UTF-8?q?refactor:=20doc=E3=82=B3=E3=83=9E?= =?UTF-8?q?=E3=83=B3=E3=83=89=E3=81=AE=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92?= =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/docs.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/docs.go b/cmd/docs.go index 7e34f08..09fb5f4 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -17,7 +17,9 @@ var docsCmd = &cobra.Command{ Short: "Document of commitify", Run: func(cmd *cobra.Command, args []string) { b, _ := static.Logo.ReadFile("logo.txt") - fmt.Print(color.CyanString(string(b)) + "\n\n ・Languageは日本語と英語が選択できます\n\n ・CodeFormatはPrefix (例: feat: A)とEmoji (例: 🐛 Bugix), Normal (例: Feat A)が選べます") + fmt.Println(color.CyanString(string(b))) + fmt.Println("\n ・Languageは日本語と英語が選択できます") + fmt.Println(" ・CodeFormatはPrefix (例: feat: A)とEmoji (例: 🐛 Bugix), Normal (例: Feat A)が選べます") }, } From a833572e9f1cdc6fbc48da780bf87818b3641bd3 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 16:53:03 +0900 Subject: [PATCH 43/89] =?UTF-8?q?refactor:=20=E8=A8=AD=E5=AE=9A=E3=81=AE?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=87=A6=E7=90=86=E3=82=92=E3=80=81=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E6=A9=9F=E8=83=BD=E3=81=8B=E3=82=89=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config.go | 42 ++++++++++----------------------------- internal/entity/config.go | 25 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index 2386dfc..e4c03f0 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -6,9 +6,10 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" - "github.com/cocoide/commitify/internal/entity" "github.com/fatih/color" "github.com/spf13/cobra" + + "github.com/cocoide/commitify/internal/entity" ) var ( @@ -27,7 +28,7 @@ var ( } ) -type configModel struct { +type configCmdModel struct { configKeyIndex int configOptionIndex int configKeySelected bool @@ -35,21 +36,21 @@ type configModel struct { textInput textinput.Model } -func initConfigModel() configModel { +func initConfigModel() configCmdModel { ti := textinput.New() ti.Focus() - return configModel{ + return configCmdModel{ textInput: ti, err: nil, } } -func (cm configModel) Init() tea.Cmd { +func (cm configCmdModel) Init() tea.Cmd { return textinput.Blink } -func (cm configModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (cm configCmdModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch cm.configKeySelected { // 設定項目を選択する case false: @@ -82,7 +83,7 @@ func (cm configModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyMsg: switch msg.Type { case tea.KeyEnter: - saveConfig(cm) + entity.SaveConfig(cm.configKeyIndex, -1, cm.textInput.Value()) return cm, tea.Quit case tea.KeyCtrlC, tea.KeyEsc: return cm, tea.Quit @@ -109,7 +110,7 @@ func (cm configModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { cm.configOptionIndex++ } case tea.KeyEnter: - saveConfig(cm) + entity.SaveConfig(cm.configKeyIndex, configOption[cm.configKeyIndex][cm.configOptionIndex], "") return cm, tea.Quit case tea.KeyCtrlC, tea.KeyEsc: return cm, tea.Quit @@ -121,7 +122,7 @@ func (cm configModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return cm, nil } -func (cm configModel) View() string { +func (cm configCmdModel) View() string { var b strings.Builder switch cm.configKeySelected { @@ -180,26 +181,3 @@ var configCmd = &cobra.Command{ func init() { rootCmd.AddCommand(configCmd) } - -func saveConfig(cm configModel) { - currentConfig, err := entity.ReadConfig() - if err != nil { - fmt.Println(err) - } - - switch cm.configKeyIndex { - case 0: - currentConfig.ChatGptApiKey = cm.textInput.Value() - case 1: - currentConfig.UseLanguage = configOption[cm.configKeyIndex][cm.configOptionIndex] - case 2: - currentConfig.CommitFormat = configOption[cm.configKeyIndex][cm.configOptionIndex] - case 3: - currentConfig.AISource = configOption[cm.configKeyIndex][cm.configOptionIndex] - } - - err = entity.WriteConfig(currentConfig) - if err != nil { - fmt.Println(err) - } -} diff --git a/internal/entity/config.go b/internal/entity/config.go index cbbfe26..3c93e4e 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -95,3 +95,28 @@ func WriteConfig(config Config) error { } return nil } + +func SaveConfig(configIndex, updateConfigParamInt int, updateConfigParamStr string) error { + currentConfig, err := ReadConfig() + if err != nil { + return err + } + + switch configIndex { + case 0: + currentConfig.ChatGptApiKey = updateConfigParamStr + case 1: + currentConfig.UseLanguage = updateConfigParamInt + case 2: + currentConfig.CommitFormat = updateConfigParamInt + case 3: + currentConfig.AISource = updateConfigParamInt + } + + err = WriteConfig(currentConfig) + if err != nil { + return err + } + + return nil +} From 6385fd2e5814557697cddb0cf15574c256dea140 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 16:53:28 +0900 Subject: [PATCH 44/89] =?UTF-8?q?fix:=20config.yaml=E3=81=AE=E6=8C=99?= =?UTF-8?q?=E5=8B=95=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/entity/config.go | 14 ++++++++++++-- main.go | 8 ++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/internal/entity/config.go b/internal/entity/config.go index 3c93e4e..faa9f67 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -3,6 +3,7 @@ package entity import ( "encoding/json" "fmt" + "os" pb "github.com/cocoide/commitify/pkg/grpc" "github.com/spf13/viper" @@ -61,8 +62,12 @@ func (c *Config) Config2PbVars() (pb.CodeFormatType, pb.LanguageType) { func ReadConfig() (Config, error) { var result Config + homePath, err := os.UserHomeDir() + if err != nil { + return result, err + } - viper.AddConfigPath("$HOME/.commitify") + viper.AddConfigPath(homePath + "/.commitify") viper.SetConfigName("config") viper.SetConfigType("yaml") if err := viper.ReadInConfig(); err != nil { @@ -75,7 +80,12 @@ func ReadConfig() (Config, error) { } func WriteConfig(config Config) error { - viper.AddConfigPath("$HOME/.commitify") + homePath, err := os.UserHomeDir() + if err != nil { + return err + } + + viper.AddConfigPath(homePath + "/.commitify") viper.SetConfigName("config") viper.SetConfigType("yaml") configMap := make(map[string]interface{}) diff --git a/main.go b/main.go index 18a6557..1c5eee1 100644 --- a/main.go +++ b/main.go @@ -9,9 +9,13 @@ import ( func main() { // configファイルがあるかどうかを確認 - homePath := os.Getenv("HOME") + homePath, err := os.UserHomeDir() + if err != nil { + fmt.Printf("error of find user home dir, %v", err) + return + } - _, err := os.Stat(homePath + "/.commitify/config.yaml") + _, err = os.Stat(homePath + "/.commitify/config.yaml") if os.IsNotExist(err) { if err := os.MkdirAll(homePath+"/.commitify", 0755); err != nil { fmt.Printf("error of make directory, %v", err) From c27f677ed942f615a30a9af52d8c8ad25b5895f7 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 17:21:35 +0900 Subject: [PATCH 45/89] =?UTF-8?q?fix:=20=E3=83=A2=E3=83=87=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E5=90=8D=E5=89=8D=E3=82=92suggestModel=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 87 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index 1ae9c60..d9bfbc5 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -20,10 +20,9 @@ import ( var ( textStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("252")).Render spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) - helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render ) -type model struct { +type suggestModel struct { choices []string currentIdx int errorMsg string @@ -33,7 +32,7 @@ type model struct { textInput textinput.Model } -func (m *model) Init() tea.Cmd { +func (sm *suggestModel) Init() tea.Cmd { conf, err := entity.ReadConfig() if err != nil { log.Fatal("設定情報の取得に失敗: ", err) @@ -53,79 +52,79 @@ func (m *model) Init() tea.Cmd { log.Fatal("コミットメッセージの生成に失敗: ", err) os.Exit(-1) } - m.choices = messages - m.isLoading = false + sm.choices = messages + sm.isLoading = false }() return textinput.Blink } -func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (sm *suggestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd - m.textInput, cmd = m.textInput.Update(msg) + sm.textInput, cmd = sm.textInput.Update(msg) switch msg := msg.(type) { case tea.KeyMsg: switch msg.Type { case tea.KeyTab: - m.isEditing = true - m.textInput.Focus() - m.textInput.SetValue(m.choices[m.currentIdx]) - m.textInput.CharLimit = 100 - m.textInput.Width = 100 - return m, cmd + sm.isEditing = true + sm.textInput.Focus() + sm.textInput.SetValue(sm.choices[sm.currentIdx]) + sm.textInput.CharLimit = 100 + sm.textInput.Width = 100 + return sm, cmd case tea.KeyUp: - if m.currentIdx > 0 { - m.currentIdx-- + if sm.currentIdx > 0 { + sm.currentIdx-- } case tea.KeyDown: - if m.currentIdx < len(m.choices)-1 { - m.currentIdx++ + if sm.currentIdx < len(sm.choices)-1 { + sm.currentIdx++ } case tea.KeyEnter: - if err := util.ExecCommitMessage(m.choices[m.currentIdx]); err != nil { - m.errorMsg = "コミットに失敗: " + err.Error() - return m, tea.Quit + if err := util.ExecCommitMessage(sm.choices[sm.currentIdx]); err != nil { + sm.errorMsg = "コミットに失敗: " + err.Error() + return sm, tea.Quit } - return m, tea.Quit + return sm, tea.Quit case tea.KeyCtrlC, tea.KeyEsc: - return m, tea.Quit + return sm, tea.Quit } case spinner.TickMsg: var cmd tea.Cmd - m.spinner, cmd = m.spinner.Update(msg) - return m, cmd + sm.spinner, cmd = sm.spinner.Update(msg) + return sm, cmd } - return m, m.spinner.Tick + return sm, sm.spinner.Tick } -func (m *model) resetSpinner() { - m.spinner = spinner.New() - m.spinner.Style = spinnerStyle - m.spinner.Spinner = spinner.Globe +func (sm *suggestModel) resetSpinner() { + sm.spinner = spinner.New() + sm.spinner.Style = spinnerStyle + sm.spinner.Spinner = spinner.Globe } -func (m *model) View() string { - if m.errorMsg != "" { - return color.RedString(m.errorMsg) +func (sm *suggestModel) View() string { + if sm.errorMsg != "" { + return color.RedString(sm.errorMsg) } - if m.isLoading { - s := fmt.Sprintf("\n %s %s\n\n", m.spinner.View(), textStyle("コミットメッセージ生成中")) + if sm.isLoading { + s := fmt.Sprintf("\n %s %s\n\n", sm.spinner.View(), textStyle("コミットメッセージ生成中")) return s } var b strings.Builder - if m.errorMsg != "" { - b.WriteString(color.RedString(m.errorMsg) + "\n\n") + if sm.errorMsg != "" { + b.WriteString(color.RedString(sm.errorMsg) + "\n\n") } - if m.isEditing { - return m.textInput.View() + if sm.isEditing { + return sm.textInput.View() } b.WriteString(color.WhiteString("🍕 Please select and enter to commit")) b.WriteString(color.WhiteString("\n Use arrow ↑↓ to navigate and press Enter to select.")) b.WriteString(color.WhiteString("\n ( enter Tab key to edit message )\n\n")) - for i, choice := range m.choices { - if i == m.currentIdx { + for i, choice := range sm.choices { + if i == sm.currentIdx { b.WriteString(fmt.Sprintf(color.HiCyanString("➡️ %s\n"), choice)) } else { b.WriteString(fmt.Sprintf(color.CyanString(" %s\n"), choice)) @@ -134,7 +133,7 @@ func (m *model) View() string { return b.String() } -func initialModel() model { +func initialModel() suggestModel { ti := textinput.New() ti.Focus() @@ -153,9 +152,9 @@ var suggestCmd = &cobra.Command{ Short: "Suggestion of commit message for staging repository", Aliases: []string{"s", "suggest"}, Run: func(cmd *cobra.Command, args []string) { - m := initialModel() - m.resetSpinner() - p := tea.NewProgram(&m) + sm := initialModel() + sm.resetSpinner() + p := tea.NewProgram(&sm) p.Run() }, } From 378104df811ce50ced410fe54b9a98f412085f33 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 17:47:28 +0900 Subject: [PATCH 46/89] =?UTF-8?q?refactor:=20=E3=82=B3=E3=83=9F=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=AE?= =?UTF-8?q?=E4=BD=9C=E6=88=90=E5=87=A6=E7=90=86=E3=82=92=E3=80=81suggest?= =?UTF-8?q?=5Fcmd=5Fservice=E3=81=A8=E3=81=97=E3=81=A6=E5=88=87=E3=82=8A?= =?UTF-8?q?=E5=88=86=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 54 +++++++++---------- .../{grpc_serve.go => ai_source_grpc.go} | 13 +---- internal/gateway/ai_source_interface.go | 5 ++ .../{openai.go => ai_source_openai.go} | 0 internal/gateway/gateway_interface.go | 5 -- internal/service/file_diff_service.go | 8 +-- internal/service/suggest_cmd.go | 44 +++++++++++++++ 7 files changed, 81 insertions(+), 48 deletions(-) rename internal/gateway/{grpc_serve.go => ai_source_grpc.go} (79%) create mode 100644 internal/gateway/ai_source_interface.go rename internal/gateway/{openai.go => ai_source_openai.go} (100%) delete mode 100644 internal/gateway/gateway_interface.go create mode 100644 internal/service/suggest_cmd.go diff --git a/cmd/suggest.go b/cmd/suggest.go index d9bfbc5..2a32716 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -10,11 +10,11 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/cocoide/commitify/internal/entity" - "github.com/cocoide/commitify/internal/gateway" - "github.com/cocoide/commitify/util" "github.com/fatih/color" "github.com/spf13/cobra" + + "github.com/cocoide/commitify/internal/service" + "github.com/cocoide/commitify/util" ) var ( @@ -30,24 +30,12 @@ type suggestModel struct { isEditing bool spinner spinner.Model textInput textinput.Model + scs *service.SuggestCmdService } func (sm *suggestModel) Init() tea.Cmd { - conf, err := entity.ReadConfig() - if err != nil { - log.Fatal("設定情報の取得に失敗: ", err) - } - - var gi gateway.GatewayInterface - switch conf.AISource { - case int(entity.WrapServer): - gi = gateway.NewGrpcServeGateway() - default: - gi = gateway.NewGrpcServeGateway() - } - go func() { - messages, err := gi.FetchCommitMessages() + messages, err := sm.scs.GenerateCommitMessages() if err != nil { log.Fatal("コミットメッセージの生成に失敗: ", err) os.Exit(-1) @@ -97,12 +85,6 @@ func (sm *suggestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return sm, sm.spinner.Tick } -func (sm *suggestModel) resetSpinner() { - sm.spinner = spinner.New() - sm.spinner.Style = spinnerStyle - sm.spinner.Spinner = spinner.Globe -} - func (sm *suggestModel) View() string { if sm.errorMsg != "" { return color.RedString(sm.errorMsg) @@ -133,28 +115,44 @@ func (sm *suggestModel) View() string { return b.String() } -func initialModel() suggestModel { +// モデルの初期化処理 +func NewSuggestModel() *suggestModel { ti := textinput.New() ti.Focus() - return model{ + // suggestコマンドのサービスの取得 + scs, err := service.NewSuggestCmdService() + if err != nil { + log.Fatal(err) + os.Exit(-1) + } + + return &suggestModel{ choices: []string{""}, currentIdx: 0, errorMsg: "", isLoading: true, isEditing: false, textInput: ti, + scs: scs, } } +// スピナーの初期化 +func (sm *suggestModel) initSpinner() { + sm.spinner = spinner.New() + sm.spinner.Style = spinnerStyle + sm.spinner.Spinner = spinner.Globe +} + var suggestCmd = &cobra.Command{ Use: "suggest", Short: "Suggestion of commit message for staging repository", Aliases: []string{"s", "suggest"}, Run: func(cmd *cobra.Command, args []string) { - sm := initialModel() - sm.resetSpinner() - p := tea.NewProgram(&sm) + sm := NewSuggestModel() + sm.initSpinner() + p := tea.NewProgram(sm) p.Run() }, } diff --git a/internal/gateway/grpc_serve.go b/internal/gateway/ai_source_grpc.go similarity index 79% rename from internal/gateway/grpc_serve.go rename to internal/gateway/ai_source_grpc.go index b76bdd2..612c542 100644 --- a/internal/gateway/grpc_serve.go +++ b/internal/gateway/ai_source_grpc.go @@ -8,7 +8,6 @@ import ( "os" "github.com/cocoide/commitify/internal/entity" - "github.com/cocoide/commitify/internal/service" pb "github.com/cocoide/commitify/pkg/grpc" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -41,7 +40,7 @@ func NewGrpcServeGateway() *grpcServeGateway { return gsg } -func (gsg grpcServeGateway) FetchCommitMessages() ([]string, error) { +func (gsg grpcServeGateway) FetchCommitMessages(fileDiffStr string) ([]string, error) { // 設定情報を取得 conf, err := entity.ReadConfig() if err != nil { @@ -49,16 +48,8 @@ func (gsg grpcServeGateway) FetchCommitMessages() ([]string, error) { } cft, lt := conf.Config2PbVars() - fds := service.NewFileDiffService() - - diffStr, err := fds.CreateFileDiffStr() - if err != nil { - log.Fatal("差分の取得に失敗: ", err) - return nil, err - } - req := &pb.CommitMessageRequest{ - InputCode: diffStr, + InputCode: fileDiffStr, CodeFormat: cft, Language: lt, } diff --git a/internal/gateway/ai_source_interface.go b/internal/gateway/ai_source_interface.go new file mode 100644 index 0000000..3dcd9a4 --- /dev/null +++ b/internal/gateway/ai_source_interface.go @@ -0,0 +1,5 @@ +package gateway + +type AISourceGatewayInterface interface { + FetchCommitMessages(fileDiffStr string) ([]string, error) +} diff --git a/internal/gateway/openai.go b/internal/gateway/ai_source_openai.go similarity index 100% rename from internal/gateway/openai.go rename to internal/gateway/ai_source_openai.go diff --git a/internal/gateway/gateway_interface.go b/internal/gateway/gateway_interface.go deleted file mode 100644 index 8d2f8fd..0000000 --- a/internal/gateway/gateway_interface.go +++ /dev/null @@ -1,5 +0,0 @@ -package gateway - -type GatewayInterface interface { - FetchCommitMessages() ([]string, error) -} diff --git a/internal/service/file_diff_service.go b/internal/service/file_diff_service.go index c171a90..e9e2405 100644 --- a/internal/service/file_diff_service.go +++ b/internal/service/file_diff_service.go @@ -5,12 +5,12 @@ import "os/exec" type fileDiffService struct { } -func NewFileDiffService() *fileDiffService { - ps := new(fileDiffService) - return ps +func NewFileDiffService() fileDiffService { + fds := fileDiffService{} + return fds } -func (ps fileDiffService) CreateFileDiffStr() (string, error) { +func (fds *fileDiffService) createFileDiffStr() (string, error) { diff, err := exec.Command("git", "diff", "--staged").Output() return string(diff), err diff --git a/internal/service/suggest_cmd.go b/internal/service/suggest_cmd.go new file mode 100644 index 0000000..07900fc --- /dev/null +++ b/internal/service/suggest_cmd.go @@ -0,0 +1,44 @@ +package service + +import ( + "log" + + "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) +} From be69e706b36cd74abd97f0f42f1bbaeb94aab4c4 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 17:47:40 +0900 Subject: [PATCH 47/89] =?UTF-8?q?doc:=20=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/entity/config.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/entity/config.go b/internal/entity/config.go index faa9f67..519e183 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/viper" ) +// コミットメッセージの言語の列挙型 type Language int const ( @@ -16,6 +17,7 @@ const ( JP ) +// コミットメッセージの形式の列挙型 type CodeFormat int const ( @@ -24,6 +26,7 @@ const ( PrefixFormat ) +// AIのソースの列挙型 type AISource int const ( From cf05d15a09f263dcfaa1a051888ae31a2c760c27 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Wed, 4 Oct 2023 17:54:19 +0900 Subject: [PATCH 48/89] =?UTF-8?q?refactor:=20=E3=82=B3=E3=83=9F=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=82=92=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92`suggest=5Fcmd=5Fservice`=E3=81=AB=E7=A7=BB?= =?UTF-8?q?=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 3 +-- internal/service/suggest_cmd.go | 9 +++++++++ util/exec.go | 24 ------------------------ 3 files changed, 10 insertions(+), 26 deletions(-) delete mode 100644 util/exec.go diff --git a/cmd/suggest.go b/cmd/suggest.go index 2a32716..13d6e16 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -14,7 +14,6 @@ import ( "github.com/spf13/cobra" "github.com/cocoide/commitify/internal/service" - "github.com/cocoide/commitify/util" ) var ( @@ -69,7 +68,7 @@ func (sm *suggestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { sm.currentIdx++ } case tea.KeyEnter: - if err := util.ExecCommitMessage(sm.choices[sm.currentIdx]); err != nil { + if err := sm.scs.SubmitCommit(sm.choices[sm.currentIdx]); err != nil { sm.errorMsg = "コミットに失敗: " + err.Error() return sm, tea.Quit } diff --git a/internal/service/suggest_cmd.go b/internal/service/suggest_cmd.go index 07900fc..389f4c3 100644 --- a/internal/service/suggest_cmd.go +++ b/internal/service/suggest_cmd.go @@ -2,6 +2,7 @@ package service import ( "log" + "os/exec" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/gateway" @@ -42,3 +43,11 @@ func (scs *SuggestCmdService) GenerateCommitMessages() ([]string, error) { 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/util/exec.go b/util/exec.go deleted file mode 100644 index 5d5fba3..0000000 --- a/util/exec.go +++ /dev/null @@ -1,24 +0,0 @@ -package util - -import ( - "fmt" - "log" - "os/exec" -) - -func ExecGetStagingCode() string { - code, err := exec.Command("git", "diff", "--staged").Output() - if err != nil { - fmt.Printf("Gitでエラーが発生") - log.Fatal(err.Error()) - } - return string(code) -} - -func ExecCommitMessage(msg string) error { - cmd := exec.Command("git", "commit", "-m", msg) - if err := cmd.Run(); err != nil { - return err - } - return nil -} From 57fc483dd9dfd9b4af14caf749b6ee92feb43b21 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 6 Oct 2023 00:53:40 +0900 Subject: [PATCH 49/89] 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 50/89] =?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 51/89] 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 52/89] 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, "") } From 751d76033fccbd67de7db4d3e69f7beef94d371f Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Tue, 7 Nov 2023 00:15:15 +0900 Subject: [PATCH 53/89] fix: compile error --- cmd/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/config.go b/cmd/config.go index fb8b593..217ef48 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.Server), int(entity.Local)}, + {int(entity.Server), int(entity.Client)}, } configOptionLabel = [][]string{ {}, From f8899c30fccb7436efbc3a53b1848d4f5486f6a5 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 20:02:59 +0900 Subject: [PATCH 54/89] =?UTF-8?q?proto=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E5=A0=B4=E6=89=80=E3=82=92=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/entity/config.go | 2 +- proto/gen/code_type.pb.go | 191 ++++++ .../gen}/commit_message_service.pb.go | 186 ++--- .../gen}/commit_message_service_grpc.pb.go | 4 +- proto/gen/separate_commit_service.pb.go | 640 ++++++++++++++++++ proto/gen/separate_commit_service_grpc.pb.go | 109 +++ proto/src/code_type.proto | 21 + proto/src/commit_message_service.proto | 24 + proto/src/separate_commit_service.proto | 53 ++ 9 files changed, 1082 insertions(+), 148 deletions(-) create mode 100644 proto/gen/code_type.pb.go rename {pkg/grpc => proto/gen}/commit_message_service.pb.go (51%) rename {pkg/grpc => proto/gen}/commit_message_service_grpc.pb.go (98%) create mode 100644 proto/gen/separate_commit_service.pb.go create mode 100644 proto/gen/separate_commit_service_grpc.pb.go create mode 100644 proto/src/code_type.proto create mode 100644 proto/src/commit_message_service.proto create mode 100644 proto/src/separate_commit_service.proto diff --git a/internal/entity/config.go b/internal/entity/config.go index a11a39b..7a25587 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -3,7 +3,7 @@ package entity import ( "encoding/json" "fmt" - "github.com/cocoide/commitify-grpc-server/pkg/pb" + pb "github.com/cocoide/commitify/proto/gen" "github.com/spf13/viper" "os" ) diff --git a/proto/gen/code_type.pb.go b/proto/gen/code_type.pb.go new file mode 100644 index 0000000..a101a56 --- /dev/null +++ b/proto/gen/code_type.pb.go @@ -0,0 +1,191 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.4 +// source: code_type.proto + +package src + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// CodeFormatType specifies the type of commit message to generate +type CodeFormatType int32 + +const ( + CodeFormatType_UNKNOWN_FORMAT CodeFormatType = 0 + CodeFormatType_NORMAL CodeFormatType = 1 + CodeFormatType_PREFIX CodeFormatType = 2 + CodeFormatType_EMOJI CodeFormatType = 3 +) + +// Enum value maps for CodeFormatType. +var ( + CodeFormatType_name = map[int32]string{ + 0: "UNKNOWN_FORMAT", + 1: "NORMAL", + 2: "PREFIX", + 3: "EMOJI", + } + CodeFormatType_value = map[string]int32{ + "UNKNOWN_FORMAT": 0, + "NORMAL": 1, + "PREFIX": 2, + "EMOJI": 3, + } +) + +func (x CodeFormatType) Enum() *CodeFormatType { + p := new(CodeFormatType) + *p = x + return p +} + +func (x CodeFormatType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CodeFormatType) Descriptor() protoreflect.EnumDescriptor { + return file_code_type_proto_enumTypes[0].Descriptor() +} + +func (CodeFormatType) Type() protoreflect.EnumType { + return &file_code_type_proto_enumTypes[0] +} + +func (x CodeFormatType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CodeFormatType.Descriptor instead. +func (CodeFormatType) EnumDescriptor() ([]byte, []int) { + return file_code_type_proto_rawDescGZIP(), []int{0} +} + +// LanguageType specifies the language of the commit message to generate +type LanguageType int32 + +const ( + LanguageType_UNKNOWN_LANGUAGE LanguageType = 0 + LanguageType_ENGLISH LanguageType = 1 + LanguageType_JAPANESE LanguageType = 2 +) + +// Enum value maps for LanguageType. +var ( + LanguageType_name = map[int32]string{ + 0: "UNKNOWN_LANGUAGE", + 1: "ENGLISH", + 2: "JAPANESE", + } + LanguageType_value = map[string]int32{ + "UNKNOWN_LANGUAGE": 0, + "ENGLISH": 1, + "JAPANESE": 2, + } +) + +func (x LanguageType) Enum() *LanguageType { + p := new(LanguageType) + *p = x + return p +} + +func (x LanguageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (LanguageType) Descriptor() protoreflect.EnumDescriptor { + return file_code_type_proto_enumTypes[1].Descriptor() +} + +func (LanguageType) Type() protoreflect.EnumType { + return &file_code_type_proto_enumTypes[1] +} + +func (x LanguageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use LanguageType.Descriptor instead. +func (LanguageType) EnumDescriptor() ([]byte, []int) { + return file_code_type_proto_rawDescGZIP(), []int{1} +} + +var File_code_type_proto protoreflect.FileDescriptor + +var file_code_type_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x47, 0x0a, 0x0e, + 0x43, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, + 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0a, + 0x0a, 0x06, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, + 0x4f, 0x4a, 0x49, 0x10, 0x03, 0x2a, 0x3f, 0x0a, 0x0c, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x5f, 0x4c, 0x41, 0x4e, 0x47, 0x55, 0x41, 0x47, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, + 0x4e, 0x47, 0x4c, 0x49, 0x53, 0x48, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4a, 0x41, 0x50, 0x41, + 0x4e, 0x45, 0x53, 0x45, 0x10, 0x02, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x73, 0x72, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_code_type_proto_rawDescOnce sync.Once + file_code_type_proto_rawDescData = file_code_type_proto_rawDesc +) + +func file_code_type_proto_rawDescGZIP() []byte { + file_code_type_proto_rawDescOnce.Do(func() { + file_code_type_proto_rawDescData = protoimpl.X.CompressGZIP(file_code_type_proto_rawDescData) + }) + return file_code_type_proto_rawDescData +} + +var file_code_type_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_code_type_proto_goTypes = []interface{}{ + (CodeFormatType)(0), // 0: code_type.CodeFormatType + (LanguageType)(0), // 1: code_type.LanguageType +} +var file_code_type_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_code_type_proto_init() } +func file_code_type_proto_init() { + if File_code_type_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_code_type_proto_rawDesc, + NumEnums: 2, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_code_type_proto_goTypes, + DependencyIndexes: file_code_type_proto_depIdxs, + EnumInfos: file_code_type_proto_enumTypes, + }.Build() + File_code_type_proto = out.File + file_code_type_proto_rawDesc = nil + file_code_type_proto_goTypes = nil + file_code_type_proto_depIdxs = nil +} diff --git a/pkg/grpc/commit_message_service.pb.go b/proto/gen/commit_message_service.pb.go similarity index 51% rename from pkg/grpc/commit_message_service.pb.go rename to proto/gen/commit_message_service.pb.go index fe6d734..a82a577 100644 --- a/pkg/grpc/commit_message_service.pb.go +++ b/proto/gen/commit_message_service.pb.go @@ -1,10 +1,10 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v4.24.2 +// protoc v4.24.4 // source: commit_message_service.proto -package pb +package src import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -20,103 +20,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// CodeFormatType specifies the type of commit message to generate -type CodeFormatType int32 - -const ( - CodeFormatType_EMOJI CodeFormatType = 0 - CodeFormatType_PREFIX CodeFormatType = 1 - CodeFormatType_NORMAL CodeFormatType = 2 -) - -// Enum value maps for CodeFormatType. -var ( - CodeFormatType_name = map[int32]string{ - 0: "EMOJI", - 1: "PREFIX", - 2: "NORMAL", - } - CodeFormatType_value = map[string]int32{ - "EMOJI": 0, - "PREFIX": 1, - "NORMAL": 2, - } -) - -func (x CodeFormatType) Enum() *CodeFormatType { - p := new(CodeFormatType) - *p = x - return p -} - -func (x CodeFormatType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (CodeFormatType) Descriptor() protoreflect.EnumDescriptor { - return file_commit_message_service_proto_enumTypes[0].Descriptor() -} - -func (CodeFormatType) Type() protoreflect.EnumType { - return &file_commit_message_service_proto_enumTypes[0] -} - -func (x CodeFormatType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use CodeFormatType.Descriptor instead. -func (CodeFormatType) EnumDescriptor() ([]byte, []int) { - return file_commit_message_service_proto_rawDescGZIP(), []int{0} -} - -// LanguageType specifies the language of the commit message to generate -type LanguageType int32 - -const ( - LanguageType_ENGLISH LanguageType = 0 - LanguageType_JAPANESE LanguageType = 1 -) - -// Enum value maps for LanguageType. -var ( - LanguageType_name = map[int32]string{ - 0: "ENGLISH", - 1: "JAPANESE", - } - LanguageType_value = map[string]int32{ - "ENGLISH": 0, - "JAPANESE": 1, - } -) - -func (x LanguageType) Enum() *LanguageType { - p := new(LanguageType) - *p = x - return p -} - -func (x LanguageType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (LanguageType) Descriptor() protoreflect.EnumDescriptor { - return file_commit_message_service_proto_enumTypes[1].Descriptor() -} - -func (LanguageType) Type() protoreflect.EnumType { - return &file_commit_message_service_proto_enumTypes[1] -} - -func (x LanguageType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use LanguageType.Descriptor instead. -func (LanguageType) EnumDescriptor() ([]byte, []int) { - return file_commit_message_service_proto_rawDescGZIP(), []int{1} -} - // CommitMessageRequest is the request format for generating messages type CommitMessageRequest struct { state protoimpl.MessageState @@ -124,8 +27,8 @@ type CommitMessageRequest struct { unknownFields protoimpl.UnknownFields InputCode string `protobuf:"bytes,1,opt,name=inputCode,proto3" json:"inputCode,omitempty"` - CodeFormat CodeFormatType `protobuf:"varint,2,opt,name=codeFormat,proto3,enum=commit_message.CodeFormatType" json:"codeFormat,omitempty"` - Language LanguageType `protobuf:"varint,3,opt,name=language,proto3,enum=commit_message.LanguageType" json:"language,omitempty"` + CodeFormat CodeFormatType `protobuf:"varint,2,opt,name=codeFormat,proto3,enum=code_type.CodeFormatType" json:"codeFormat,omitempty"` + Language LanguageType `protobuf:"varint,3,opt,name=language,proto3,enum=code_type.LanguageType" json:"language,omitempty"` } func (x *CommitMessageRequest) Reset() { @@ -171,14 +74,14 @@ func (x *CommitMessageRequest) GetCodeFormat() CodeFormatType { if x != nil { return x.CodeFormat } - return CodeFormatType_EMOJI + return CodeFormatType_UNKNOWN_FORMAT } func (x *CommitMessageRequest) GetLanguage() LanguageType { if x != nil { return x.Language } - return LanguageType_ENGLISH + return LanguageType_UNKNOWN_LANGUAGE } // CommitMessageResponse returns generated commit messages @@ -234,37 +137,31 @@ var File_commit_message_service_proto protoreflect.FileDescriptor var file_commit_message_service_proto_rawDesc = []byte{ 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xae, - 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x46, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x38, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, - 0x33, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x2a, 0x33, 0x0a, 0x0e, 0x43, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x4f, 0x4a, 0x49, 0x10, - 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x10, 0x01, 0x12, 0x0a, 0x0a, - 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x02, 0x2a, 0x29, 0x0a, 0x0c, 0x4c, 0x61, 0x6e, - 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x47, - 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4a, 0x41, 0x50, 0x41, 0x4e, 0x45, - 0x53, 0x45, 0x10, 0x01, 0x32, 0x7c, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x64, 0x0a, 0x15, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f, + 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xa4, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x12, 0x33, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, + 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, 0x33, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x32, 0x7c, 0x0a, 0x14, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x73, 0x72, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -279,19 +176,18 @@ func file_commit_message_service_proto_rawDescGZIP() []byte { return file_commit_message_service_proto_rawDescData } -var file_commit_message_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_commit_message_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_commit_message_service_proto_goTypes = []interface{}{ - (CodeFormatType)(0), // 0: commit_message.CodeFormatType - (LanguageType)(0), // 1: commit_message.LanguageType - (*CommitMessageRequest)(nil), // 2: commit_message.CommitMessageRequest - (*CommitMessageResponse)(nil), // 3: commit_message.CommitMessageResponse + (*CommitMessageRequest)(nil), // 0: commit_message.CommitMessageRequest + (*CommitMessageResponse)(nil), // 1: commit_message.CommitMessageResponse + (CodeFormatType)(0), // 2: code_type.CodeFormatType + (LanguageType)(0), // 3: code_type.LanguageType } var file_commit_message_service_proto_depIdxs = []int32{ - 0, // 0: commit_message.CommitMessageRequest.codeFormat:type_name -> commit_message.CodeFormatType - 1, // 1: commit_message.CommitMessageRequest.language:type_name -> commit_message.LanguageType - 2, // 2: commit_message.CommitMessageService.GenerateCommitMessage:input_type -> commit_message.CommitMessageRequest - 3, // 3: commit_message.CommitMessageService.GenerateCommitMessage:output_type -> commit_message.CommitMessageResponse + 2, // 0: commit_message.CommitMessageRequest.codeFormat:type_name -> code_type.CodeFormatType + 3, // 1: commit_message.CommitMessageRequest.language:type_name -> code_type.LanguageType + 0, // 2: commit_message.CommitMessageService.GenerateCommitMessage:input_type -> commit_message.CommitMessageRequest + 1, // 3: commit_message.CommitMessageService.GenerateCommitMessage:output_type -> commit_message.CommitMessageResponse 3, // [3:4] is the sub-list for method output_type 2, // [2:3] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name @@ -304,6 +200,7 @@ func file_commit_message_service_proto_init() { if File_commit_message_service_proto != nil { return } + file_code_type_proto_init() if !protoimpl.UnsafeEnabled { file_commit_message_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CommitMessageRequest); i { @@ -335,14 +232,13 @@ func file_commit_message_service_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_commit_message_service_proto_rawDesc, - NumEnums: 2, + NumEnums: 0, NumMessages: 2, NumExtensions: 0, NumServices: 1, }, GoTypes: file_commit_message_service_proto_goTypes, DependencyIndexes: file_commit_message_service_proto_depIdxs, - EnumInfos: file_commit_message_service_proto_enumTypes, MessageInfos: file_commit_message_service_proto_msgTypes, }.Build() File_commit_message_service_proto = out.File diff --git a/pkg/grpc/commit_message_service_grpc.pb.go b/proto/gen/commit_message_service_grpc.pb.go similarity index 98% rename from pkg/grpc/commit_message_service_grpc.pb.go rename to proto/gen/commit_message_service_grpc.pb.go index 65a91f3..3bd3153 100644 --- a/pkg/grpc/commit_message_service_grpc.pb.go +++ b/proto/gen/commit_message_service_grpc.pb.go @@ -1,10 +1,10 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.24.2 +// - protoc v4.24.4 // source: commit_message_service.proto -package pb +package src import ( context "context" diff --git a/proto/gen/separate_commit_service.pb.go b/proto/gen/separate_commit_service.pb.go new file mode 100644 index 0000000..96c736a --- /dev/null +++ b/proto/gen/separate_commit_service.pb.go @@ -0,0 +1,640 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.4 +// source: separate_commit_service.proto + +package src + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ChangeType specifies the type of +type ChangeType int32 + +const ( + ChangeType_UNKNOWN_CHANGE ChangeType = 0 + ChangeType_CREATE ChangeType = 1 + ChangeType_UPDATE ChangeType = 2 + ChangeType_DELETE ChangeType = 3 +) + +// Enum value maps for ChangeType. +var ( + ChangeType_name = map[int32]string{ + 0: "UNKNOWN_CHANGE", + 1: "CREATE", + 2: "UPDATE", + 3: "DELETE", + } + ChangeType_value = map[string]int32{ + "UNKNOWN_CHANGE": 0, + "CREATE": 1, + "UPDATE": 2, + "DELETE": 3, + } +) + +func (x ChangeType) Enum() *ChangeType { + p := new(ChangeType) + *p = x + return p +} + +func (x ChangeType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ChangeType) Descriptor() protoreflect.EnumDescriptor { + return file_separate_commit_service_proto_enumTypes[0].Descriptor() +} + +func (ChangeType) Type() protoreflect.EnumType { + return &file_separate_commit_service_proto_enumTypes[0] +} + +func (x ChangeType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ChangeType.Descriptor instead. +func (ChangeType) EnumDescriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{0} +} + +// SeparateCommitRequest is the request format for generating messages +type SeparateCommitRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FileChanges []*FileChange `protobuf:"bytes,1,rep,name=fileChanges,proto3" json:"fileChanges,omitempty"` + CodeFormat CodeFormatType `protobuf:"varint,2,opt,name=codeFormat,proto3,enum=code_type.CodeFormatType" json:"codeFormat,omitempty"` + Language LanguageType `protobuf:"varint,3,opt,name=language,proto3,enum=code_type.LanguageType" json:"language,omitempty"` +} + +func (x *SeparateCommitRequest) Reset() { + *x = SeparateCommitRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_separate_commit_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SeparateCommitRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SeparateCommitRequest) ProtoMessage() {} + +func (x *SeparateCommitRequest) ProtoReflect() protoreflect.Message { + mi := &file_separate_commit_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SeparateCommitRequest.ProtoReflect.Descriptor instead. +func (*SeparateCommitRequest) Descriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{0} +} + +func (x *SeparateCommitRequest) GetFileChanges() []*FileChange { + if x != nil { + return x.FileChanges + } + return nil +} + +func (x *SeparateCommitRequest) GetCodeFormat() CodeFormatType { + if x != nil { + return x.CodeFormat + } + return CodeFormatType_UNKNOWN_FORMAT +} + +func (x *SeparateCommitRequest) GetLanguage() LanguageType { + if x != nil { + return x.Language + } + return LanguageType_UNKNOWN_LANGUAGE +} + +type LineDiff struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + Line string `protobuf:"bytes,2,opt,name=line,proto3" json:"line,omitempty"` +} + +func (x *LineDiff) Reset() { + *x = LineDiff{} + if protoimpl.UnsafeEnabled { + mi := &file_separate_commit_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineDiff) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineDiff) ProtoMessage() {} + +func (x *LineDiff) ProtoReflect() protoreflect.Message { + mi := &file_separate_commit_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LineDiff.ProtoReflect.Descriptor instead. +func (*LineDiff) Descriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{1} +} + +func (x *LineDiff) GetIndex() int32 { + if x != nil { + return x.Index + } + return 0 +} + +func (x *LineDiff) GetLine() string { + if x != nil { + return x.Line + } + return "" +} + +type CodeDiff struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Added []*LineDiff `protobuf:"bytes,1,rep,name=added,proto3" json:"added,omitempty"` + Deleted []*LineDiff `protobuf:"bytes,2,rep,name=deleted,proto3" json:"deleted,omitempty"` +} + +func (x *CodeDiff) Reset() { + *x = CodeDiff{} + if protoimpl.UnsafeEnabled { + mi := &file_separate_commit_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CodeDiff) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CodeDiff) ProtoMessage() {} + +func (x *CodeDiff) ProtoReflect() protoreflect.Message { + mi := &file_separate_commit_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CodeDiff.ProtoReflect.Descriptor instead. +func (*CodeDiff) Descriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{2} +} + +func (x *CodeDiff) GetAdded() []*LineDiff { + if x != nil { + return x.Added + } + return nil +} + +func (x *CodeDiff) GetDeleted() []*LineDiff { + if x != nil { + return x.Deleted + } + return nil +} + +type FileChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CodeDiff *CodeDiff `protobuf:"bytes,1,opt,name=codeDiff,proto3" json:"codeDiff,omitempty"` + Filename string `protobuf:"bytes,2,opt,name=filename,proto3" json:"filename,omitempty"` + ChangeType ChangeType `protobuf:"varint,3,opt,name=changeType,proto3,enum=separate_commit.ChangeType" json:"changeType,omitempty"` +} + +func (x *FileChange) Reset() { + *x = FileChange{} + if protoimpl.UnsafeEnabled { + mi := &file_separate_commit_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileChange) ProtoMessage() {} + +func (x *FileChange) ProtoReflect() protoreflect.Message { + mi := &file_separate_commit_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileChange.ProtoReflect.Descriptor instead. +func (*FileChange) Descriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{3} +} + +func (x *FileChange) GetCodeDiff() *CodeDiff { + if x != nil { + return x.CodeDiff + } + return nil +} + +func (x *FileChange) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +func (x *FileChange) GetChangeType() ChangeType { + if x != nil { + return x.ChangeType + } + return ChangeType_UNKNOWN_CHANGE +} + +// SeparateCommitResponse returns generated and separated commit messages +type SeparateCommitResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SeparatedCommits []*SeparatedCommitMessages `protobuf:"bytes,1,rep,name=separatedCommits,proto3" json:"separatedCommits,omitempty"` +} + +func (x *SeparateCommitResponse) Reset() { + *x = SeparateCommitResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_separate_commit_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SeparateCommitResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SeparateCommitResponse) ProtoMessage() {} + +func (x *SeparateCommitResponse) ProtoReflect() protoreflect.Message { + mi := &file_separate_commit_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SeparateCommitResponse.ProtoReflect.Descriptor instead. +func (*SeparateCommitResponse) Descriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{4} +} + +func (x *SeparateCommitResponse) GetSeparatedCommits() []*SeparatedCommitMessages { + if x != nil { + return x.SeparatedCommits + } + return nil +} + +type SeparatedCommitMessages struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Messages []string `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` + Filename string `protobuf:"bytes,2,opt,name=filename,proto3" json:"filename,omitempty"` + ChangeType ChangeType `protobuf:"varint,3,opt,name=changeType,proto3,enum=separate_commit.ChangeType" json:"changeType,omitempty"` +} + +func (x *SeparatedCommitMessages) Reset() { + *x = SeparatedCommitMessages{} + if protoimpl.UnsafeEnabled { + mi := &file_separate_commit_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SeparatedCommitMessages) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SeparatedCommitMessages) ProtoMessage() {} + +func (x *SeparatedCommitMessages) ProtoReflect() protoreflect.Message { + mi := &file_separate_commit_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SeparatedCommitMessages.ProtoReflect.Descriptor instead. +func (*SeparatedCommitMessages) Descriptor() ([]byte, []int) { + return file_separate_commit_service_proto_rawDescGZIP(), []int{5} +} + +func (x *SeparatedCommitMessages) GetMessages() []string { + if x != nil { + return x.Messages + } + return nil +} + +func (x *SeparatedCommitMessages) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +func (x *SeparatedCommitMessages) GetChangeType() ChangeType { + if x != nil { + return x.ChangeType + } + return ChangeType_UNKNOWN_CHANGE +} + +var File_separate_commit_service_proto protoreflect.FileDescriptor + +var file_separate_commit_service_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x1a, 0x0f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0b, 0x66, + 0x69, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0b, 0x66, + 0x69, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x6f, + 0x64, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a, 0x08, 0x4c, 0x69, + 0x6e, 0x65, 0x44, 0x69, 0x66, 0x66, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, + 0x22, 0x70, 0x0a, 0x08, 0x43, 0x6f, 0x64, 0x65, 0x44, 0x69, 0x66, 0x66, 0x12, 0x2f, 0x0a, 0x05, + 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, + 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x4c, 0x69, + 0x6e, 0x65, 0x44, 0x69, 0x66, 0x66, 0x52, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x12, 0x33, 0x0a, + 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x44, 0x69, 0x66, 0x66, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x22, 0x9c, 0x01, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x35, 0x0a, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x44, 0x69, 0x66, 0x66, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x44, 0x69, 0x66, 0x66, 0x52, 0x08, + 0x63, 0x6f, 0x64, 0x65, 0x44, 0x69, 0x66, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x6e, 0x0a, 0x16, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x10, 0x73, + 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, + 0x10, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1a, 0x0a, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x2a, 0x44, 0x0a, 0x0a, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x48, 0x41, 0x4e, + 0x47, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, + 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, + 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x32, 0x89, 0x01, 0x0a, 0x15, 0x53, 0x65, 0x70, + 0x61, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x70, 0x0a, 0x1d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x75, + 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x26, 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x73, 0x65, + 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x53, 0x65, + 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x72, + 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_separate_commit_service_proto_rawDescOnce sync.Once + file_separate_commit_service_proto_rawDescData = file_separate_commit_service_proto_rawDesc +) + +func file_separate_commit_service_proto_rawDescGZIP() []byte { + file_separate_commit_service_proto_rawDescOnce.Do(func() { + file_separate_commit_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_separate_commit_service_proto_rawDescData) + }) + return file_separate_commit_service_proto_rawDescData +} + +var file_separate_commit_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_separate_commit_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_separate_commit_service_proto_goTypes = []interface{}{ + (ChangeType)(0), // 0: separate_commit.ChangeType + (*SeparateCommitRequest)(nil), // 1: separate_commit.SeparateCommitRequest + (*LineDiff)(nil), // 2: separate_commit.LineDiff + (*CodeDiff)(nil), // 3: separate_commit.CodeDiff + (*FileChange)(nil), // 4: separate_commit.FileChange + (*SeparateCommitResponse)(nil), // 5: separate_commit.SeparateCommitResponse + (*SeparatedCommitMessages)(nil), // 6: separate_commit.SeparatedCommitMessages + (CodeFormatType)(0), // 7: code_type.CodeFormatType + (LanguageType)(0), // 8: code_type.LanguageType +} +var file_separate_commit_service_proto_depIdxs = []int32{ + 4, // 0: separate_commit.SeparateCommitRequest.fileChanges:type_name -> separate_commit.FileChange + 7, // 1: separate_commit.SeparateCommitRequest.codeFormat:type_name -> code_type.CodeFormatType + 8, // 2: separate_commit.SeparateCommitRequest.language:type_name -> code_type.LanguageType + 2, // 3: separate_commit.CodeDiff.added:type_name -> separate_commit.LineDiff + 2, // 4: separate_commit.CodeDiff.deleted:type_name -> separate_commit.LineDiff + 3, // 5: separate_commit.FileChange.codeDiff:type_name -> separate_commit.CodeDiff + 0, // 6: separate_commit.FileChange.changeType:type_name -> separate_commit.ChangeType + 6, // 7: separate_commit.SeparateCommitResponse.separatedCommits:type_name -> separate_commit.SeparatedCommitMessages + 0, // 8: separate_commit.SeparatedCommitMessages.changeType:type_name -> separate_commit.ChangeType + 1, // 9: separate_commit.SeparateCommitService.GenerateMultipleCommitMessage:input_type -> separate_commit.SeparateCommitRequest + 5, // 10: separate_commit.SeparateCommitService.GenerateMultipleCommitMessage:output_type -> separate_commit.SeparateCommitResponse + 10, // [10:11] is the sub-list for method output_type + 9, // [9:10] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_separate_commit_service_proto_init() } +func file_separate_commit_service_proto_init() { + if File_separate_commit_service_proto != nil { + return + } + file_code_type_proto_init() + if !protoimpl.UnsafeEnabled { + file_separate_commit_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SeparateCommitRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_separate_commit_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineDiff); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_separate_commit_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CodeDiff); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_separate_commit_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileChange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_separate_commit_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SeparateCommitResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_separate_commit_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SeparatedCommitMessages); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_separate_commit_service_proto_rawDesc, + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_separate_commit_service_proto_goTypes, + DependencyIndexes: file_separate_commit_service_proto_depIdxs, + EnumInfos: file_separate_commit_service_proto_enumTypes, + MessageInfos: file_separate_commit_service_proto_msgTypes, + }.Build() + File_separate_commit_service_proto = out.File + file_separate_commit_service_proto_rawDesc = nil + file_separate_commit_service_proto_goTypes = nil + file_separate_commit_service_proto_depIdxs = nil +} diff --git a/proto/gen/separate_commit_service_grpc.pb.go b/proto/gen/separate_commit_service_grpc.pb.go new file mode 100644 index 0000000..3fc3840 --- /dev/null +++ b/proto/gen/separate_commit_service_grpc.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.4 +// source: separate_commit_service.proto + +package src + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + SeparateCommitService_GenerateMultipleCommitMessage_FullMethodName = "/separate_commit.SeparateCommitService/GenerateMultipleCommitMessage" +) + +// SeparateCommitServiceClient is the client API for SeparateCommitService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SeparateCommitServiceClient interface { + GenerateMultipleCommitMessage(ctx context.Context, in *SeparateCommitRequest, opts ...grpc.CallOption) (*SeparateCommitResponse, error) +} + +type separateCommitServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSeparateCommitServiceClient(cc grpc.ClientConnInterface) SeparateCommitServiceClient { + return &separateCommitServiceClient{cc} +} + +func (c *separateCommitServiceClient) GenerateMultipleCommitMessage(ctx context.Context, in *SeparateCommitRequest, opts ...grpc.CallOption) (*SeparateCommitResponse, error) { + out := new(SeparateCommitResponse) + err := c.cc.Invoke(ctx, SeparateCommitService_GenerateMultipleCommitMessage_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SeparateCommitServiceServer is the server API for SeparateCommitService service. +// All implementations must embed UnimplementedSeparateCommitServiceServer +// for forward compatibility +type SeparateCommitServiceServer interface { + GenerateMultipleCommitMessage(context.Context, *SeparateCommitRequest) (*SeparateCommitResponse, error) + mustEmbedUnimplementedSeparateCommitServiceServer() +} + +// UnimplementedSeparateCommitServiceServer must be embedded to have forward compatible implementations. +type UnimplementedSeparateCommitServiceServer struct { +} + +func (UnimplementedSeparateCommitServiceServer) GenerateMultipleCommitMessage(context.Context, *SeparateCommitRequest) (*SeparateCommitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GenerateMultipleCommitMessage not implemented") +} +func (UnimplementedSeparateCommitServiceServer) mustEmbedUnimplementedSeparateCommitServiceServer() {} + +// UnsafeSeparateCommitServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SeparateCommitServiceServer will +// result in compilation errors. +type UnsafeSeparateCommitServiceServer interface { + mustEmbedUnimplementedSeparateCommitServiceServer() +} + +func RegisterSeparateCommitServiceServer(s grpc.ServiceRegistrar, srv SeparateCommitServiceServer) { + s.RegisterService(&SeparateCommitService_ServiceDesc, srv) +} + +func _SeparateCommitService_GenerateMultipleCommitMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SeparateCommitRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeparateCommitServiceServer).GenerateMultipleCommitMessage(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeparateCommitService_GenerateMultipleCommitMessage_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeparateCommitServiceServer).GenerateMultipleCommitMessage(ctx, req.(*SeparateCommitRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// SeparateCommitService_ServiceDesc is the grpc.ServiceDesc for SeparateCommitService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SeparateCommitService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "separate_commit.SeparateCommitService", + HandlerType: (*SeparateCommitServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GenerateMultipleCommitMessage", + Handler: _SeparateCommitService_GenerateMultipleCommitMessage_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "separate_commit_service.proto", +} diff --git a/proto/src/code_type.proto b/proto/src/code_type.proto new file mode 100644 index 0000000..c7c5b42 --- /dev/null +++ b/proto/src/code_type.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +option go_package = "proto/src"; + +package code_type; + + +// CodeFormatType specifies the type of commit message to generate +enum CodeFormatType { + UNKNOWN_FORMAT = 0; + NORMAL = 1; + PREFIX = 2; + EMOJI = 3; +} + +// LanguageType specifies the language of the commit message to generate +enum LanguageType { + UNKNOWN_LANGUAGE = 0; + ENGLISH =1; + JAPANESE =2; +} \ No newline at end of file diff --git a/proto/src/commit_message_service.proto b/proto/src/commit_message_service.proto new file mode 100644 index 0000000..f9bcd93 --- /dev/null +++ b/proto/src/commit_message_service.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +option go_package = "proto/src"; + +package commit_message; + +import "code_type.proto"; + +// CommitMessageService provides methods to generate commit messages +service CommitMessageService { + rpc GenerateCommitMessage(CommitMessageRequest) returns (CommitMessageResponse); +} + +// CommitMessageRequest is the request format for generating messages +message CommitMessageRequest { + string inputCode = 1; + code_type.CodeFormatType codeFormat = 2; + code_type.LanguageType language = 3; +} + +// CommitMessageResponse returns generated commit messages +message CommitMessageResponse { + repeated string messages = 1; +} \ No newline at end of file diff --git a/proto/src/separate_commit_service.proto b/proto/src/separate_commit_service.proto new file mode 100644 index 0000000..26b9f8a --- /dev/null +++ b/proto/src/separate_commit_service.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + +option go_package = "proto/src"; + +package separate_commit; + +import "code_type.proto"; + +service SeparateCommitService { + rpc GenerateMultipleCommitMessage(SeparateCommitRequest) returns (SeparateCommitResponse); +} + +// SeparateCommitRequest is the request format for generating messages +message SeparateCommitRequest { + repeated FileChange fileChanges = 1; + code_type.CodeFormatType codeFormat = 2; + code_type.LanguageType language = 3; +} + +message LineDiff { + int32 index = 1; + string line = 2; +} + +message CodeDiff { + repeated LineDiff added = 1; + repeated LineDiff deleted = 2; +} + +message FileChange { + CodeDiff codeDiff = 1; + string filename = 2; + ChangeType changeType = 3; +} + +// ChangeType specifies the type of +enum ChangeType { + UNKNOWN_CHANGE = 0; + CREATE = 1; + UPDATE = 2; + DELETE = 3; +} + +// SeparateCommitResponse returns generated and separated commit messages +message SeparateCommitResponse { + repeated SeparatedCommitMessages separatedCommits = 1; +} + +message SeparatedCommitMessages { + repeated string messages = 1; + string filename = 2; + ChangeType changeType = 3; +} From 0044f4df960ae4f9c9040adc9d965a31b5cec496 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 20:03:17 +0900 Subject: [PATCH 55/89] =?UTF-8?q?proto=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E5=A0=B4=E6=89=80=E3=82=92=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gateway/grpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/gateway/grpc.go b/internal/gateway/grpc.go index d0391b1..4d436a8 100644 --- a/internal/gateway/grpc.go +++ b/internal/gateway/grpc.go @@ -2,9 +2,9 @@ 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" + pb "github.com/cocoide/commitify/proto/gen" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" From aa8fc6218dbc769117923a8deb433c10cd72ec08 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 22:56:38 +0900 Subject: [PATCH 56/89] =?UTF-8?q?feat:=20=E3=82=AB=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=A0HttpClient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gateway/http_client.go | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 internal/gateway/http_client.go diff --git a/internal/gateway/http_client.go b/internal/gateway/http_client.go new file mode 100644 index 0000000..b918aee --- /dev/null +++ b/internal/gateway/http_client.go @@ -0,0 +1,103 @@ +package gateway + +import ( + "fmt" + "io" + "net/http" + "strconv" +) + +type HttpClient struct { + Client *http.Client + Endpoint string + Headers map[string]string + Params map[string]interface{} + Body io.Reader +} + +func NewHttpClient() *HttpClient { + return &HttpClient{ + Client: &http.Client{}, + Headers: make(map[string]string), + Params: make(map[string]interface{}), + } +} + +func (h *HttpClient) WithBaseURL(baseURL string) *HttpClient { + h.Endpoint = baseURL + return h +} + +func (h *HttpClient) WithBearerToken(token string) *HttpClient { + h.Headers["Authorization"] = fmt.Sprintf("Bearer %s", token) + return h +} + +func (h *HttpClient) WithPath(path string) *HttpClient { + h.Endpoint = h.Endpoint + "/" + path + return h +} + +func (h *HttpClient) WithParam(key string, value interface{}) *HttpClient { + h.Params[key] = value + return h +} + +type HttpMethod int + +const ( + GET HttpMethod = iota + 1 + POST + DELTE + PUT +) + +func (h *HttpClient) Execute(method HttpMethod) ([]byte, error) { + var methodName string + switch method { + case GET: + methodName = "GET" + case POST: + methodName = "POST" + case DELTE: + methodName = "DELETE" + case PUT: + methodName = "PUT" + } + client := h.Client + + req, err := http.NewRequest(methodName, h.Endpoint, h.Body) + if err != nil { + return nil, err + } + + for k, v := range h.Headers { + req.Header.Add(k, v) + } + + query := req.URL.Query() + for key, value := range h.Params { + switch v := value.(type) { + case string: + query.Add(key, v) + case int: + query.Add(key, strconv.Itoa(v)) + case bool: + query.Add(key, strconv.FormatBool(v)) + default: + return nil, fmt.Errorf("Failed to parse param value: %v", value) + } + } + req.URL.RawQuery = query.Encode() + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +} From cd2a6e2e684dce3ec427b9597e89a63ba85d25f4 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 22:56:55 +0900 Subject: [PATCH 57/89] feat: logincmd usecase --- internal/usecase/login_cmd.go | 122 ++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 internal/usecase/login_cmd.go diff --git a/internal/usecase/login_cmd.go b/internal/usecase/login_cmd.go new file mode 100644 index 0000000..495d6c4 --- /dev/null +++ b/internal/usecase/login_cmd.go @@ -0,0 +1,122 @@ +package usecase + +import ( + "fmt" + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/gateway" + "log" + "net/url" + "strconv" + "time" +) + +const ( + GithubClientID = "b27d87c28752d2363922" + GithubScope = "repo" + GrantType = "urn:ietf:params:oauth:grant-type:device_code" +) + +type LoginCmdUsecase struct { + http *gateway.HttpClient +} + +func NewLoginCmdUsecase(http *gateway.HttpClient) *LoginCmdUsecase { + http.WithBaseURL("https://github.com/login") + return &LoginCmdUsecase{http: http} +} + +type BeginGithubSSOResponse struct { + DeviceCode string + UserCode string + Interval int + ExpiresIn int +} + +func (u *LoginCmdUsecase) BeginGithubSSO() (*BeginGithubSSOResponse, error) { + b, err := u.http.WithPath("device/code"). + WithParam("client_id", GithubClientID). + WithParam("scope", GithubScope). + Execute(gateway.POST) + if err != nil { + return nil, err + } + values, err := url.ParseQuery(string(b)) + if err != nil { + return nil, err + } + deviceCode := values.Get("device_code") + userCode := values.Get("user_code") + expiresIn, err := strconv.Atoi(values.Get("expires_in")) + if err != nil { + return nil, err + } + interval, err := strconv.Atoi(values.Get("interval")) + if err != nil { + return nil, err + } + if deviceCode == "" || userCode == "" { + return nil, fmt.Errorf("failed to parse code") + } + return &BeginGithubSSOResponse{ + DeviceCode: deviceCode, + UserCode: userCode, + ExpiresIn: expiresIn, + Interval: interval, + }, nil +} + +type ScheduleVerifyAuthRequest struct { + DeviceCode string + Interval int + ExpiresIn int +} + +func (u *LoginCmdUsecase) ScheduleVerifyAuth(req *ScheduleVerifyAuthRequest) error { + u.http = gateway.NewHttpClient(). + WithBaseURL("https://github.com/login"). + WithPath("oauth/access_token"). + WithParam("client_id", GithubClientID). + WithParam("device_code", req.DeviceCode). + WithParam("grant_type", GrantType) + + timeout := time.After(time.Duration(req.ExpiresIn) * time.Second) + ticker := time.NewTicker(time.Duration(req.Interval) * time.Second) + defer ticker.Stop() + + for { + select { + case <-timeout: + return fmt.Errorf("認証プロセスがタイムアウトしました") + case <-ticker.C: + b, err := u.http.Execute(gateway.POST) + if err != nil { + return err + } + values, err := url.ParseQuery(string(b)) + if err != nil { + return err + } + accessToken := values.Get("access_token") + if accessToken != "" { + config, err := entity.ReadConfig() + if err != nil { + return err + } + config.WithGithubToken(accessToken) + if err := config.WriteConfig(); err != nil { + return err + } + log.Print("**SSO認証が成功しました**") + return nil + } + if newIntervalStr := values.Get("interval"); newIntervalStr != "" { + newInterval, err := strconv.Atoi(newIntervalStr) + if err != nil { + return err + } + ticker.Stop() + ticker = time.NewTicker(time.Duration(newInterval) * time.Second) + } + } + } +} From 989f014f32bfabf588f3c183c721a8569dac6737 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 22:57:05 +0900 Subject: [PATCH 58/89] feat: logincmd interface --- cmd/login.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 cmd/login.go diff --git a/cmd/login.go b/cmd/login.go new file mode 100644 index 0000000..3dc0873 --- /dev/null +++ b/cmd/login.go @@ -0,0 +1,45 @@ +/* +Copyright © 2023 NAME HERE +*/ +package cmd + +import ( + "fmt" + "github.com/cocoide/commitify/internal/gateway" + "github.com/cocoide/commitify/internal/usecase" + "github.com/fatih/color" + "github.com/spf13/cobra" + "time" +) + +const ( + DeviceActivateURL = "https://github.com/login/device" +) + +var loginCmd = &cobra.Command{ + Use: "login", + Short: "login by github", + Long: `by login you can use auto pull request feature`, + Run: func(cmd *cobra.Command, args []string) { + httpClient := gateway.NewHttpClient() + u := usecase.NewLoginCmdUsecase(httpClient) + res, err := u.BeginGithubSSO() + if err != nil { + fmt.Printf("ログイン中にエラーが発生: %v", err) + } + go func() { + req := &usecase.ScheduleVerifyAuthRequest{ + DeviceCode: res.DeviceCode, Interval: res.Interval, ExpiresIn: res.ExpiresIn} + if err := u.ScheduleVerifyAuth(req); err != nil { + fmt.Printf("error occured: %v", err) + } + }() + fmt.Printf("以下のページで認証コード『%s』を入力して下さい。\n", res.UserCode) + fmt.Printf(color.HiCyanString("➡️ %s\n"), DeviceActivateURL) + time.Sleep(time.Second * time.Duration(res.ExpiresIn)) + }, +} + +func init() { + rootCmd.AddCommand(loginCmd) +} From ad2f7cc554356648f0e8fba5625571b4e1cac97b Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 22:57:27 +0900 Subject: [PATCH 59/89] chore: update entity --- cmd/suggest.go | 2 +- internal/entity/config.go | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index b5bdfd2..bf5e38b 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -129,7 +129,7 @@ func NewSuggestModel() *suggestModel { if err != nil { log.Fatalf("設定ファイルの読み込みができませんでした") } - switch config.WithGptRequestLocation() { + switch config.GptRequestLocation() { case entity.Client: nlp := gateway.NewOpenAIGateway(context.Background()) commitMessageService = gateway.NewClientCommitMessageGateway(nlp) diff --git a/internal/entity/config.go b/internal/entity/config.go index 7a25587..de50fb5 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -38,6 +38,7 @@ type Config struct { UseLanguage int `json:"UseLanguage"` CommitFormat int `json:"CommitFormat"` AISource int `json:"AISource"` + GithubToken string `json:"GithubToken"` } func (c *Config) Config2PbVars() (pb.CodeFormatType, pb.LanguageType) { @@ -81,7 +82,7 @@ func ReadConfig() (Config, error) { return result, nil } -func WriteConfig(config Config) error { +func (c Config) WriteConfig() error { homePath, err := os.UserHomeDir() if err != nil { return err @@ -91,7 +92,7 @@ func WriteConfig(config Config) error { viper.SetConfigName("config") viper.SetConfigType("yaml") configMap := make(map[string]interface{}) - configBytes, err := json.Marshal(config) + configBytes, err := json.Marshal(c) if err != nil { return fmt.Errorf("error marshalling config: %s", err.Error()) } @@ -108,6 +109,11 @@ func WriteConfig(config Config) error { return nil } +func (c *Config) WithGithubToken(token string) *Config { + c.GithubToken = token + return c +} + func SaveConfig(configIndex, updateConfigParamInt int, updateConfigParamStr string) error { currentConfig, err := ReadConfig() if err != nil { @@ -125,7 +131,7 @@ func SaveConfig(configIndex, updateConfigParamInt int, updateConfigParamStr stri currentConfig.AISource = updateConfigParamInt } - err = WriteConfig(currentConfig) + err = currentConfig.WriteConfig() if err != nil { return err } @@ -133,7 +139,7 @@ func SaveConfig(configIndex, updateConfigParamInt int, updateConfigParamStr stri return nil } -func (c *Config) WithGptRequestLocation() GptRequestLocation { +func (c *Config) GptRequestLocation() GptRequestLocation { switch c.AISource { case 0: return Server From b2e091f95e77acb40969c737b9492857c1e7a851 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sun, 10 Dec 2023 23:14:19 +0900 Subject: [PATCH 60/89] =?UTF-8?q?refactor:=20=E5=91=BD=E5=90=8D=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 4 ++-- internal/service/service.go | 2 +- internal/usecase/suggest_cmd.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index bf5e38b..4808e47 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -123,7 +123,7 @@ func NewSuggestModel() *suggestModel { ti.Focus() // suggestコマンドのサービスの取得 - inputOutput := gateway.NewInputOutputGateway() + git := gateway.NewGitGateway() var commitMessageService service.CommitMessageService config, err := entity.ReadConfig() if err != nil { @@ -136,7 +136,7 @@ func NewSuggestModel() *suggestModel { case entity.Server: commitMessageService = gateway.NewGrpcServerGateway() } - suggestCmdUsecase := usecase.NewSuggestCmdUsecase(commitMessageService, inputOutput) + suggestCmdUsecase := usecase.NewSuggestCmdUsecase(commitMessageService, git) return &suggestModel{ choices: []string{""}, diff --git a/internal/service/service.go b/internal/service/service.go index 0fb0bc0..1359b02 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -9,7 +9,7 @@ type CommitMessageService interface { // githubに関するデータのinput/output type GithubService interface { - GetStaginCodeDiff() (string, error) + GetStagingCodeDiff() (string, error) } type NLPService interface { diff --git a/internal/usecase/suggest_cmd.go b/internal/usecase/suggest_cmd.go index 2682011..1782236 100644 --- a/internal/usecase/suggest_cmd.go +++ b/internal/usecase/suggest_cmd.go @@ -18,7 +18,7 @@ func NewSuggestCmdUsecase(message service.CommitMessageService, github service.G } func (u *SuggestCmdUsecase) GenerateCommitMessages() ([]string, error) { - stagingCodeDiff, err := u.github.GetStaginCodeDiff() + stagingCodeDiff, err := u.github.GetStagingCodeDiff() // stagingCodeを取捨選択する処理をここに入れる if err != nil { return nil, err From 1a0dbebfbc13487fb0a9d439e525cae28b68be49 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Mon, 11 Dec 2023 09:14:51 +0900 Subject: [PATCH 61/89] feat: withBody method --- internal/gateway/http_client.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/gateway/http_client.go b/internal/gateway/http_client.go index b918aee..abba682 100644 --- a/internal/gateway/http_client.go +++ b/internal/gateway/http_client.go @@ -1,6 +1,7 @@ package gateway import ( + "bytes" "fmt" "io" "net/http" @@ -28,6 +29,11 @@ func (h *HttpClient) WithBaseURL(baseURL string) *HttpClient { return h } +func (h *HttpClient) WithHeader(key, value string) *HttpClient { + h.Headers[key] = value + return h +} + func (h *HttpClient) WithBearerToken(token string) *HttpClient { h.Headers["Authorization"] = fmt.Sprintf("Bearer %s", token) return h @@ -52,6 +58,11 @@ const ( PUT ) +func (h *HttpClient) WithBody(values []byte) *HttpClient { + h.Body = bytes.NewReader(values) + return h +} + func (h *HttpClient) Execute(method HttpMethod) ([]byte, error) { var methodName string switch method { From 409d709617cc1e08a8bc04a2012c49b5bfde6356 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 03:55:05 +0900 Subject: [PATCH 62/89] feat: GithubService for pull request --- internal/entity/github.go | 12 ++++ internal/gateway/github.go | 111 +++++++++++++++++++++++++++++++++++++ internal/service/github.go | 17 ++++++ 3 files changed, 140 insertions(+) create mode 100644 internal/entity/github.go create mode 100644 internal/gateway/github.go create mode 100644 internal/service/github.go diff --git a/internal/entity/github.go b/internal/entity/github.go new file mode 100644 index 0000000..4e1a602 --- /dev/null +++ b/internal/entity/github.go @@ -0,0 +1,12 @@ +package entity + +type PullRequest struct { + Owner string + Repo string + Title string + Body string + Head string + Base string +} + +type PullRequests []*PullRequest diff --git a/internal/gateway/github.go b/internal/gateway/github.go new file mode 100644 index 0000000..1f83fcb --- /dev/null +++ b/internal/gateway/github.go @@ -0,0 +1,111 @@ +package gateway + +import ( + "encoding/json" + "fmt" + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/service" + "github.com/pkg/errors" + "os/exec" + "strings" +) + +type githubGateway struct { +} + +func NewGithubGateway() service.GithubService { + return &githubGateway{} +} + +func (g *githubGateway) GetStagingCodeDiff() (string, error) { + // Gitが入ってるかどうかのチェックも入れる + // 入っていないなら専用のエラーメッセージを生成 + diff, err := exec.Command("git", "diff", "--staged").Output() + return string(diff), err +} + +func (g *githubGateway) GetCurrentRepoDetails() (*service.GetRepoDetailsResponse, error) { + _, err := exec.LookPath("git") + if err != nil { + return nil, errors.New("git is not installed on the system") + } + output, err := exec.Command("git", "config", "--get", "remote.origin.url").Output() + if err != nil { + return nil, err + } + url := strings.TrimSpace(string(output)) + parts := strings.Split(url, "/") + if len(parts) < 2 { + return nil, errors.New("unable to parse the repository URL") + } + repo := strings.TrimSuffix(parts[len(parts)-1], ".git") + owner := parts[len(parts)-2] + + return &service.GetRepoDetailsResponse{ + Owner: owner, + Repo: repo, + }, nil +} + +func (g *githubGateway) CreatePullRequest(req *entity.PullRequest, token string) error { + type Body struct { + Title string `json:"title"` + Body string `json:"body"` + Head string `json:"head"` + Base string `json:"base"` + } + body := &Body{ + Title: req.Title, + Body: req.Body, + Head: req.Head, + Base: req.Base, + } + b, err := json.Marshal(body) + if err != nil { + return err + } + _, err = NewHttpClient(). + WithBaseURL(fmt.Sprintf("https://api.github.com/repos/%s/%s/pulls", req.Owner, req.Repo)). + WithHeader("Accept", "application/vnd.github+json"). + WithBearerToken(token). + WithBody(b). + Execute(POST) + return err +} + +func (g *githubGateway) GetCurrentBranch() (string, error) { + output, err := exec.Command("git", "branch", "--show-current").Output() + if err != nil { + return "", err + } + return strings.TrimSpace(strings.TrimSpace(string(output))), nil +} + +func (g *githubGateway) GetUnPushedCommits(base string) ([]string, error) { + head, err := g.GetCurrentBranch() + if err != nil { + return nil, err + } + output, err := exec.Command("git", "log", base+".."+head, "--pretty=format:%s").Output() + if err != nil { + return nil, err + } + commits := strings.Split(string(output), "\n") + return commits, nil +} + +func (g *githubGateway) GetRecentUpdatedBranch() ([]string, error) { + var result []string + output, err := exec.Command("git", "for-each-ref", "--sort=-committerdate", "refs/remotes/", "--format=%(refname:short)").Output() + if err != nil { + return nil, err + } + for _, line := range strings.Split(string(output), "\n") { + branch := strings.TrimPrefix(line, "origin/") + if branch == "origin" { + continue + } + result = append(result, branch) + } + return result, nil +} diff --git a/internal/service/github.go b/internal/service/github.go new file mode 100644 index 0000000..f386074 --- /dev/null +++ b/internal/service/github.go @@ -0,0 +1,17 @@ +package service + +import "github.com/cocoide/commitify/internal/entity" + +type GetRepoDetailsResponse struct { + Owner string + Repo string +} + +type GithubService interface { + GetStagingCodeDiff() (string, error) + GetCurrentRepoDetails() (*GetRepoDetailsResponse, error) + CreatePullRequest(pr *entity.PullRequest, token string) error + GetCurrentBranch() (string, error) + GetUnPushedCommits(base string) ([]string, error) + GetRecentUpdatedBranch() ([]string, error) +} From 8d71b6681ff2b8b37460d9d5546212f951afd9cb Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 03:56:04 +0900 Subject: [PATCH 63/89] chore --- cmd/suggest.go | 4 ++-- internal/service/service.go | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index 4808e47..e7b3782 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -123,7 +123,7 @@ func NewSuggestModel() *suggestModel { ti.Focus() // suggestコマンドのサービスの取得 - git := gateway.NewGitGateway() + github := gateway.NewGithubGateway() var commitMessageService service.CommitMessageService config, err := entity.ReadConfig() if err != nil { @@ -136,7 +136,7 @@ func NewSuggestModel() *suggestModel { case entity.Server: commitMessageService = gateway.NewGrpcServerGateway() } - suggestCmdUsecase := usecase.NewSuggestCmdUsecase(commitMessageService, git) + suggestCmdUsecase := usecase.NewSuggestCmdUsecase(commitMessageService, github) return &suggestModel{ choices: []string{""}, diff --git a/internal/service/service.go b/internal/service/service.go index 1359b02..62ac05a 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -7,11 +7,6 @@ type CommitMessageService interface { GenerateCommitMessageList(code string, config entity.Config) ([]string, error) } -// githubに関するデータのinput/output -type GithubService interface { - GetStagingCodeDiff() (string, error) -} - type NLPService interface { GetAnswerFromPrompt(prompt string) (string, error) } From cd9d95ebed50b2a1f200df42733522e1701353ed Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 03:56:23 +0900 Subject: [PATCH 64/89] feat pushCmdUsecase --- internal/usecase/push_cmd.go | 72 ++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 internal/usecase/push_cmd.go diff --git a/internal/usecase/push_cmd.go b/internal/usecase/push_cmd.go new file mode 100644 index 0000000..6ca4a97 --- /dev/null +++ b/internal/usecase/push_cmd.go @@ -0,0 +1,72 @@ +package usecase + +import ( + "fmt" + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/service" + "github.com/pkg/errors" + "strings" +) + +type PushCmdUsecase struct { + github service.GithubService + nlp service.NLPService +} + +const ( + GeneratePRFromCommitsPrompt = "generate pull request content from commit messages [%s] in Japanese" + GeneratePRTitleFromPRBody = "generate pull request title from pr body [%s] in Japanese as one sentence like 〇〇の機能追加" +) + +func NewPushCmdUsecase(github service.GithubService, nlp service.NLPService) *PushCmdUsecase { + return &PushCmdUsecase{github: github, nlp: nlp} +} + +func (u *PushCmdUsecase) GetRemoteBaseBranchCandidates() ([]string, error) { + return u.github.GetRecentUpdatedBranch() +} + +func (u *PushCmdUsecase) GeneratePullRequest(base string) (*entity.PullRequest, error) { + head, err := u.github.GetCurrentBranch() + if err != nil { + return nil, err + } + details, err := u.github.GetCurrentRepoDetails() + if err != nil { + return nil, err + } + commits, err := u.github.GetUnPushedCommits(base) + if err != nil { + return nil, err + } + prBodyPrompt := fmt.Sprintf(GeneratePRFromCommitsPrompt, strings.Join(commits, ", ")) + body, err := u.nlp.GetAnswerFromPrompt(prBodyPrompt) + if err != nil { + return nil, err + } + prTitlePrompt := fmt.Sprintf(GeneratePRTitleFromPRBody, body) + title, err := u.nlp.GetAnswerFromPrompt(prTitlePrompt) + if err != nil { + return nil, err + } + return &entity.PullRequest{ + Head: head, + Base: base, + Body: body, + Title: title, + Repo: details.Repo, + Owner: details.Owner, + }, nil +} + +func (u *PushCmdUsecase) SubmitPullRequest(pr *entity.PullRequest) error { + config, err := entity.ReadConfig() + if err != nil { + return err + } + tkn := config.GithubToken + if tkn == "" { + return errors.New("github token not found") + } + return u.github.CreatePullRequest(pr, tkn) +} From e2adf85e5c832e680f9dae9aea6796649fe39020 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 03:56:36 +0900 Subject: [PATCH 65/89] feat: pushCmdInterface --- cmd/push.go | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 cmd/push.go diff --git a/cmd/push.go b/cmd/push.go new file mode 100644 index 0000000..2a37896 --- /dev/null +++ b/cmd/push.go @@ -0,0 +1,272 @@ +/* +Copyright © 2023 NAME HERE +*/ +package cmd + +import ( + "fmt" + "github.com/charmbracelet/bubbles/spinner" + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/gateway" + "github.com/cocoide/commitify/internal/usecase" + "github.com/fatih/color" + "github.com/spf13/cobra" + "golang.org/x/net/context" + "strings" +) + +type pushModel struct { + step PushCmdStep + selectBaseIndex int + baseList []string + pr *entity.PullRequest + pcu *usecase.PushCmdUsecase + loadMsg string + errMsg string + spinner spinner.Model + prInput *prInput +} + +type prInput struct { + titleInput textinput.Model + bodyInput textinput.Model +} + +type PushCmdStep int + +const ( + SelectBaseBranch PushCmdStep = iota + ConfirmPR + EditPRTitle + EditPRBody + SubmitPR +) + +var _ tea.Model = &pushModel{} + +func (m *pushModel) Init() tea.Cmd { + return nil +} + +type generatePRMsg struct { + pr *entity.PullRequest + err error +} + +func (m *pushModel) generatePRCmd() tea.Cmd { + return func() tea.Msg { + selectBranch := m.baseList[m.selectBaseIndex] + pr, err := m.pcu.GeneratePullRequest(selectBranch) + return generatePRMsg{pr, err} + } +} + +type submitPRMsg struct { + err error +} + +func (m *pushModel) submitPRCmd() tea.Cmd { + return func() tea.Msg { + err := m.pcu.SubmitPullRequest(m.pr) + return submitPRMsg{err} + } +} + +func (m *pushModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyCtrlC, tea.KeyEsc: + return m, tea.Quit + + } + switch m.step { + case SelectBaseBranch: + switch msg.Type { + case tea.KeyUp: + if m.selectBaseIndex > 0 { + m.selectBaseIndex-- + } + case tea.KeyDown: + if m.selectBaseIndex < len(m.baseList)-1 { + m.selectBaseIndex++ + } + case tea.KeyEnter: + m.loadMsg = "PRを生成中..." + return m, m.generatePRCmd() + } + case ConfirmPR: + switch msg.Type { + case tea.KeyTab: + m.step = EditPRTitle + m.focusInPRTitle() + return m, cmd + case tea.KeyEnter: + m.step = SubmitPR + m.loadMsg = "PRを提出中..." + return m, m.submitPRCmd() + } + case EditPRTitle: + cmd = m.updateTitleInput(msg) + switch msg.Type { + case tea.KeyEnter: + m.pr.Title = m.prInput.titleInput.Value() + m.step = EditPRBody + m.focusInPRBody() + return m, cmd + } + case EditPRBody: + cmd = m.updateBodyInput(msg) + switch msg.Type { + case tea.KeyEnter: + m.pr.Body = m.prInput.bodyInput.Value() + m.step = SubmitPR + m.loadMsg = "PRを提出中..." + return m, m.submitPRCmd() + } + } + case generatePRMsg: + if msg.err != nil { + m.errMsg = fmt.Sprintf("🚨PR生成中にエラーが発生: %v", msg.err) + } else { + m.pr = msg.pr + m.step = ConfirmPR + } + m.finishLoading() + case submitPRMsg: + if msg.err != nil { + // リファクタ: github tokenがexpireした時は、loginコマンドを自動実行 + // → tokenがexpireしたときのエラーを調べないといけない... + m.errMsg = fmt.Sprintf("🚨PR提出中にエラーが発生: %v", msg.err) + } + m.finishLoading() + } + return m, nil +} + +func (m *pushModel) View() string { + if m.errMsg != "" { + return m.errMsg + } + if m.loadMsg != "" { + return fmt.Sprintf("\n %s %s\n\n", m.spinner.View(), textStyle(m.loadMsg)) + } + switch m.step { + case SelectBaseBranch: + return m.buildSelectBaseBranchText() + case ConfirmPR: + return color.HiWhiteString("<生成されたPRの確認: TabKeyで編集, EnterでPush>") + fmt.Sprintf("\n\nTitle: %s\n\nBody: %s", m.pr.Title, m.pr.Body) + case EditPRTitle: + return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle: %s\n\nBody: %s", m.prInput.titleInput.View(), m.pr.Body) + case EditPRBody: + return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle: %s\n\nBody: %s", m.pr.Title, m.prInput.bodyInput.View()) + case SubmitPR: + return fmt.Sprintf("**🎉PRの作成に成功**") + } + return "" +} + +func NewPushModel() *pushModel { + ti := textinput.New() + ti.Focus() + var errMsg string + ctx := context.Background() + github := gateway.NewGithubGateway() + nlp := gateway.NewOpenAIGateway(ctx) + pcu := usecase.NewPushCmdUsecase(github, nlp) + baseList, err := pcu.GetRemoteBaseBranchCandidates() + if err != nil { + errMsg = "🚨Baseブランチを取得中にエラーが発生" + } + var maxBaseElements = 5 + var selectedBaseList []string + if len(baseList) < maxBaseElements { + selectedBaseList = baseList[:] + } else { + selectedBaseList = baseList[:maxBaseElements] + } + return &pushModel{ + step: SelectBaseBranch, + baseList: selectedBaseList, + pcu: pcu, + errMsg: errMsg, + loadMsg: "", + prInput: &prInput{ + titleInput: textinput.New(), + bodyInput: textinput.New(), + }, + } +} + +var pushCmd = &cobra.Command{ + Use: "push", + Short: "push and create pull request", + Run: func(cmd *cobra.Command, args []string) { + m := NewPushModel() + m.initSpinner() + p := tea.NewProgram(m) + p.Run() + }, +} + +func init() { + rootCmd.AddCommand(pushCmd) +} + +func (m *pushModel) buildSelectBaseBranchText() string { + var b strings.Builder + b.WriteString(color.HiWhiteString("📢Baseブランチ(Merge先)を選んで下さい\n")) + b.WriteString(color.WhiteString("click ↑↓ to navigate and press Enter to select.\n")) + + for i, base := range m.baseList { + if i == m.selectBaseIndex { + b.WriteString(fmt.Sprintf(color.HiCyanString("➡️ %s\n"), base)) + } else { + b.WriteString(fmt.Sprintf(color.CyanString(" %s\n"), base)) + } + } + return b.String() +} + +func (m *pushModel) finishLoading() { + m.loadMsg = "" +} + +func (m *pushModel) initSpinner() { + m.spinner = spinner.New() + m.spinner.Style = spinnerStyle + m.spinner.Spinner = spinner.Globe +} + +func (m *pushModel) focusInPRTitle() { + input := m.prInput.titleInput + input.Focus() + input.SetValue(m.pr.Title) + input.CharLimit = 100 + input.Width = 100 + m.prInput.titleInput = input +} + +func (m *pushModel) focusInPRBody() { + input := m.prInput.bodyInput + input.Focus() + input.SetValue(m.pr.Body) + input.CharLimit = 1000 + input.Width = 500 + m.prInput.bodyInput = input +} + +func (m *pushModel) updateTitleInput(msg tea.Msg) tea.Cmd { + var cmd tea.Cmd + m.prInput.titleInput, cmd = m.prInput.titleInput.Update(msg) + return cmd +} + +func (m *pushModel) updateBodyInput(msg tea.Msg) tea.Cmd { + var cmd tea.Cmd + m.prInput.bodyInput, cmd = m.prInput.bodyInput.Update(msg) + return cmd +} From ff3f2ad4ba2b499d21605ec81cb36b8d157e624e Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 03:57:08 +0900 Subject: [PATCH 66/89] delete --- internal/gateway/input_output.go | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 internal/gateway/input_output.go diff --git a/internal/gateway/input_output.go b/internal/gateway/input_output.go deleted file mode 100644 index 25bfbb7..0000000 --- a/internal/gateway/input_output.go +++ /dev/null @@ -1,20 +0,0 @@ -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 -} From 617bb06534ba65378429f679839781de0148b551 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 03:57:46 +0900 Subject: [PATCH 67/89] update modules --- go.mod | 3 ++- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c700d69..f8bcbb4 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ 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.6.0 + github.com/pkg/errors v0.9.1 github.com/sashabaranov/go-openai v1.15.2 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 @@ -48,6 +48,7 @@ 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 + github.com/stretchr/testify v1.8.4 // 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 62f959e..ea8c7aa 100644 --- a/go.sum +++ b/go.sum @@ -56,8 +56,6 @@ 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= @@ -182,6 +180,7 @@ github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -218,6 +217,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 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/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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= From a679487eb4b19033cd92877528d263d1ebae0163 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 04:02:33 +0900 Subject: [PATCH 68/89] chore: refactor --- internal/service/{service.go => commit_message.go} | 6 +----- internal/service/github.go | 1 + internal/service/nlp.go | 6 ++++++ 3 files changed, 8 insertions(+), 5 deletions(-) rename internal/service/{service.go => commit_message.go} (53%) create mode 100644 internal/service/nlp.go diff --git a/internal/service/service.go b/internal/service/commit_message.go similarity index 53% rename from internal/service/service.go rename to internal/service/commit_message.go index 62ac05a..90fe0c5 100644 --- a/internal/service/service.go +++ b/internal/service/commit_message.go @@ -2,11 +2,7 @@ package service import "github.com/cocoide/commitify/internal/entity" -// 分割コミットの生成のクライアント側もここに入れていく +//go:generate mockgen -source=commit_message.go -destination=../../mock/commit_message.go type CommitMessageService interface { GenerateCommitMessageList(code string, config entity.Config) ([]string, error) } - -type NLPService interface { - GetAnswerFromPrompt(prompt string) (string, error) -} diff --git a/internal/service/github.go b/internal/service/github.go index f386074..defa6c0 100644 --- a/internal/service/github.go +++ b/internal/service/github.go @@ -7,6 +7,7 @@ type GetRepoDetailsResponse struct { Repo string } +//go:generate mockgen -source=github.go -destination=../../mock/github.go type GithubService interface { GetStagingCodeDiff() (string, error) GetCurrentRepoDetails() (*GetRepoDetailsResponse, error) diff --git a/internal/service/nlp.go b/internal/service/nlp.go new file mode 100644 index 0000000..60b8dec --- /dev/null +++ b/internal/service/nlp.go @@ -0,0 +1,6 @@ +package service + +//go:generate mockgen -source=nlp.go -destination=../../mock/nlp.go +type NLPService interface { + GetAnswerFromPrompt(prompt string) (string, error) +} From f16c5c101b5528c30c5c6892141eadae4f856310 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 04:06:08 +0900 Subject: [PATCH 69/89] autogen mocks --- go.mod | 2 +- go.sum | 10 +--- mock/commit_message.go | 54 +++++++++++++++++ mock/github.go | 129 +++++++++++++++++++++++++++++++++++++++++ mock/nlp.go | 53 +++++++++++++++++ mock/openai.go | 63 -------------------- 6 files changed, 238 insertions(+), 73 deletions(-) create mode 100644 mock/commit_message.go create mode 100644 mock/github.go create mode 100644 mock/nlp.go delete mode 100644 mock/openai.go diff --git a/go.mod b/go.mod index f8bcbb4..52e7d70 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/charmbracelet/bubbletea v0.24.2 github.com/charmbracelet/lipgloss v0.7.1 github.com/fatih/color v1.15.0 - github.com/golang/mock v1.6.0 + github.com/golang/mock v1.4.4 github.com/pkg/errors v0.9.1 github.com/sashabaranov/go-openai v1.15.2 github.com/spf13/cobra v1.7.0 diff --git a/go.sum b/go.sum index ea8c7aa..9eba7b7 100644 --- a/go.sum +++ b/go.sum @@ -86,9 +86,8 @@ 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= @@ -224,7 +223,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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= @@ -271,7 +269,6 @@ 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= @@ -303,7 +300,6 @@ 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= @@ -326,7 +322,6 @@ 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= @@ -361,10 +356,8 @@ 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= @@ -435,7 +428,6 @@ 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/mock/commit_message.go b/mock/commit_message.go new file mode 100644 index 0000000..eafd041 --- /dev/null +++ b/mock/commit_message.go @@ -0,0 +1,54 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: commit_message.go +// +// Generated by this command: +// +// mockgen -source=commit_message.go -destination=../../mock/commit_message.go +// +// Package mock_service is a generated GoMock package. +package mock_service + +import ( + "github.com/golang/mock/gomock" + reflect "reflect" + + entity "github.com/cocoide/commitify/internal/entity" +) + +// MockCommitMessageService is a mock of CommitMessageService interface. +type MockCommitMessageService struct { + ctrl *gomock.Controller + recorder *MockCommitMessageServiceMockRecorder +} + +// MockCommitMessageServiceMockRecorder is the mock recorder for MockCommitMessageService. +type MockCommitMessageServiceMockRecorder struct { + mock *MockCommitMessageService +} + +// NewMockCommitMessageService creates a new mock instance. +func NewMockCommitMessageService(ctrl *gomock.Controller) *MockCommitMessageService { + mock := &MockCommitMessageService{ctrl: ctrl} + mock.recorder = &MockCommitMessageServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCommitMessageService) EXPECT() *MockCommitMessageServiceMockRecorder { + return m.recorder +} + +// GenerateCommitMessageList mocks base method. +func (m *MockCommitMessageService) GenerateCommitMessageList(code string, config entity.Config) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GenerateCommitMessageList", code, config) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GenerateCommitMessageList indicates an expected call of GenerateCommitMessageList. +func (mr *MockCommitMessageServiceMockRecorder) GenerateCommitMessageList(code, config any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenerateCommitMessageList", reflect.TypeOf((*MockCommitMessageService)(nil).GenerateCommitMessageList), code, config) +} diff --git a/mock/github.go b/mock/github.go new file mode 100644 index 0000000..ecdcb7f --- /dev/null +++ b/mock/github.go @@ -0,0 +1,129 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.go +// +// Generated by this command: +// +// mockgen -source=github.go -destination=../../mock/github.go +// +// Package mock_service is a generated GoMock package. +package mock_service + +import ( + "github.com/golang/mock/gomock" + reflect "reflect" + + entity "github.com/cocoide/commitify/internal/entity" + service "github.com/cocoide/commitify/internal/service" +) + +// MockGithubService is a mock of GithubService interface. +type MockGithubService struct { + ctrl *gomock.Controller + recorder *MockGithubServiceMockRecorder +} + +// MockGithubServiceMockRecorder is the mock recorder for MockGithubService. +type MockGithubServiceMockRecorder struct { + mock *MockGithubService +} + +// NewMockGithubService creates a new mock instance. +func NewMockGithubService(ctrl *gomock.Controller) *MockGithubService { + mock := &MockGithubService{ctrl: ctrl} + mock.recorder = &MockGithubServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockGithubService) EXPECT() *MockGithubServiceMockRecorder { + return m.recorder +} + +// CreatePullRequest mocks base method. +func (m *MockGithubService) CreatePullRequest(pr *entity.PullRequest, token string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreatePullRequest", pr, token) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreatePullRequest indicates an expected call of CreatePullRequest. +func (mr *MockGithubServiceMockRecorder) CreatePullRequest(pr, token any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatePullRequest", reflect.TypeOf((*MockGithubService)(nil).CreatePullRequest), pr, token) +} + +// GetCurrentBranch mocks base method. +func (m *MockGithubService) GetCurrentBranch() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentBranch") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentBranch indicates an expected call of GetCurrentBranch. +func (mr *MockGithubServiceMockRecorder) GetCurrentBranch() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentBranch", reflect.TypeOf((*MockGithubService)(nil).GetCurrentBranch)) +} + +// GetCurrentRepoDetails mocks base method. +func (m *MockGithubService) GetCurrentRepoDetails() (*service.GetRepoDetailsResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentRepoDetails") + ret0, _ := ret[0].(*service.GetRepoDetailsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentRepoDetails indicates an expected call of GetCurrentRepoDetails. +func (mr *MockGithubServiceMockRecorder) GetCurrentRepoDetails() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentRepoDetails", reflect.TypeOf((*MockGithubService)(nil).GetCurrentRepoDetails)) +} + +// GetRecentUpdatedBranch mocks base method. +func (m *MockGithubService) GetRecentUpdatedBranch() ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRecentUpdatedBranch") + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRecentUpdatedBranch indicates an expected call of GetRecentUpdatedBranch. +func (mr *MockGithubServiceMockRecorder) GetRecentUpdatedBranch() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRecentUpdatedBranch", reflect.TypeOf((*MockGithubService)(nil).GetRecentUpdatedBranch)) +} + +// GetStagingCodeDiff mocks base method. +func (m *MockGithubService) GetStagingCodeDiff() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStagingCodeDiff") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStagingCodeDiff indicates an expected call of GetStagingCodeDiff. +func (mr *MockGithubServiceMockRecorder) GetStagingCodeDiff() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStagingCodeDiff", reflect.TypeOf((*MockGithubService)(nil).GetStagingCodeDiff)) +} + +// GetUnPushedCommits mocks base method. +func (m *MockGithubService) GetUnPushedCommits(base string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUnPushedCommits", base) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUnPushedCommits indicates an expected call of GetUnPushedCommits. +func (mr *MockGithubServiceMockRecorder) GetUnPushedCommits(base any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnPushedCommits", reflect.TypeOf((*MockGithubService)(nil).GetUnPushedCommits), base) +} diff --git a/mock/nlp.go b/mock/nlp.go new file mode 100644 index 0000000..6a445bd --- /dev/null +++ b/mock/nlp.go @@ -0,0 +1,53 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: nlp.go +// +// Generated by this command: +// +// mockgen -source=nlp.go -destination=../../mock/nlp.go +// +// Package mock_service is a generated GoMock package. +package mock_service + +import ( + reflect "reflect" + + "github.com/golang/mock/gomock" +) + +// MockNLPService is a mock of NLPService interface. +type MockNLPService struct { + ctrl *gomock.Controller + recorder *MockNLPServiceMockRecorder +} + +// MockNLPServiceMockRecorder is the mock recorder for MockNLPService. +type MockNLPServiceMockRecorder struct { + mock *MockNLPService +} + +// NewMockNLPService creates a new mock instance. +func NewMockNLPService(ctrl *gomock.Controller) *MockNLPService { + mock := &MockNLPService{ctrl: ctrl} + mock.recorder = &MockNLPServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockNLPService) EXPECT() *MockNLPServiceMockRecorder { + return m.recorder +} + +// GetAnswerFromPrompt mocks base method. +func (m *MockNLPService) GetAnswerFromPrompt(prompt string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAnswerFromPrompt", prompt) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAnswerFromPrompt indicates an expected call of GetAnswerFromPrompt. +func (mr *MockNLPServiceMockRecorder) GetAnswerFromPrompt(prompt any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAnswerFromPrompt", reflect.TypeOf((*MockNLPService)(nil).GetAnswerFromPrompt), prompt) +} diff --git a/mock/openai.go b/mock/openai.go deleted file mode 100644 index 78f7b68..0000000 --- a/mock/openai.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: openai.go - -// Package mock_gateway is a generated GoMock package. -package mock_gateway - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" -) - -// MockOpenAIGateway is a mock of OpenAIGateway interface. -type MockOpenAIGateway struct { - ctrl *gomock.Controller - recorder *MockOpenAIGatewayMockRecorder -} - -// MockOpenAIGatewayMockRecorder is the mock recorder for MockOpenAIGateway. -type MockOpenAIGatewayMockRecorder struct { - mock *MockOpenAIGateway -} - -// NewMockOpenAIGateway creates a new mock instance. -func NewMockOpenAIGateway(ctrl *gomock.Controller) *MockOpenAIGateway { - mock := &MockOpenAIGateway{ctrl: ctrl} - mock.recorder = &MockOpenAIGatewayMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockOpenAIGateway) EXPECT() *MockOpenAIGatewayMockRecorder { - return m.recorder -} - -// AsyncGetAnswerFromPrompt mocks base method. -func (m *MockOpenAIGateway) AsyncGetAnswerFromPrompt(prompt string, variability float32) <-chan string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AsyncGetAnswerFromPrompt", prompt, variability) - ret0, _ := ret[0].(<-chan string) - return ret0 -} - -// AsyncGetAnswerFromPrompt indicates an expected call of AsyncGetAnswerFromPrompt. -func (mr *MockOpenAIGatewayMockRecorder) AsyncGetAnswerFromPrompt(prompt, variability interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AsyncGetAnswerFromPrompt", reflect.TypeOf((*MockOpenAIGateway)(nil).AsyncGetAnswerFromPrompt), prompt, variability) -} - -// GetAnswerFromPrompt mocks base method. -func (m *MockOpenAIGateway) GetAnswerFromPrompt(prompt string, variability float32) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAnswerFromPrompt", prompt, variability) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAnswerFromPrompt indicates an expected call of GetAnswerFromPrompt. -func (mr *MockOpenAIGatewayMockRecorder) GetAnswerFromPrompt(prompt, variability interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAnswerFromPrompt", reflect.TypeOf((*MockOpenAIGateway)(nil).GetAnswerFromPrompt), prompt, variability) -} From e4882fe4b563b0316dfff8b8a86a4bb3668f5fd6 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 04:22:13 +0900 Subject: [PATCH 70/89] update push cmd interface --- cmd/push.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/push.go b/cmd/push.go index 2a37896..ff400e3 100644 --- a/cmd/push.go +++ b/cmd/push.go @@ -6,6 +6,7 @@ package cmd import ( "fmt" "github.com/charmbracelet/bubbles/spinner" + "github.com/charmbracelet/bubbles/textarea" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/cocoide/commitify/internal/entity" @@ -31,7 +32,7 @@ type pushModel struct { type prInput struct { titleInput textinput.Model - bodyInput textinput.Model + bodyInput textarea.Model } type PushCmdStep int @@ -158,11 +159,11 @@ func (m *pushModel) View() string { case SelectBaseBranch: return m.buildSelectBaseBranchText() case ConfirmPR: - return color.HiWhiteString("<生成されたPRの確認: TabKeyで編集, EnterでPush>") + fmt.Sprintf("\n\nTitle: %s\n\nBody: %s", m.pr.Title, m.pr.Body) + return color.HiWhiteString("<生成されたPRの確認: TabKeyで編集, EnterでPush>") + fmt.Sprintf("\n\nTitle:\n%s\n\nBody:\n%s", m.pr.Title, m.pr.Body) case EditPRTitle: - return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle: %s\n\nBody: %s", m.prInput.titleInput.View(), m.pr.Body) + return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle:\n%s\n\nBody:\n%s", m.prInput.titleInput.View(), m.pr.Body) case EditPRBody: - return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle: %s\n\nBody: %s", m.pr.Title, m.prInput.bodyInput.View()) + return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle:\n%s\n\nBody:\n%s", m.pr.Title, m.prInput.bodyInput.View()) case SubmitPR: return fmt.Sprintf("**🎉PRの作成に成功**") } @@ -196,7 +197,7 @@ func NewPushModel() *pushModel { loadMsg: "", prInput: &prInput{ titleInput: textinput.New(), - bodyInput: textinput.New(), + bodyInput: textarea.New(), }, } } @@ -255,7 +256,8 @@ func (m *pushModel) focusInPRBody() { input.Focus() input.SetValue(m.pr.Body) input.CharLimit = 1000 - input.Width = 500 + input.SetWidth(100) + input.SetHeight(len(m.pr.Body) / 100) m.prInput.bodyInput = input } From 8fdb8bffa2164b3da800f25c6d6827b9608235d6 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Fri, 15 Dec 2023 21:16:43 +0900 Subject: [PATCH 71/89] update push cmd interface --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d277b14..e6cbe87 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ go.work # Environment variables .env dist/ -config.yaml \ No newline at end of file +config.yaml +.idea \ No newline at end of file From 2ddf00a668c63d953e08e5ad3a2fde9eb3af673a Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 02:12:23 +0900 Subject: [PATCH 72/89] make params private --- internal/gateway/http_client.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/gateway/http_client.go b/internal/gateway/http_client.go index b918aee..283183e 100644 --- a/internal/gateway/http_client.go +++ b/internal/gateway/http_client.go @@ -8,38 +8,38 @@ import ( ) type HttpClient struct { - Client *http.Client - Endpoint string - Headers map[string]string - Params map[string]interface{} - Body io.Reader + client *http.Client + endpoint string + headers map[string]string + params map[string]interface{} + body io.Reader } func NewHttpClient() *HttpClient { return &HttpClient{ - Client: &http.Client{}, - Headers: make(map[string]string), - Params: make(map[string]interface{}), + client: &http.Client{}, + headers: make(map[string]string), + params: make(map[string]interface{}), } } func (h *HttpClient) WithBaseURL(baseURL string) *HttpClient { - h.Endpoint = baseURL + h.endpoint = baseURL return h } func (h *HttpClient) WithBearerToken(token string) *HttpClient { - h.Headers["Authorization"] = fmt.Sprintf("Bearer %s", token) + h.headers["Authorization"] = fmt.Sprintf("Bearer %s", token) return h } func (h *HttpClient) WithPath(path string) *HttpClient { - h.Endpoint = h.Endpoint + "/" + path + h.endpoint = h.endpoint + "/" + path return h } func (h *HttpClient) WithParam(key string, value interface{}) *HttpClient { - h.Params[key] = value + h.params[key] = value return h } @@ -64,19 +64,19 @@ func (h *HttpClient) Execute(method HttpMethod) ([]byte, error) { case PUT: methodName = "PUT" } - client := h.Client + client := h.client - req, err := http.NewRequest(methodName, h.Endpoint, h.Body) + req, err := http.NewRequest(methodName, h.endpoint, h.body) if err != nil { return nil, err } - for k, v := range h.Headers { + for k, v := range h.headers { req.Header.Add(k, v) } query := req.URL.Query() - for key, value := range h.Params { + for key, value := range h.params { switch v := value.(type) { case string: query.Add(key, v) From d5631cd62c6f13db3081b1cfc71eef6630e65ce0 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 02:20:12 +0900 Subject: [PATCH 73/89] fix --- internal/gateway/http_client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/gateway/http_client.go b/internal/gateway/http_client.go index b4ca831..a80e46d 100644 --- a/internal/gateway/http_client.go +++ b/internal/gateway/http_client.go @@ -30,7 +30,7 @@ func (h *HttpClient) WithBaseURL(baseURL string) *HttpClient { } func (h *HttpClient) WithHeader(key, value string) *HttpClient { - h.Headers[key] = value + h.headers[key] = value return h } @@ -59,7 +59,7 @@ const ( ) func (h *HttpClient) WithBody(values []byte) *HttpClient { - h.Body = bytes.NewReader(values) + h.body = bytes.NewReader(values) return h } From 35677c6ccd65e9e1a2bf1635df8e644307a0baff Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 02:33:13 +0900 Subject: [PATCH 74/89] =?UTF-8?q?refactor=E3=80=80=E9=9D=9E=E5=90=8C?= =?UTF-8?q?=E6=9C=9F=E5=87=A6=E7=90=86=E3=81=AEUI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/login.go | 23 ++++++++++++++++++----- internal/usecase/login_cmd.go | 2 -- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cmd/login.go b/cmd/login.go index 3dc0873..6de9bea 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -9,7 +9,7 @@ import ( "github.com/cocoide/commitify/internal/usecase" "github.com/fatih/color" "github.com/spf13/cobra" - "time" + "sync" ) const ( @@ -27,16 +27,29 @@ var loginCmd = &cobra.Command{ if err != nil { fmt.Printf("ログイン中にエラーが発生: %v", err) } + + var wg sync.WaitGroup + wg.Add(1) + + errChan := make(chan error, 1) + go func() { + defer wg.Done() + req := &usecase.ScheduleVerifyAuthRequest{ DeviceCode: res.DeviceCode, Interval: res.Interval, ExpiresIn: res.ExpiresIn} - if err := u.ScheduleVerifyAuth(req); err != nil { - fmt.Printf("error occured: %v", err) - } + err := u.ScheduleVerifyAuth(req) + errChan <- err }() fmt.Printf("以下のページで認証コード『%s』を入力して下さい。\n", res.UserCode) fmt.Printf(color.HiCyanString("➡️ %s\n"), DeviceActivateURL) - time.Sleep(time.Second * time.Duration(res.ExpiresIn)) + wg.Wait() + err = <-errChan + if err != nil { + fmt.Printf("🚨認証エラーが発生: %v", err) + } else { + fmt.Printf("**🎉認証が正常に完了**") + } }, } diff --git a/internal/usecase/login_cmd.go b/internal/usecase/login_cmd.go index 495d6c4..fe76056 100644 --- a/internal/usecase/login_cmd.go +++ b/internal/usecase/login_cmd.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/gateway" - "log" "net/url" "strconv" "time" @@ -106,7 +105,6 @@ func (u *LoginCmdUsecase) ScheduleVerifyAuth(req *ScheduleVerifyAuthRequest) err if err := config.WriteConfig(); err != nil { return err } - log.Print("**SSO認証が成功しました**") return nil } if newIntervalStr := values.Get("interval"); newIntervalStr != "" { From a88556ec5e36e7fdf5aaad0485f279edb45b9280 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 02:54:18 +0900 Subject: [PATCH 75/89] fix api header --- internal/gateway/github.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/gateway/github.go b/internal/gateway/github.go index 1f83fcb..387a021 100644 --- a/internal/gateway/github.go +++ b/internal/gateway/github.go @@ -67,6 +67,7 @@ func (g *githubGateway) CreatePullRequest(req *entity.PullRequest, token string) _, err = NewHttpClient(). WithBaseURL(fmt.Sprintf("https://api.github.com/repos/%s/%s/pulls", req.Owner, req.Repo)). WithHeader("Accept", "application/vnd.github+json"). + WithHeader("X-GitHub-Api-Version", "2022-11-28"). WithBearerToken(token). WithBody(b). Execute(POST) From 8b042a54383bba733852c2254c2beea46a4d5a80 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 03:14:40 +0900 Subject: [PATCH 76/89] refactor --- internal/gateway/github.go | 7 ++++--- internal/gateway/http_client.go | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/gateway/github.go b/internal/gateway/github.go index 387a021..fd85382 100644 --- a/internal/gateway/github.go +++ b/internal/gateway/github.go @@ -11,10 +11,11 @@ import ( ) type githubGateway struct { + client *HttpClient } -func NewGithubGateway() service.GithubService { - return &githubGateway{} +func NewGithubGateway(client *HttpClient) service.GithubService { + return &githubGateway{client: client} } func (g *githubGateway) GetStagingCodeDiff() (string, error) { @@ -64,7 +65,7 @@ func (g *githubGateway) CreatePullRequest(req *entity.PullRequest, token string) if err != nil { return err } - _, err = NewHttpClient(). + _, err = g.client. WithBaseURL(fmt.Sprintf("https://api.github.com/repos/%s/%s/pulls", req.Owner, req.Repo)). WithHeader("Accept", "application/vnd.github+json"). WithHeader("X-GitHub-Api-Version", "2022-11-28"). diff --git a/internal/gateway/http_client.go b/internal/gateway/http_client.go index a80e46d..7fdea78 100644 --- a/internal/gateway/http_client.go +++ b/internal/gateway/http_client.go @@ -110,5 +110,9 @@ func (h *HttpClient) Execute(method HttpMethod) ([]byte, error) { if err != nil { return nil, err } + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return nil, fmt.Errorf("request failed with status code: %d, resBody: %v", resp.StatusCode, string(body)) + } return body, nil } From d23debf521c66b68ce75d29d28e1cfde5cd94a41 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 03:14:47 +0900 Subject: [PATCH 77/89] feat test --- internal/gateway/github_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 internal/gateway/github_test.go diff --git a/internal/gateway/github_test.go b/internal/gateway/github_test.go new file mode 100644 index 0000000..0939a9f --- /dev/null +++ b/internal/gateway/github_test.go @@ -0,0 +1,26 @@ +package gateway + +import ( + "github.com/cocoide/commitify/internal/entity" + "log" + "testing" +) + +const ( + TestHeadBranch = "temp/test-auto-pr" +) + +func Test_CreatePullRequest(t *testing.T) { + conf, err := entity.ReadConfig() + if err != nil { + log.Fatal(err) + } + tkn := conf.GithubToken + http := NewHttpClient() + pr := &entity.PullRequest{ + Owner: "cocoide", Repo: "commitify", Title: "test title", Body: "test body", Head: TestHeadBranch, Base: "main"} + u := NewGithubGateway(http) + if err := u.CreatePullRequest(pr, tkn); err != nil { + t.Error(err) + } +} From 2a9453b6343a3bbe9b55a17a2f328272aa4aa19b Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 03:19:34 +0900 Subject: [PATCH 78/89] refactor --- cmd/suggest.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index e7b3782..a658b84 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -123,7 +123,8 @@ func NewSuggestModel() *suggestModel { ti.Focus() // suggestコマンドのサービスの取得 - github := gateway.NewGithubGateway() + http := gateway.NewHttpClient() + github := gateway.NewGithubGateway(http) var commitMessageService service.CommitMessageService config, err := entity.ReadConfig() if err != nil { From 75fe915c6d0d1367f0472499c363423ab3cdb2d6 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 03:31:01 +0900 Subject: [PATCH 79/89] refactor --- cmd/suggest.go | 3 +-- internal/gateway/github.go | 4 ++-- internal/gateway/github_test.go | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cmd/suggest.go b/cmd/suggest.go index a658b84..e7b3782 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -123,8 +123,7 @@ func NewSuggestModel() *suggestModel { ti.Focus() // suggestコマンドのサービスの取得 - http := gateway.NewHttpClient() - github := gateway.NewGithubGateway(http) + github := gateway.NewGithubGateway() var commitMessageService service.CommitMessageService config, err := entity.ReadConfig() if err != nil { diff --git a/internal/gateway/github.go b/internal/gateway/github.go index fd85382..e11886e 100644 --- a/internal/gateway/github.go +++ b/internal/gateway/github.go @@ -14,8 +14,8 @@ type githubGateway struct { client *HttpClient } -func NewGithubGateway(client *HttpClient) service.GithubService { - return &githubGateway{client: client} +func NewGithubGateway() service.GithubService { + return &githubGateway{client: NewHttpClient()} } func (g *githubGateway) GetStagingCodeDiff() (string, error) { diff --git a/internal/gateway/github_test.go b/internal/gateway/github_test.go index 0939a9f..01f4f93 100644 --- a/internal/gateway/github_test.go +++ b/internal/gateway/github_test.go @@ -16,10 +16,9 @@ func Test_CreatePullRequest(t *testing.T) { log.Fatal(err) } tkn := conf.GithubToken - http := NewHttpClient() pr := &entity.PullRequest{ Owner: "cocoide", Repo: "commitify", Title: "test title", Body: "test body", Head: TestHeadBranch, Base: "main"} - u := NewGithubGateway(http) + u := NewGithubGateway() if err := u.CreatePullRequest(pr, tkn); err != nil { t.Error(err) } From 9a4af6eca1583ccb119d051eb238e7d48294176e Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 03:40:19 +0900 Subject: [PATCH 80/89] comment --- internal/gateway/github.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/gateway/github.go b/internal/gateway/github.go index e11886e..ecb2a3b 100644 --- a/internal/gateway/github.go +++ b/internal/gateway/github.go @@ -65,6 +65,7 @@ func (g *githubGateway) CreatePullRequest(req *entity.PullRequest, token string) if err != nil { return err } + // API参照ドキュメント: https://docs.github.com/ja/rest/pulls/pulls?apiVersion=2022-11-28#create-a-pull-request--code-samples _, err = g.client. WithBaseURL(fmt.Sprintf("https://api.github.com/repos/%s/%s/pulls", req.Owner, req.Repo)). WithHeader("Accept", "application/vnd.github+json"). @@ -111,3 +112,7 @@ func (g *githubGateway) GetRecentUpdatedBranch() ([]string, error) { } return result, nil } + +func (g *githubGateway) ExecPush(base string) ([]string, error) { + +} From 39ea8c34d6070985839f3c3ea41d1e6559ae34ee Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 03:55:16 +0900 Subject: [PATCH 81/89] feat: pushCurrentBranch method --- internal/gateway/github.go | 11 +++++++++-- internal/service/github.go | 1 + internal/usecase/push_cmd.go | 4 ++++ mock/github.go | 16 +++++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/internal/gateway/github.go b/internal/gateway/github.go index ecb2a3b..66285b7 100644 --- a/internal/gateway/github.go +++ b/internal/gateway/github.go @@ -113,6 +113,13 @@ func (g *githubGateway) GetRecentUpdatedBranch() ([]string, error) { return result, nil } -func (g *githubGateway) ExecPush(base string) ([]string, error) { - +func (g *githubGateway) PushCurrentBranch() error { + head, err := g.GetCurrentBranch() + if err != nil { + return err + } + if _, err = exec.Command("git", "push", "origin", head).Output(); err != nil { + return fmt.Errorf("failed to push branch %s: %w", head, err) + } + return nil } diff --git a/internal/service/github.go b/internal/service/github.go index defa6c0..8d87e98 100644 --- a/internal/service/github.go +++ b/internal/service/github.go @@ -15,4 +15,5 @@ type GithubService interface { GetCurrentBranch() (string, error) GetUnPushedCommits(base string) ([]string, error) GetRecentUpdatedBranch() ([]string, error) + PushCurrentBranch() error } diff --git a/internal/usecase/push_cmd.go b/internal/usecase/push_cmd.go index 6ca4a97..7020428 100644 --- a/internal/usecase/push_cmd.go +++ b/internal/usecase/push_cmd.go @@ -60,6 +60,10 @@ func (u *PushCmdUsecase) GeneratePullRequest(base string) (*entity.PullRequest, } func (u *PushCmdUsecase) SubmitPullRequest(pr *entity.PullRequest) error { + if err := u.github.PushCurrentBranch(); err != nil { + return err + } + // CurrentブランチにPRが作成されてる場合以下は実行しない仕様にしたい(エラーが発生するので) config, err := entity.ReadConfig() if err != nil { return err diff --git a/mock/github.go b/mock/github.go index ecdcb7f..aa2aa83 100644 --- a/mock/github.go +++ b/mock/github.go @@ -9,11 +9,11 @@ package mock_service import ( - "github.com/golang/mock/gomock" reflect "reflect" entity "github.com/cocoide/commitify/internal/entity" service "github.com/cocoide/commitify/internal/service" + gomock "go.uber.org/mock/gomock" ) // MockGithubService is a mock of GithubService interface. @@ -127,3 +127,17 @@ func (mr *MockGithubServiceMockRecorder) GetUnPushedCommits(base any) *gomock.Ca mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnPushedCommits", reflect.TypeOf((*MockGithubService)(nil).GetUnPushedCommits), base) } + +// PushCurrentBranch mocks base method. +func (m *MockGithubService) PushCurrentBranch() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PushCurrentBranch") + ret0, _ := ret[0].(error) + return ret0 +} + +// PushCurrentBranch indicates an expected call of PushCurrentBranch. +func (mr *MockGithubServiceMockRecorder) PushCurrentBranch() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushCurrentBranch", reflect.TypeOf((*MockGithubService)(nil).PushCurrentBranch)) +} From c0ac1e578bbb4d9dfb3de7c9a9b67498f7eaac79 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sat, 16 Dec 2023 05:46:39 +0900 Subject: [PATCH 82/89] =?UTF-8?q?fix:=20=E3=82=B3=E3=83=9E=E3=83=B3?= =?UTF-8?q?=E3=83=89=E3=81=AE=E5=87=BA=E5=8A=9B=E3=81=AB=E6=94=B9=E8=A1=8C?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/login.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/login.go b/cmd/login.go index 6de9bea..3c46be8 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -5,11 +5,12 @@ package cmd import ( "fmt" + "sync" + "github.com/cocoide/commitify/internal/gateway" "github.com/cocoide/commitify/internal/usecase" "github.com/fatih/color" "github.com/spf13/cobra" - "sync" ) const ( @@ -48,7 +49,7 @@ var loginCmd = &cobra.Command{ if err != nil { fmt.Printf("🚨認証エラーが発生: %v", err) } else { - fmt.Printf("**🎉認証が正常に完了**") + fmt.Printf("**🎉認証が正常に完了**\n") } }, } From e4410c573c5aa5325934254184d2bbacbcc0f1de Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sat, 16 Dec 2023 08:31:59 +0900 Subject: [PATCH 83/89] =?UTF-8?q?feat:=20=E3=82=B3=E3=83=B3=E3=83=95?= =?UTF-8?q?=E3=82=A3=E3=82=B0=E3=81=AE=E9=A0=85=E7=9B=AE=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config.go | 4 ++-- go.mod | 1 + go.sum | 2 ++ internal/entity/config.go | 9 ++++++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index 217ef48..b0e95b0 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -18,13 +18,13 @@ var ( {}, {int(entity.EN), int(entity.JP)}, {int(entity.NormalFormat), int(entity.EmojiFormat), int(entity.PrefixFormat)}, - {int(entity.Server), int(entity.Client)}, + {int(entity.Server), int(entity.Client), int(entity.Qdrant), int(entity.Gemini)}, } configOptionLabel = [][]string{ {}, {"English", "Japanese"}, {"Normal Format", "Emoji Format", "PrefixFormat"}, - {"Wrap Server", "OpenAI API"}, + {"Wrap Server", "OpenAI API", "Qdrant Database", "Gemini API"}, } ) diff --git a/go.mod b/go.mod index 52e7d70..caa3f7d 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/sashabaranov/go-openai v1.15.2 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 + go.uber.org/mock v0.3.0 golang.org/x/net v0.15.0 google.golang.org/grpc v1.58.0 google.golang.org/protobuf v1.31.0 diff --git a/go.sum b/go.sum index 9eba7b7..b69ce55 100644 --- a/go.sum +++ b/go.sum @@ -229,6 +229,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/internal/entity/config.go b/internal/entity/config.go index de50fb5..999c68c 100644 --- a/internal/entity/config.go +++ b/internal/entity/config.go @@ -3,9 +3,10 @@ package entity import ( "encoding/json" "fmt" + "os" + pb "github.com/cocoide/commitify/proto/gen" "github.com/spf13/viper" - "os" ) // コミットメッセージの言語の列挙型 @@ -31,6 +32,8 @@ type GptRequestLocation int const ( Server GptRequestLocation = iota Client + Qdrant + Gemini ) type Config struct { @@ -145,6 +148,10 @@ func (c *Config) GptRequestLocation() GptRequestLocation { return Server case 1: return Client + case 2: + return Qdrant + case 3: + return Gemini default: return Server } From b9f4dbce0d3ac24d20eb50640ab89a16eedf8dac Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sat, 16 Dec 2023 08:32:21 +0900 Subject: [PATCH 84/89] =?UTF-8?q?feat:=20=E3=82=B3=E3=83=9F=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=AE?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=85=83=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/suggest.go | 11 +++++--- internal/gateway/gemini.go | 53 +++++++++++++++++++++++++++++++++++++ internal/gateway/qdrant.go | 54 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 internal/gateway/gemini.go create mode 100644 internal/gateway/qdrant.go diff --git a/cmd/suggest.go b/cmd/suggest.go index e7b3782..6c2acd9 100644 --- a/cmd/suggest.go +++ b/cmd/suggest.go @@ -2,14 +2,15 @@ package cmd import ( "fmt" + "log" + "os" + "strings" + "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" "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/textinput" @@ -135,6 +136,10 @@ func NewSuggestModel() *suggestModel { commitMessageService = gateway.NewClientCommitMessageGateway(nlp) case entity.Server: commitMessageService = gateway.NewGrpcServerGateway() + case entity.Qdrant: + commitMessageService = gateway.NewQdrantServerGateway() + case entity.Gemini: + commitMessageService = gateway.NewGeminiServerGateway() } suggestCmdUsecase := usecase.NewSuggestCmdUsecase(commitMessageService, github) diff --git a/internal/gateway/gemini.go b/internal/gateway/gemini.go new file mode 100644 index 0000000..dfcf5b1 --- /dev/null +++ b/internal/gateway/gemini.go @@ -0,0 +1,53 @@ +package gateway + +import ( + "encoding/json" + "fmt" + + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/service" +) + +type geminiServerGateway struct { + client *HttpClient +} + +func NewGeminiServerGateway() service.CommitMessageService { + c := NewHttpClient(). + WithBaseURL("http://suwageeks.org:5215"). + WithPath("/gemini"). + WithHeader("Content-Type", "application/json") + + return &geminiServerGateway{client: c} +} + +func (qs *geminiServerGateway) GenerateCommitMessageList(diff string, conf entity.Config) ([]string, error) { + type geminiBody struct { + Diff string `json:"diff"` + } + + body := &geminiBody{ + Diff: diff, + } + b, err := json.Marshal(body) + if err != nil { + return nil, err + } + + res, err := qs.client.WithBody(b).Execute(POST) + if err != nil { + return nil, err + } + fmt.Print(string(res)) + + type geminiResponse struct { + Messages []string `json:"messages"` + } + + values := new(geminiResponse) + if err = json.Unmarshal(res, values); err != nil { + return nil, err + } + + return values.Messages, nil +} diff --git a/internal/gateway/qdrant.go b/internal/gateway/qdrant.go new file mode 100644 index 0000000..ca90091 --- /dev/null +++ b/internal/gateway/qdrant.go @@ -0,0 +1,54 @@ +package gateway + +import ( + "encoding/json" + "fmt" + + "github.com/cocoide/commitify/internal/entity" + "github.com/cocoide/commitify/internal/service" +) + +type qdrantServerGateway struct { + client *HttpClient +} + +func NewQdrantServerGateway() service.CommitMessageService { + c := NewHttpClient() + + return &qdrantServerGateway{client: c} +} + +func (qs *qdrantServerGateway) GenerateCommitMessageList(diff string, conf entity.Config) ([]string, error) { + type qdrantBody struct { + Diff string `json:"diff"` + } + + body := &qdrantBody{ + Diff: diff, + } + b, err := json.Marshal(body) + if err != nil { + return nil, err + } + + res, err := qs.client. + WithBaseURL("http://suwageeks.org:5215"). + WithPath("/search"). + WithHeader("Content-Type", "application/json"). + WithBody(b).Execute(POST) + if err != nil { + return nil, err + } + fmt.Print(string(res)) + + type qdrantResponse struct { + Messages []string `json:"messages"` + } + + values := new(qdrantResponse) + if err = json.Unmarshal(res, values); err != nil { + return nil, err + } + + return values.Messages, nil +} From 6507d4c4ffd104e6b70804e3e97447a99ccbc63e Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 09:04:21 +0900 Subject: [PATCH 85/89] fix import --- mock/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/github.go b/mock/github.go index aa2aa83..6713c95 100644 --- a/mock/github.go +++ b/mock/github.go @@ -13,7 +13,7 @@ import ( entity "github.com/cocoide/commitify/internal/entity" service "github.com/cocoide/commitify/internal/service" - gomock "go.uber.org/mock/gomock" + "github.com/golang/mock/gomock" ) // MockGithubService is a mock of GithubService interface. From 4b3811655b5dd9dd95810ad6fd6692deebac5134 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sat, 16 Dec 2023 09:45:28 +0900 Subject: [PATCH 86/89] =?UTF-8?q?fix:=20=E3=83=87=E3=83=90=E3=83=83?= =?UTF-8?q?=E3=82=B0=E7=94=A8=E3=81=AE=E5=87=BA=E5=8A=9B=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gateway/gemini.go | 2 -- internal/gateway/qdrant.go | 2 -- 2 files changed, 4 deletions(-) diff --git a/internal/gateway/gemini.go b/internal/gateway/gemini.go index dfcf5b1..027ed04 100644 --- a/internal/gateway/gemini.go +++ b/internal/gateway/gemini.go @@ -2,7 +2,6 @@ package gateway import ( "encoding/json" - "fmt" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/service" @@ -38,7 +37,6 @@ func (qs *geminiServerGateway) GenerateCommitMessageList(diff string, conf entit if err != nil { return nil, err } - fmt.Print(string(res)) type geminiResponse struct { Messages []string `json:"messages"` diff --git a/internal/gateway/qdrant.go b/internal/gateway/qdrant.go index ca90091..aa2fe01 100644 --- a/internal/gateway/qdrant.go +++ b/internal/gateway/qdrant.go @@ -2,7 +2,6 @@ package gateway import ( "encoding/json" - "fmt" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/service" @@ -39,7 +38,6 @@ func (qs *qdrantServerGateway) GenerateCommitMessageList(diff string, conf entit if err != nil { return nil, err } - fmt.Print(string(res)) type qdrantResponse struct { Messages []string `json:"messages"` From 38dd1857e00f10f7453c44a308ed5c6b8de46fa9 Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 09:52:19 +0900 Subject: [PATCH 87/89] chore: refactor --- cmd/push.go | 33 ++++++++++++--------------------- internal/usecase/push_cmd.go | 2 +- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/cmd/push.go b/cmd/push.go index ff400e3..6ecbba2 100644 --- a/cmd/push.go +++ b/cmd/push.go @@ -39,7 +39,6 @@ type PushCmdStep int const ( SelectBaseBranch PushCmdStep = iota - ConfirmPR EditPRTitle EditPRBody SubmitPR @@ -78,11 +77,16 @@ func (m *pushModel) submitPRCmd() tea.Cmd { func (m *pushModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { + case spinner.TickMsg: + var cmd tea.Cmd + m.spinner, cmd = m.spinner.Update(msg) + return m, cmd case tea.KeyMsg: switch msg.Type { case tea.KeyCtrlC, tea.KeyEsc: return m, tea.Quit - + case tea.KeyCtrlE: + m.step-- } switch m.step { case SelectBaseBranch: @@ -99,17 +103,6 @@ func (m *pushModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.loadMsg = "PRを生成中..." return m, m.generatePRCmd() } - case ConfirmPR: - switch msg.Type { - case tea.KeyTab: - m.step = EditPRTitle - m.focusInPRTitle() - return m, cmd - case tea.KeyEnter: - m.step = SubmitPR - m.loadMsg = "PRを提出中..." - return m, m.submitPRCmd() - } case EditPRTitle: cmd = m.updateTitleInput(msg) switch msg.Type { @@ -134,7 +127,8 @@ func (m *pushModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.errMsg = fmt.Sprintf("🚨PR生成中にエラーが発生: %v", msg.err) } else { m.pr = msg.pr - m.step = ConfirmPR + m.step = EditPRTitle + m.focusInPRTitle() } m.finishLoading() case submitPRMsg: @@ -158,12 +152,10 @@ func (m *pushModel) View() string { switch m.step { case SelectBaseBranch: return m.buildSelectBaseBranchText() - case ConfirmPR: - return color.HiWhiteString("<生成されたPRの確認: TabKeyで編集, EnterでPush>") + fmt.Sprintf("\n\nTitle:\n%s\n\nBody:\n%s", m.pr.Title, m.pr.Body) case EditPRTitle: - return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle:\n%s\n\nBody:\n%s", m.prInput.titleInput.View(), m.pr.Body) + return color.HiWhiteString("\n\n") + fmt.Sprintf("Title:\n%s", m.prInput.titleInput.View()) case EditPRBody: - return color.HiWhiteString("") + fmt.Sprintf("\n\nTitle:\n%s\n\nBody:\n%s", m.pr.Title, m.prInput.bodyInput.View()) + return color.HiWhiteString("\n\n") + fmt.Sprintf("Body:\n%s", m.prInput.bodyInput.View()) case SubmitPR: return fmt.Sprintf("**🎉PRの作成に成功**") } @@ -255,9 +247,8 @@ func (m *pushModel) focusInPRBody() { input := m.prInput.bodyInput input.Focus() input.SetValue(m.pr.Body) - input.CharLimit = 1000 - input.SetWidth(100) - input.SetHeight(len(m.pr.Body) / 100) + input.CharLimit = 5000 + input.SetWidth(200) m.prInput.bodyInput = input } diff --git a/internal/usecase/push_cmd.go b/internal/usecase/push_cmd.go index 7020428..5d10127 100644 --- a/internal/usecase/push_cmd.go +++ b/internal/usecase/push_cmd.go @@ -14,7 +14,7 @@ type PushCmdUsecase struct { } const ( - GeneratePRFromCommitsPrompt = "generate pull request content from commit messages [%s] in Japanese" + GeneratePRFromCommitsPrompt = "generate pull request body from commit messages [%s] in Japanese" GeneratePRTitleFromPRBody = "generate pull request title from pr body [%s] in Japanese as one sentence like 〇〇の機能追加" ) From 5a8a15bd2931241559b6c136a209737bd8b5d204 Mon Sep 17 00:00:00 2001 From: mochi-yu Date: Sat, 16 Dec 2023 10:29:01 +0900 Subject: [PATCH 88/89] =?UTF-8?q?feat:=20=E5=A4=89=E6=9B=B4=E3=81=8C?= =?UTF-8?q?=E3=81=AA=E3=81=84=E6=99=82=E3=81=AE=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=83=8F=E3=83=B3=E3=83=89=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gateway/gemini.go | 5 +++++ internal/gateway/qdrant.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/internal/gateway/gemini.go b/internal/gateway/gemini.go index 027ed04..8433213 100644 --- a/internal/gateway/gemini.go +++ b/internal/gateway/gemini.go @@ -5,6 +5,7 @@ import ( "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/service" + "github.com/pkg/errors" ) type geminiServerGateway struct { @@ -21,6 +22,10 @@ func NewGeminiServerGateway() service.CommitMessageService { } func (qs *geminiServerGateway) GenerateCommitMessageList(diff string, conf entity.Config) ([]string, error) { + if diff == "" { + return nil, errors.New("ステージされた変更がありません。") + } + type geminiBody struct { Diff string `json:"diff"` } diff --git a/internal/gateway/qdrant.go b/internal/gateway/qdrant.go index aa2fe01..7ff2a39 100644 --- a/internal/gateway/qdrant.go +++ b/internal/gateway/qdrant.go @@ -2,6 +2,7 @@ package gateway import ( "encoding/json" + "errors" "github.com/cocoide/commitify/internal/entity" "github.com/cocoide/commitify/internal/service" @@ -18,6 +19,10 @@ func NewQdrantServerGateway() service.CommitMessageService { } func (qs *qdrantServerGateway) GenerateCommitMessageList(diff string, conf entity.Config) ([]string, error) { + if diff == "" { + return nil, errors.New("ステージされた変更がありません。") + } + type qdrantBody struct { Diff string `json:"diff"` } From 7ef0f395ee168de289f2523551bce33a4167429c Mon Sep 17 00:00:00 2001 From: {cocoide} Date: Sat, 16 Dec 2023 15:08:47 +0900 Subject: [PATCH 89/89] delete gomock gen code --- internal/service/commit_message.go | 1 - internal/service/github.go | 1 - internal/service/nlp.go | 1 - 3 files changed, 3 deletions(-) diff --git a/internal/service/commit_message.go b/internal/service/commit_message.go index 90fe0c5..c03a649 100644 --- a/internal/service/commit_message.go +++ b/internal/service/commit_message.go @@ -2,7 +2,6 @@ package service import "github.com/cocoide/commitify/internal/entity" -//go:generate mockgen -source=commit_message.go -destination=../../mock/commit_message.go type CommitMessageService interface { GenerateCommitMessageList(code string, config entity.Config) ([]string, error) } diff --git a/internal/service/github.go b/internal/service/github.go index 8d87e98..d3bb211 100644 --- a/internal/service/github.go +++ b/internal/service/github.go @@ -7,7 +7,6 @@ type GetRepoDetailsResponse struct { Repo string } -//go:generate mockgen -source=github.go -destination=../../mock/github.go type GithubService interface { GetStagingCodeDiff() (string, error) GetCurrentRepoDetails() (*GetRepoDetailsResponse, error) diff --git a/internal/service/nlp.go b/internal/service/nlp.go index 60b8dec..2cf6f79 100644 --- a/internal/service/nlp.go +++ b/internal/service/nlp.go @@ -1,6 +1,5 @@ package service -//go:generate mockgen -source=nlp.go -destination=../../mock/nlp.go type NLPService interface { GetAnswerFromPrompt(prompt string) (string, error) }