Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-16 21:08:01 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-16 21:08:01 +0300
commit8e45d25f7dde6508839ffee719c0ddc2cf6b12d3 (patch)
tree9839e7fe63b36904d40995ebf519124c9a8f7681 /lib/gitlab/ci/ansi2json/state.rb
parent00c78fb814d7ce00989ac04edd6cdaa3239da284 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/ci/ansi2json/state.rb')
-rw-r--r--lib/gitlab/ci/ansi2json/state.rb98
1 files changed, 98 insertions, 0 deletions
diff --git a/lib/gitlab/ci/ansi2json/state.rb b/lib/gitlab/ci/ansi2json/state.rb
new file mode 100644
index 00000000000..db7a9035b8b
--- /dev/null
+++ b/lib/gitlab/ci/ansi2json/state.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+# In this class we keep track of the state changes that the
+# Converter makes as it scans through the log stream.
+module Gitlab
+ module Ci
+ module Ansi2json
+ class State
+ attr_accessor :offset, :current_line, :inherited_style, :open_sections, :last_line_offset
+
+ def initialize(new_state, stream_size)
+ @offset = 0
+ @inherited_style = {}
+ @open_sections = {}
+ @stream_size = stream_size
+
+ restore_state!(new_state)
+ end
+
+ def encode
+ state = {
+ offset: @last_line_offset,
+ style: @current_line.style.to_h,
+ open_sections: @open_sections
+ }
+ Base64.urlsafe_encode64(state.to_json)
+ end
+
+ def open_section(section, timestamp)
+ @open_sections[section] = timestamp
+
+ @current_line.add_section(section)
+ @current_line.set_as_section_header
+ end
+
+ def close_section(section, timestamp)
+ return unless section_open?(section)
+
+ duration = timestamp.to_i - @open_sections[section].to_i
+ @current_line.set_section_duration(duration)
+
+ @open_sections.delete(section)
+ end
+
+ def section_open?(section)
+ @open_sections.key?(section)
+ end
+
+ def set_current_line!(style: nil, advance_offset: 0)
+ new_line = Line.new(
+ offset: @offset + advance_offset,
+ style: style || @current_line.style,
+ sections: @open_sections.keys
+ )
+ @current_line = new_line
+ end
+
+ def set_last_line_offset
+ @last_line_offset = @current_line.offset
+ end
+
+ def update_style(commands)
+ @current_line.flush_current_segment!
+ @current_line.update_style(commands)
+ end
+
+ private
+
+ def restore_state!(encoded_state)
+ state = decode_state(encoded_state)
+
+ return unless state
+ return if state['offset'].to_i > @stream_size
+
+ @offset = state['offset'].to_i if state['offset']
+ @open_sections = state['open_sections'] if state['open_sections']
+
+ if state['style']
+ @inherited_style = {
+ fg: state.dig('style', 'fg'),
+ bg: state.dig('style', 'bg'),
+ mask: state.dig('style', 'mask')
+ }
+ end
+ end
+
+ def decode_state(state)
+ return unless state.present?
+
+ decoded_state = Base64.urlsafe_decode64(state)
+ return unless decoded_state.present?
+
+ JSON.parse(decoded_state)
+ end
+ end
+ end
+ end
+end