checkParentCycles detects cycles in the parent chain (e.g. A→B→A)
(tasks []*model.Task, taskMap map[string]*model.Task, result *ValidationResult)
| 335 | |
| 336 | // checkParentCycles detects cycles in the parent chain (e.g. A→B→A) |
| 337 | func (v *Validator) checkParentCycles(tasks []*model.Task, taskMap map[string]*model.Task, result *ValidationResult) { |
| 338 | for _, task := range tasks { |
| 339 | if task.Parent == "" { |
| 340 | continue |
| 341 | } |
| 342 | visited := map[string]bool{task.ID: true} |
| 343 | current := task.Parent |
| 344 | for current != "" { |
| 345 | if visited[current] { |
| 346 | result.AddIssue(LevelError, task.ID, task.FilePath, |
| 347 | fmt.Sprintf("parent cycle detected: task '%s' creates a cycle via '%s'", task.ID, current)) |
| 348 | break |
| 349 | } |
| 350 | visited[current] = true |
| 351 | parent, exists := taskMap[current] |
| 352 | if !exists { |
| 353 | break // missing parent already reported |
| 354 | } |
| 355 | current = parent.Parent |
| 356 | } |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | // ValidateConfig checks the .taskmd.yaml config file for issues. |
| 361 | // Returns an empty result if config is nil. |