# frozen_string_literal: true module Gitlab module Ci module Ansi2json class Converter def convert(stream, new_state) @lines = [] @state = State.new(new_state, stream.size) append = false truncated = false cur_offset = stream.tell if cur_offset > @state.offset @state.offset = cur_offset truncated = true else stream.seek(@state.offset) append = @state.offset > 0 end start_offset = @state.offset @state.set_current_line!(style: Style.new(@state.inherited_style)) stream.each_line do |line| s = StringScanner.new(line) convert_line(s) end # This must be assigned before flushing the current line # or the @current_line.offset will advance to the very end # of the trace. Instead we want @last_line_offset to always # point to the beginning of last line. @state.set_last_line_offset flush_current_line # TODO: replace OpenStruct with a better type # https://gitlab.com/gitlab-org/gitlab/issues/34305 OpenStruct.new( lines: @lines, state: @state.encode, append: append, truncated: truncated, offset: start_offset, size: stream.tell - start_offset, total: stream.size ) end private def convert_line(scanner) until scanner.eos? if scanner.scan(Gitlab::Regex.build_trace_section_regex) handle_section(scanner) elsif scanner.scan(/\e([@-_])(.*?)([@-~])/) handle_sequence(scanner) elsif scanner.scan(/\e(([@-_])(.*?)?)?$/) break elsif scanner.scan(/