98 lines
2.6 KiB
Ruby
98 lines
2.6 KiB
Ruby
|
module Gitlab
|
||
|
module Ci
|
||
|
class Trace
|
||
|
class SectionParser
|
||
|
def initialize(lines)
|
||
|
@lines = lines
|
||
|
end
|
||
|
|
||
|
def parse!
|
||
|
@markers = {}
|
||
|
|
||
|
@lines.each do |line, pos|
|
||
|
parse_line(line, pos)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def sections
|
||
|
sanitize_markers.map do |name, markers|
|
||
|
start_, end_ = markers
|
||
|
|
||
|
{
|
||
|
name: name,
|
||
|
byte_start: start_[:marker],
|
||
|
byte_end: end_[:marker],
|
||
|
date_start: start_[:timestamp],
|
||
|
date_end: end_[:timestamp]
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def parse_line(line, line_start_position)
|
||
|
s = StringScanner.new(line)
|
||
|
until s.eos?
|
||
|
find_next_marker(s) do |scanner|
|
||
|
marker_begins_at = line_start_position + scanner.pointer
|
||
|
|
||
|
if scanner.scan(Gitlab::Regex.build_trace_section_regex)
|
||
|
marker_ends_at = line_start_position + scanner.pointer
|
||
|
handle_line(scanner[1], scanner[2].to_i, scanner[3], marker_begins_at, marker_ends_at)
|
||
|
true
|
||
|
else
|
||
|
false
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def sanitize_markers
|
||
|
@markers.select do |_, markers|
|
||
|
markers.size == 2 && markers[0][:action] == :start && markers[1][:action] == :end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def handle_line(action, time, name, marker_start, marker_end)
|
||
|
action = action.to_sym
|
||
|
timestamp = Time.at(time).utc
|
||
|
marker = if action == :start
|
||
|
marker_end
|
||
|
else
|
||
|
marker_start
|
||
|
end
|
||
|
|
||
|
@markers[name] ||= []
|
||
|
@markers[name] << {
|
||
|
name: name,
|
||
|
action: action,
|
||
|
timestamp: timestamp,
|
||
|
marker: marker
|
||
|
}
|
||
|
end
|
||
|
|
||
|
def beginning_of_section_regex
|
||
|
@beginning_of_section_regex ||= /section_/.freeze
|
||
|
end
|
||
|
|
||
|
def find_next_marker(s)
|
||
|
beginning_of_section_len = 8
|
||
|
maybe_marker = s.exist?(beginning_of_section_regex)
|
||
|
|
||
|
if maybe_marker.nil?
|
||
|
s.terminate
|
||
|
else
|
||
|
# repositioning at the beginning of the match
|
||
|
s.pos += maybe_marker - beginning_of_section_len
|
||
|
if block_given?
|
||
|
good_marker = yield(s)
|
||
|
# if not a good marker: Consuming the matched beginning_of_section_regex
|
||
|
s.pos += beginning_of_section_len unless good_marker
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|