Method: Tap::Support::Audit.dump

Defined in:
lib/tap/support/audit.rb

.dump(audits, target = $stdout) ⇒ Object

Produces a pretty-print dump of the specified audits to target. A block may be provided to format the trailer of each line.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/tap/support/audit.rb', line 92

def dump(audits, target=$stdout) # :yields: audit
  return dump(audits, target) do |audit| 
    "o-[#{audit.key}] #{audit.value.inspect}"
  end unless block_given?
  
  # arrayify audits
  audits = [audits].flatten
  
  # the order of audits
  order = []
  
  # (audit, sinks) hash preventing double iteration over 
  # audits, and identifying sinks for a particular audit
  sinks = {}
  
  # iterate over all audits, collecting in order
  audits.each do |audit|
    traverse(audit, order, sinks)
  end
  
  # visit each audit, collecting audits into indent groups
  groups = []
  group = nil
  order.each do |audit|
    sources = audit.sources
    unless sources.length == 1 && sinks[sources[0]].length <= 1
      group = []
      groups << group
    end
    
    group << audit
  end
  
  # identify nodes at which a fork occurs... these are audits
  # that have more than one sink, and they cause a fork-style
  # leader to be printed
  forks = {}
  sinks.each_pair do |audit, sinks|
    n = sinks.length
    forks[audit] = [0, n] if n > 1
  end
  
  # setup print
  index = 0
  leader = ""
  
  # print each group
  groups.each do |group|
    sources = group[0].sources
    complete = audits.include?(group[-1])
    
    case 
    when sources.length > 1
      # print a merge
      # `-`-`-o-[merge]
      
      leader =~ /^(.*)((\| *){#{sources.length}})$/
      leader = "#{$1}#{' ' * $2.length} "
      target << "#{$1}#{$2.gsub('|', '`').gsub(' ', '-')}-#{yield(group.shift)}\n"
      
    when fork = forks[sources[0]]
      # print a fork
      # |-o-[a]
      # |
      # `---o-[b]
      
      n = fork[0] += 1
      base = leader[0, leader.length - (2 * n - 1)]
      target << "#{base}#{fork[0] == fork[1] ? '`-' : '|-'}#{'--' * (n-1)}#{yield(group.shift)}\n"
      leader  = "#{base}#{fork[0] == fork[1] ? '  ' : '| '}#{'| ' * (n-1)}"
      
    when index > 0
      # simply get ready to print the next series of audits
      # o-[a]
      # o-[b]
      
      leader = "#{leader} "
      leader = "" if leader.strip.empty?
    end
    
    # print the next series of audits
    group.each do |audit|
      target << "#{leader}#{yield(audit)}\n"
    end
    
    # add a continuation line, if necessary
    unless group == groups.last
      if complete
        leader = "#{leader} "
      else
        leader = "#{leader}|"
      end
      target << "#{leader}\n"
    end
    
    index += 1
  end
  
  target
end