lib/attr/gather/workflow/dot_serializer.rb
# frozen_string_literal: true
require 'tempfile'
module Attr
module Gather
module Workflow
# @api private
class DotSerializer
def initialize(task_graph)
@task_graph = task_graph
end
def to_dot
lines = @task_graph.tsort.map { |t| serialize_row(t) }
joined_lines = lines.flatten.map { |l| " #{l}" }.join("\n").strip
<<~DOT
digraph TaskGraph {
#{joined_lines}
}
DOT
end
def preview
Tempfile.open(['task-graph-preview', '.svg']) do |tf|
IO.popen("dot -Tsvg -o #{tf.path}", 'w') { |p| p.write(to_dot) }
`xdg-open #{tf.path}`
end
end
private
def serialize_row(task)
row = all_dependants_for_task(task).map { |dt| [task, dt] }
row.map { |item| "#{item.map(&:name).join(' -> ')};" }
end
def all_dependants_for_task(input_task)
@task_graph.to_h.keys.select { |task| task.depends_on?(input_task) }
end
end
end
end
end