buildMixedBody creates the body section for mixed-type commit messages. Each category gets a section with task titles (and subtasks for completed).
(changes TaskChanges)
| 280 | // buildMixedBody creates the body section for mixed-type commit messages. |
| 281 | // Each category gets a section with task titles (and subtasks for completed). |
| 282 | func buildMixedBody(changes TaskChanges) string { |
| 283 | type categoryGroup struct { |
| 284 | label string |
| 285 | tasks []*model.Task |
| 286 | } |
| 287 | |
| 288 | categories := []categoryGroup{ |
| 289 | {"Completed", changes.Completed}, |
| 290 | {"Added", changes.Added}, |
| 291 | {"Started", changes.Started}, |
| 292 | {"Blocked", changes.Blocked}, |
| 293 | {"Cancelled", changes.Cancelled}, |
| 294 | } |
| 295 | |
| 296 | var sections []string |
| 297 | for _, cat := range categories { |
| 298 | if len(cat.tasks) == 0 { |
| 299 | continue |
| 300 | } |
| 301 | var lines []string |
| 302 | for _, t := range cat.tasks { |
| 303 | if cat.label == "Completed" { |
| 304 | subtasks := extractCompletedSubtasks(t.Body) |
| 305 | if len(subtasks) > 0 { |
| 306 | lines = append(lines, fmt.Sprintf("%s:\n%s", t.Title, formatSubtaskBullets(subtasks))) |
| 307 | } else { |
| 308 | lines = append(lines, fmt.Sprintf("- %s (task %s)", t.Title, t.ID)) |
| 309 | } |
| 310 | } else { |
| 311 | lines = append(lines, fmt.Sprintf("- %s (task %s)", t.Title, t.ID)) |
| 312 | } |
| 313 | } |
| 314 | section := fmt.Sprintf("%s:\n%s", cat.label, strings.Join(lines, "\n")) |
| 315 | sections = append(sections, section) |
| 316 | } |
| 317 | |
| 318 | return strings.Join(sections, "\n\n") |
| 319 | } |
| 320 | |
| 321 | func lowerFirst(s string) string { |
| 322 | if s == "" { |
no test coverage detected