Check dependency graph for cycles. Throw a CycleError
if one is found, detailing the services involved.
_ = require 'underscore'
class CycleError extends Error
constructor: (dependency, walkedList) ->
index = _.indexOf walkedList, dependency
cycle = _.reject walkedList, (s) -> _.indexOf(walkedList, s) < index
cycle.push dependency
@message = "Cyclic Dependency found: '#{cycle.join '\' -> \''}'"
name: 'Cyclic Dependency Error'
module.exports = (graph) ->
services = _.keys graph
visited = []
visitNode = (service, walked) ->
walked = [] unless _.isArray walked
visited.push service
walked.push service
visitDependencies = (dependency) ->
if _.contains walked, dependency
throw new CycleError dependency, walked
visitNode dependency, walked.slice 0
_.each graph[service], visitDependencies
_.each services, visitNode
return true