gitlab-org--gitlab-foss/lib/gitlab/ci/trace_reader.rb
Lin Jen-Shin 050103f209 Make sure TraceReader uses Encoding.default_external
Encoding.default_external was chosen over
Encoding.default_internal because File.read is
returning Encoding.default_external, therefore
we should align with it. Alternatively, we could
force both of them to be Encoding.default_internal.

However, ideally this should be determined by different
projects. For example, some projects might want to use
an encoding different to what GitLab is using.

This might not happen soon though.

Closes #27052
2017-01-26 18:29:44 +08:00

50 lines
1.3 KiB
Ruby

module Gitlab
module Ci
# This was inspired from: http://stackoverflow.com/a/10219411/1520132
class TraceReader
BUFFER_SIZE = 4096
attr_accessor :path, :buffer_size
def initialize(new_path, buffer_size: BUFFER_SIZE)
self.path = new_path
self.buffer_size = Integer(buffer_size)
end
def read(last_lines: nil)
if last_lines
read_last_lines(last_lines)
else
File.read(path)
end
end
def read_last_lines(max_lines)
File.open(path) do |file|
chunks = []
pos = lines = 0
max = file.size
# We want an extra line to make sure fist line has full contents
while lines <= max_lines && pos < max
pos += buffer_size
buf = if pos <= max
file.seek(-pos, IO::SEEK_END)
file.read(buffer_size)
else # Reached the head, read only left
file.seek(0)
file.read(buffer_size - (pos - max))
end
lines += buf.count("\n")
chunks.unshift(buf)
end
chunks.join.lines.last(max_lines).join
.force_encoding(Encoding.default_external)
end
end
end
end
end