Class: Gitlab::Chat::Output

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/chat/output.rb

Overview

Class for gathering and formatting the output of a `Ci::Build`.

Constant Summary collapse

MissingBuildSectionError =
Class.new(StandardError)
PRIMARY_SECTION =

The primary trace section to look for.

'chat_reply'
FALLBACK_SECTION =

The backup trace section in case the primary one could not be found.

'build_script'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(build) ⇒ Output

build - The `Ci::Build` to obtain the output from.


18
19
20
# File 'lib/gitlab/chat/output.rb', line 18

def initialize(build)
  @build = build
end

Instance Attribute Details

#buildObject (readonly)

Returns the value of attribute build


7
8
9
# File 'lib/gitlab/chat/output.rb', line 7

def build
  @build
end

Instance Method Details

#find_build_trace_section(name) ⇒ Object

Returns the trace section for the given name, or `nil` if the section could not be found.

name - The name of the trace section to find.


80
81
82
# File 'lib/gitlab/chat/output.rb', line 80

def find_build_trace_section(name)
  trace_sections.find { |s| s[:name] == name }
end

#read_offset_and_lengthObject

Returns the offset to seek to and the number of bytes to read relative to the offset.


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/gitlab/chat/output.rb', line 42

def read_offset_and_length
  section = find_build_trace_section(PRIMARY_SECTION) ||
    find_build_trace_section(FALLBACK_SECTION)

  unless section
    raise(
      MissingBuildSectionError,
      "The build_script trace section could not be found for build #{build.id}"
    )
  end

  length = section[:byte_end] - section[:byte_start]

  [section[:byte_start], length]
end

#to_sObject

Returns a `String` containing the output of the build.

The output _does not_ include the command that was executed.


25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/gitlab/chat/output.rb', line 25

def to_s
  offset, length = read_offset_and_length

  trace.read do |stream|
    stream.seek(offset)

    output = stream
      .stream
      .read(length)
      .force_encoding(Encoding.default_external)

    without_executed_command_line(output)
  end
end

#traceObject


88
89
90
# File 'lib/gitlab/chat/output.rb', line 88

def trace
  @trace ||= build.trace
end

#trace_sectionsObject


84
85
86
# File 'lib/gitlab/chat/output.rb', line 84

def trace_sections
  @trace_sections ||= trace.extract_sections
end

#without_executed_command_line(output) ⇒ Object

Removes the line containing the executed command from the build output.

output - A `String` containing the output of a trace section.


61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/gitlab/chat/output.rb', line 61

def without_executed_command_line(output)
  # If `output.split("\n")` produces an empty Array then the slicing that
  # follows it will produce a nil. For example:
  #
  #     "\n".split("\n")        # => []
  #     "\n".split("\n")[1..-1] # => nil
  #
  # To work around this we only "join" if we're given an Array.
  if (converted = output.split("\n")[1..-1])
    converted.join("\n")
  else
    ''
  end
end