ToASCII generates an ASCII tree representation. An optional ASCIIFormatter applies styling callbacks; pass nil for plain text. nolint:gocognit,gocyclo,funlen // TODO: refactor to reduce complexity
(rootTaskID string, downstream bool, f *ASCIIFormatter)
| 301 | // |
| 302 | //nolint:gocognit,gocyclo,funlen // TODO: refactor to reduce complexity |
| 303 | func (g *Graph) ToASCII(rootTaskID string, downstream bool, f *ASCIIFormatter) string { |
| 304 | var sb strings.Builder |
| 305 | |
| 306 | visited := make(map[string]bool) |
| 307 | |
| 308 | var printTree func(taskID string, prefix string, isLast bool) |
| 309 | printTree = func(taskID string, prefix string, isLast bool) { |
| 310 | if visited[taskID] { |
| 311 | // Already visited, just show reference |
| 312 | task, exists := g.TaskMap[taskID] |
| 313 | if exists { |
| 314 | connector := "├── " |
| 315 | if isLast { |
| 316 | connector = "└── " |
| 317 | } |
| 318 | ref := f.applyReference("(see above)") |
| 319 | sb.WriteString(fmt.Sprintf("%s%s[%s] %s %s\n", |
| 320 | prefix, f.applyConnector(connector), |
| 321 | f.applyID(taskID), f.applyTitle(task.Title, string(task.Status)), ref)) |
| 322 | } |
| 323 | return |
| 324 | } |
| 325 | |
| 326 | visited[taskID] = true |
| 327 | |
| 328 | task, exists := g.TaskMap[taskID] |
| 329 | if !exists { |
| 330 | return |
| 331 | } |
| 332 | |
| 333 | // Print current node |
| 334 | connector := "├── " |
| 335 | if isLast { |
| 336 | connector = "└── " |
| 337 | } |
| 338 | |
| 339 | statusIndicator := "" |
| 340 | switch task.Status { |
| 341 | case model.StatusCompleted: |
| 342 | statusIndicator = f.applyStatusIndicator(" ✓", string(task.Status)) |
| 343 | case model.StatusInProgress: |
| 344 | statusIndicator = f.applyStatusIndicator(" ⋯", string(task.Status)) |
| 345 | case model.StatusBlocked: |
| 346 | statusIndicator = f.applyStatusIndicator(" ⊗", string(task.Status)) |
| 347 | } |
| 348 | |
| 349 | formattedID := f.applyID(taskID) |
| 350 | formattedTitle := f.applyTitle(task.Title, string(task.Status)) |
| 351 | |
| 352 | if prefix == "" { |
| 353 | sb.WriteString(fmt.Sprintf("[%s] %s%s\n", formattedID, formattedTitle, statusIndicator)) |
| 354 | } else { |
| 355 | sb.WriteString(fmt.Sprintf("%s%s[%s] %s%s\n", |
| 356 | prefix, f.applyConnector(connector), formattedID, formattedTitle, statusIndicator)) |
| 357 | } |
| 358 | |
| 359 | // Get children based on direction |
| 360 | var children []string |