diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2017-04-18 17:03:02 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2017-04-18 17:03:02 +0800 |
commit | 7c1abc2cabb20e286ca40be2e3071bb95886bf25 (patch) | |
tree | 54e3ee598eedf08e8dd4d82854612c38e91f6fe6 | |
parent | ec9f6180bc4684521444ee0681308bf4c9c71297 (diff) | |
download | gitlab-ce-use-buffer-for-ansi2html.tar.gz |
Use a buffer for Ansi2html so it's not affecting Streamuse-buffer-for-ansi2html
Fixes https://sentry.gitlap.com/gitlab/gitlabcom/issues/27545/
-rw-r--r-- | lib/gitlab/ci/trace/stream.rb | 34 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/trace/stream_spec.rb | 17 |
2 files changed, 39 insertions, 12 deletions
diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb index b929bdd55bc..8fa2b18329e 100644 --- a/lib/gitlab/ci/trace/stream.rb +++ b/lib/gitlab/ci/trace/stream.rb @@ -14,14 +14,7 @@ module Gitlab def initialize @stream = yield - if @stream - @stream.binmode - # Ci::Ansi2html::Converter would read from @stream directly, - # using @stream.each_line to be specific. It's safe to set - # the encoding here because IO#seek(bytes) and IO#read(bytes) - # are not characters based, so encoding doesn't matter to them. - @stream.set_encoding(Encoding.default_external) - end + @stream.binmode if @stream end def valid? @@ -63,13 +56,14 @@ module Gitlab end def html_with_state(state = nil) - ::Ci::Ansi2html.convert(stream, state) + buffer = create_stream_for_ansi2html(stream) if stream + ::Ci::Ansi2html.convert(buffer, state) end def html(last_lines: nil) text = raw(last_lines: last_lines) - stream = StringIO.new(text) - ::Ci::Ansi2html.convert(stream).html + buffer = create_stream_for_ansi2html(text) + ::Ci::Ansi2html.convert(buffer).html end def extract_coverage(regex) @@ -122,6 +116,24 @@ module Gitlab chunks.join.lines.last(last_lines).join end + + def create_stream_for_ansi2html(io_or_string) + buffer = StringIO.new + + case io_or_string + when IO, StringIO + IO.copy_stream(io_or_string, buffer) + when String + buffer.string = io_or_string + else + raise TypeError, + "should be an IO or String, but got: #{io_or_string.class}" + end + + buffer.set_encoding(Encoding.default_external) + buffer.rewind + buffer + end end end end diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb index 03f040f4465..2bd2aab829e 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -71,9 +71,13 @@ describe Gitlab::Ci::Trace::Stream do end describe '#append' do + let(:tempfile) { Tempfile.new } + let(:stream) do described_class.new do - StringIO.new("12345678") + tempfile.write("12345678") + tempfile.rewind + tempfile end end @@ -84,6 +88,17 @@ describe Gitlab::Ci::Trace::Stream do expect(stream.size).to eq(6) expect(stream.raw).to eq("123489") end + + it 'appends in binary mode' do + '😺'.force_encoding('ASCII-8BIT').each_char.with_index do |byte, offset| + stream.append(byte, offset) + end + + stream.seek(0) + + expect(stream.size).to eq(4) + expect(stream.raw).to eq('😺') + end end describe '#set' do |