MCPcopy Create free account
hub / github.com/driangle/taskmd / checkCircularDependencies

Method checkCircularDependencies

sdk/go/validator/validator.go:249–308  ·  view source on GitHub ↗

checkCircularDependencies detects cycles in the dependency graph nolint:gocognit // TODO: refactor to reduce complexity

(tasks []*model.Task, taskMap map[string]*model.Task, result *ValidationResult)

Source from the content-addressed store, hash-verified

247//
248//nolint:gocognit // TODO: refactor to reduce complexity
249func (v *Validator) checkCircularDependencies(tasks []*model.Task, taskMap map[string]*model.Task, result *ValidationResult) {
250 // Build adjacency list
251 graph := make(map[string][]string)
252 for _, task := range tasks {
253 graph[task.ID] = task.Dependencies
254 }
255
256 // Track visit states: 0 = unvisited, 1 = visiting, 2 = visited
257 visitState := make(map[string]int)
258 path := []string{}
259
260 var hasCycle func(string) bool
261 hasCycle = func(taskID string) bool {
262 if visitState[taskID] == 1 {
263 // Found a cycle - build cycle path
264 cycleStart := -1
265 for i, id := range path {
266 if id == taskID {
267 cycleStart = i
268 break
269 }
270 }
271 if cycleStart >= 0 {
272 cyclePath := append(path[cycleStart:], taskID)
273 result.AddIssue(LevelError, taskID, taskMap[taskID].FilePath,
274 fmt.Sprintf("circular dependency detected: %s", strings.Join(cyclePath, " -> ")))
275 }
276 return true
277 }
278
279 if visitState[taskID] == 2 {
280 return false // Already fully processed
281 }
282
283 visitState[taskID] = 1
284 path = append(path, taskID)
285
286 for _, depID := range graph[taskID] {
287 if _, exists := taskMap[depID]; !exists {
288 continue // Skip missing dependencies (already reported)
289 }
290 if hasCycle(depID) {
291 visitState[taskID] = 2
292 path = path[:len(path)-1]
293 return true
294 }
295 }
296
297 visitState[taskID] = 2
298 path = path[:len(path)-1]
299 return false
300 }
301
302 // Check each task for cycles
303 for taskID := range taskMap {
304 if visitState[taskID] == 0 {
305 hasCycle(taskID)
306 }

Callers 1

ValidateMethod · 0.95

Calls 1

AddIssueMethod · 0.80

Tested by

no test coverage detected