Class: Gitlab::Ci::Trace::Stream

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/ci/trace/stream.rb

Constant Summary collapse

BUFFER_SIZE =
4096
LIMIT_SIZE =
500.kilobytes

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(metrics = Trace::Metrics.new) ⇒ Stream

Returns a new instance of Stream.



14
15
16
17
18
# File 'lib/gitlab/ci/trace/stream.rb', line 14

def initialize(metrics = Trace::Metrics.new)
  @stream = yield
  @stream&.binmode
  @metrics = metrics
end

Instance Attribute Details

#metricsObject (readonly)

Returns the value of attribute metrics.



10
11
12
# File 'lib/gitlab/ci/trace/stream.rb', line 10

def metrics
  @metrics
end

#streamObject (readonly)

Returns the value of attribute stream.



10
11
12
# File 'lib/gitlab/ci/trace/stream.rb', line 10

def stream
  @stream
end

Instance Method Details

#append(data, offset) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/gitlab/ci/trace/stream.rb', line 40

def append(data, offset)
  data = data.force_encoding(Encoding::BINARY)

  metrics.increment_trace_operation(operation: :streamed)
  metrics.increment_trace_bytes(data.bytesize)

  stream.seek(offset, IO::SEEK_SET)
  stream.write(data)
  stream.truncate(offset + data.bytesize)
  stream.flush
end

#extract_coverage(regex) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/gitlab/ci/trace/stream.rb', line 74

def extract_coverage(regex)
  return unless valid?
  return unless regex.present?

  regex = Gitlab::UntrustedRegexp.new(regex)

  match = ""

  reverse_line do |line|
    line.chomp!
    matches = regex.scan(line)
    next unless matches.is_a?(Array)
    next if matches.empty?

    match = matches.flatten.last
    coverage = match.gsub(/\d+(\.\d+)?/).first
    return coverage if coverage.present? # rubocop:disable Cop/AvoidReturnFromBlocks
  end

  nil
rescue StandardError
  # if bad regex or something goes wrong we dont want to interrupt transition
  # so we just silently ignore error for now
end

#extract_sectionsObject



99
100
101
102
103
104
105
106
107
# File 'lib/gitlab/ci/trace/stream.rb', line 99

def extract_sections
  return [] unless valid?

  lines = to_enum(:each_line_with_pos)
  parser = SectionParser.new(lines)

  parser.parse!
  parser.sections
end

#file?Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/gitlab/ci/trace/stream.rb', line 25

def file?
  self.path.present?
end

#html(last_lines: nil, max_size: nil) ⇒ Object



68
69
70
71
72
# File 'lib/gitlab/ci/trace/stream.rb', line 68

def html(last_lines: nil, max_size: nil)
  text = raw(last_lines: last_lines, max_size: max_size)
  buffer = StringIO.new(text)
  ::Gitlab::Ci::Ansi2html.convert(buffer).html
end

#limit(last_bytes = LIMIT_SIZE) ⇒ Object



33
34
35
36
37
38
# File 'lib/gitlab/ci/trace/stream.rb', line 33

def limit(last_bytes = LIMIT_SIZE)
  if last_bytes < size
    stream.seek(-last_bytes, IO::SEEK_END)
    stream.readline
  end
end

#pathObject



29
30
31
# File 'lib/gitlab/ci/trace/stream.rb', line 29

def path
  self.stream.path if self.stream.respond_to?(:path)
end

#raw(last_lines: nil, max_size: nil) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/gitlab/ci/trace/stream.rb', line 56

def raw(last_lines: nil, max_size: nil)
  return unless valid?

  if max_size.to_i > 0
    read_last_lines_with_max_size(last_lines, max_size)
  elsif last_lines.to_i > 0
    read_last_lines(last_lines)
  else
    stream.read
  end.force_encoding(Encoding.default_external)
end

#set(data) ⇒ Object



52
53
54
# File 'lib/gitlab/ci/trace/stream.rb', line 52

def set(data)
  append(data, 0)
end

#valid?Boolean Also known as: present?

Returns:

  • (Boolean)


20
21
22
# File 'lib/gitlab/ci/trace/stream.rb', line 20

def valid?
  self.stream.present?
end