diff --git a/internal/generate/generate.go b/internal/generate/generate.go new file mode 100644 index 0000000..fd0a69b --- /dev/null +++ b/internal/generate/generate.go @@ -0,0 +1,98 @@ +package generate + +import ( + "bytes" + "context" + "fmt" + "text/template" +) + +type ReleaseNote struct { + Version string + Title string + Overview string + PR []string + Change []string + Fixture []string + BreakingChange []string + Issue []string + Keep []string + Problem []string + Try []string + Other []string +} + +func GenerateReleaseNote(ctx context.Context, releaseNote ReleaseNote) (string, error) { + const templateText = ` +Release Note: {{ .Version }} + +{{ .Title }} + +## 概要 + +{{ .Overview }} + +## 変更内容 +{{ range .Change }} + - {{ . }} +{{- end }} + +## PR +{{ range .PR }} + - PR: #{{ . }} +{{- end }} + +## 破壊的変更 +{{ range .BreakingChange }} + - {{ . }} +{{- end }} + +## 修正内容 +{{ range .Fixture }} + - {{ . }} +{{- end }} + +## 既知の問題 +{{ range .Issue }} + - {{ . }} +{{- end }} + +## KPT +### 🌻 Keep +{{ range .Keep }} + - {{ . }} +{{- end }} + +### 😨 Problem +{{ range .Problem }} + - {{ . }} +{{- end }} + +### 🌈 Try +{{ range .Try }} + - {{ . }} +{{- end }} + +## その他 +{{ range .Other }} + - {{ . }} +{{- end }}` + + // テンプレートを解析 + tmpl, err := template.New("releasenote").Parse(templateText) + if err != nil { + fmt.Println("テンプレートの解析エラー:", err) + return "", err + } + + var buf bytes.Buffer + + // テンプレートを実行し、結果をバッファに書き込む + err = tmpl.Execute(&buf, releaseNote) + if err != nil { + return "", fmt.Errorf("テンプレートの実行エラー: %w", err) + } + + // バッファの内容を文字列として返す + return buf.String(), nil +} diff --git a/internal/generate/generate_test.go b/internal/generate/generate_test.go new file mode 100644 index 0000000..8bfc8fc --- /dev/null +++ b/internal/generate/generate_test.go @@ -0,0 +1,120 @@ +package generate + +import ( + "context" + "strings" + "testing" +) + +func TestGenerateReleaseNote(t *testing.T) { + eexpect_1 := ` +Release Note: v1.0.0 + +プロフィール + +## 概要 + +名前: 山田太郎 +年齢: 30歳 +住所: 東京 +趣味: + - 読書 + - 旅行 + - 料理 + +## 変更内容 + + - 名前: 山田太郎 + - 年齢: 30歳 + - 住所: 東京 + +## PR + + - PR: #1 + - PR: #2 + +## 破壊的変更 + + - 名前: 山田太郎 + - 年齢: 30歳 + - 住所: 東京 + +## 修正内容 + + - 読書 + - 旅行 + - 料理 + +## 既知の問題 + + - 読書 + - 旅行 + - 料理 + +## KPT +### 🌻 Keep + + - 読書 + - 旅行 + - 料理 + +### 😨 Problem + + - 読書 + - 旅行 + - 料理 + +### 🌈 Try + + - 読書 + - 旅行 + - 料理 + +## その他 + + - 読書 + - 旅行 + - 料理` + + ctx := context.Background() + cases := []struct { + name string + releaseNote ReleaseNote + expected string + iserr bool + }{ + { + name: "test case 1", + releaseNote: ReleaseNote{ + Version: "v1.0.0", + Title: "プロフィール", + Overview: "名前: 山田太郎\n年齢: 30歳\n住所: 東京\n趣味:\n - 読書\n - 旅行\n - 料理", + PR: []string{"1", "2"}, + Change: []string{"名前: 山田太郎", "年齢: 30歳", "住所: 東京"}, + Fixture: []string{"読書", "旅行", "料理"}, + BreakingChange: []string{"名前: 山田太郎", "年齢: 30歳", "住所: 東京"}, + Issue: []string{"読書", "旅行", "料理"}, + Keep: []string{"読書", "旅行", "料理"}, + Problem: []string{"読書", "旅行", "料理"}, + Try: []string{"読書", "旅行", "料理"}, + Other: []string{"読書", "旅行", "料理"}, + }, + expected: eexpect_1, + iserr: false, + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + result, err := GenerateReleaseNote(ctx, tt.releaseNote) + if (err != nil) != tt.iserr { + t.Errorf("got: %v err is not nil but expected err is nil", err) + } + expectedTrimmed := strings.TrimSpace(tt.expected) + resultTrimmed := strings.TrimSpace(result) + if resultTrimmed != expectedTrimmed { + t.Errorf("got %v, but expected %v", result, tt.expected) + } + }) + } +}