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

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

Overview

This was inspired from: stackoverflow.com/a/10219411/1520132

Constant Summary collapse

BUFFER_SIZE =
4096
LIMIT_SIZE =
500.kilobytes

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStream

Returns a new instance of Stream.


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

def initialize
  @stream = yield
  @stream&.binmode
end

Instance Attribute Details

#streamObject (readonly)

Returns the value of attribute stream


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

def stream
  @stream
end

Instance Method Details

#append(data, offset) ⇒ Object


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

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

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

#extract_coverage(regex) ⇒ Object


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

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
  # if bad regex or something goes wrong we dont want to interrupt transition
  # so we just silently ignore error for now
end

#extract_sectionsObject


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

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)

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

def file?
  self.path.present?
end

#html(last_lines: nil) ⇒ Object


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

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

#limit(last_bytes = LIMIT_SIZE) ⇒ Object


36
37
38
39
40
41
# File 'lib/gitlab/ci/trace/stream.rb', line 36

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

#pathObject


32
33
34
# File 'lib/gitlab/ci/trace/stream.rb', line 32

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

#present?Object


17
# File 'lib/gitlab/ci/trace/stream.rb', line 17

alias_method :present?, :valid?

#raw(last_lines: nil) ⇒ Object


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

def raw(last_lines: nil)
  return unless valid?

  if 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

Returns:

  • (Boolean)

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

def valid?
  self.stream.present?
end