lib/codependency/graph.rb in codependency-0.2.0 vs lib/codependency/graph.rb in codependency-0.3.0
- old
+ new
@@ -1,30 +1,45 @@
+require 'open3'
+
module Codependency
class Graph
def initialize( start, options={} )
@options = options
@nodes = Hash.new { |h, k| h[ k ] = Node.new( k, parser ) }
@start = @nodes[ start ]
end
+ ##
+ # a topologically sorted list of all dependencies of the `start` file.
def files
- [ ].tap { |list| resolve @start, list }.reverse.map &:filename
+ deps = resolve( @start, [ ] ).map( &:dependencies ).join ' '
+
+ cmd, out, err = Open3.popen3 "echo '#{deps}' | tsort"
+
+ if msg = err.gets
+ raise CircularDependencyError, msg
+ end
+
+ out.readlines.map( &:chomp ).reverse
end
protected
+ ##
+ # adds a node's dependencies to a list (memo).
+ # intended to be used recursively.
def resolve( node, list )
- list << node # TODO if the node were in the list here,
- # would that indicate a circular dependency?
- node.dependencies.map { |filename| @nodes[ filename ] }.each do |dep|
- if list.include?( dep )
- list << list.slice!( list.index( dep ) )
- else
- resolve dep, list
- end
+ list << node
+
+ node.edges.map { |filename| @nodes[ filename ] }.each do |dep|
+ resolve dep, list unless list.include?( dep )
end
+
+ list
end
+ ##
+ # the parser to use for this graph. shared by all nodes.
def parser
@parser ||= Parser.new @options
end
end
end