From 3c359cadb9f968db6e9f78b277928b877a16a04c Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 15 May 2017 21:35:42 +0800 Subject: Scan trace lines from bottom up for parsing coverage So that it stops at the last coverage pattern, instead of the first, and we still not reading the whole trace if possible. --- lib/gitlab/ci/trace/stream.rb | 41 +++++++++++++++++++++++++-------- spec/lib/gitlab/ci/trace/stream_spec.rb | 2 +- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb index fa462cbe095..2bb7a5bad35 100644 --- a/lib/gitlab/ci/trace/stream.rb +++ b/lib/gitlab/ci/trace/stream.rb @@ -73,7 +73,7 @@ module Gitlab match = "" - stream.each_line do |line| + reverse_line do |line| matches = line.scan(regex) next unless matches.is_a?(Array) next if matches.empty? @@ -85,19 +85,23 @@ module Gitlab nil rescue - # if bad regex or something goes wrong we dont want to interrupt transition - # so we just silentrly ignore error for now + # if bad regex or something goes wrong we don't want to interrupt transition + # so we just silently ignore error for now end private - def read_last_lines(last_lines) - chunks = [] - pos = lines = 0 + def read_last_lines(last_lines = nil) + to_enum(:reverse_line, last_lines).reverse_each.to_a.join + end + + def reverse_line(last_lines = nil, &block) + leftover = '' + pos = read_lines = 0 max = stream.size # We want an extra line to make sure fist line has full contents - while lines <= last_lines && pos < max + while pos < max && (last_lines.nil? || last_lines > 0) pos += BUFFER_SIZE buf = @@ -109,11 +113,28 @@ module Gitlab stream.read(BUFFER_SIZE - (pos - max)) end - lines += buf.count("\n") - chunks.unshift(buf) + read_lines += buf.count("\n") + + next_partial_line, *current_lines = buf.lines + *complete_lines, partial_line = current_lines + complete_lines << "#{partial_line}#{leftover}" + + if last_lines + complete_lines.last(last_lines) + else + complete_lines + end.reverse_each(&block) + + last_lines -= complete_lines.size if last_lines + leftover = next_partial_line end - chunks.join.lines.last(last_lines).join + # Handle the leftover + if last_lines && last_lines > 0 + leftover.lines.last(last_lines).reverse_each(&block) + elsif last_lines.nil? + leftover.lines.reverse_each(&block) + 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 40ac5a3ed37..4d2d8327655 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -240,7 +240,7 @@ describe Gitlab::Ci::Trace::Stream do end context 'multiple results in content & regex' do - let(:data) { ' (98.39%) covered. (98.29%) covered' } + let(:data) { " (98.39%) covered.\n (98.29%) covered" } let(:regex) { '\(\d+.\d+\%\) covered' } it { is_expected.to eq("98.29") } -- cgit v1.2.1