ruby_ci 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/minitest/reporters/rubyci_reporter.rb +172 -6
- data/lib/ruby_ci/brakeman.rb +15 -1
- data/lib/ruby_ci/configuration.rb +4 -1
- data/lib/ruby_ci/dryrun_runner_prepend.rb +28 -0
- data/lib/ruby_ci/rspec_dryrun_formatter.rb +113 -0
- data/lib/ruby_ci/rspec_formatter.rb +223 -6
- data/lib/ruby_ci/ruby_critic/cli/application.rb +13 -1
- data/lib/ruby_ci/runner_prepend.rb +26 -1
- data/lib/ruby_ci/simple_cov.rb +62 -1
- data/lib/ruby_ci/version.rb +1 -1
- data/lib/ruby_ci.rb +6 -1
- data/ruby_ci.gemspec +1 -0
- metadata +18 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3635c09d11258f3e066c50631d7a25eb3946512ea3eedb4e35b9e240797b1f85
         | 
| 4 | 
            +
              data.tar.gz: fb84e77923af72c0c2b3568d87a3c78d2165c176b0c6dbb2a6e6124062a127bd
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9efac45b1459e07557e0d766d767460b8ab179c1dd8c1afa7189d17b8067df2d790a34bc14c00d3f8a342b52b22905bf313fc63bdf8f0ecf0e9eb276da2ffcbe
         | 
| 7 | 
            +
              data.tar.gz: fe6fc89c19b6716cd9b132fdf3ef748859966318cbc6de6bb69e5fe5b9740b57b0c6049d415b97c6569913b5c5373aa51d2834e328245dd6e6273b271c5b6d48
         | 
| @@ -1,5 +1,28 @@ | |
| 1 1 | 
             
            module Minitest
         | 
| 2 2 | 
             
              module Reporters
         | 
| 3 | 
            +
                class Suite
         | 
| 4 | 
            +
                  attr_reader :name
         | 
| 5 | 
            +
                  def initialize(name)
         | 
| 6 | 
            +
                    @name = name
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def ==(other)
         | 
| 10 | 
            +
                    name == other.name
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def eql?(other)
         | 
| 14 | 
            +
                    self == other
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def hash
         | 
| 18 | 
            +
                    name.hash
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def to_s
         | 
| 22 | 
            +
                    name.to_s
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 3 26 | 
             
                class RubyciReporter
         | 
| 4 27 | 
             
                  attr_accessor :tests, :test_results, :ids
         | 
| 5 28 |  | 
| @@ -7,16 +30,40 @@ module Minitest | |
| 7 30 | 
             
                    @tests = {}
         | 
| 8 31 | 
             
                    @test_results = {}
         | 
| 9 32 | 
             
                    @ids = {}
         | 
| 33 | 
            +
                    @events = []
         | 
| 10 34 |  | 
| 11 | 
            -
                     | 
| 12 | 
            -
                      tests
         | 
| 13 | 
            -
                    end
         | 
| 35 | 
            +
                    $stdout = StringIO.new()
         | 
| 14 36 |  | 
| 15 | 
            -
                     | 
| 16 | 
            -
                       | 
| 37 | 
            +
                    if ENV['RBCI_REMOTE_TESTS'] != 'true'
         | 
| 38 | 
            +
                      RubyCI.minitest_ws.on(:enq_request) do
         | 
| 39 | 
            +
                        tests
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      RubyCI.minitest_ws.on(:deq) do |api_tests|
         | 
| 43 | 
            +
                        test_results
         | 
| 44 | 
            +
                      end
         | 
| 17 45 | 
             
                    end
         | 
| 18 46 | 
             
                  end
         | 
| 19 47 |  | 
| 48 | 
            +
                  def start
         | 
| 49 | 
            +
                    test_count = Runnable.runnables.sum { |s| s.runnable_methods.count }
         | 
| 50 | 
            +
                    msg('start', { test_count: test_count })
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                  
         | 
| 53 | 
            +
                  def get_output
         | 
| 54 | 
            +
                    return if $stdout.pos == 0
         | 
| 55 | 
            +
                    $stdout.rewind
         | 
| 56 | 
            +
                    res = $stdout.read
         | 
| 57 | 
            +
                    $stdout.flush
         | 
| 58 | 
            +
                    $stdout.rewind
         | 
| 59 | 
            +
                    return unless res
         | 
| 60 | 
            +
                    res.strip.chomp if res.strip.chomp != ""
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                  
         | 
| 63 | 
            +
                  def before_test(test)
         | 
| 64 | 
            +
                    $stdout = StringIO.new()
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 20 67 | 
             
                  def prerecord(klass, name)
         | 
| 21 68 | 
             
                    description = test_description(name)
         | 
| 22 69 | 
             
                    path = test_path(klass.name)
         | 
| @@ -36,6 +83,7 @@ module Minitest | |
| 36 83 | 
             
                  end
         | 
| 37 84 |  | 
| 38 85 | 
             
                  def record(result)
         | 
| 86 | 
            +
                    test_finished(result)
         | 
| 39 87 | 
             
                    description = test_description(result.name)
         | 
| 40 88 | 
             
                    id = ids[description]
         | 
| 41 89 | 
             
                    path = test_path(result.klass)
         | 
| @@ -61,15 +109,133 @@ module Minitest | |
| 61 109 | 
             
                      test_results[path][:file_status] = file_status
         | 
| 62 110 | 
             
                    end
         | 
| 63 111 |  | 
| 64 | 
            -
             | 
| 112 | 
            +
             | 
| 113 | 
            +
                    if ENV['RBCI_REMOTE_TESTS'] == 'true'
         | 
| 114 | 
            +
                      send_events
         | 
| 115 | 
            +
                    else
         | 
| 116 | 
            +
                      RubyCI.minitest_await
         | 
| 117 | 
            +
                    end
         | 
| 65 118 | 
             
                  end
         | 
| 66 119 |  | 
| 67 120 | 
             
                  def method_missing(method, *args)
         | 
| 68 121 | 
             
                    return
         | 
| 69 122 | 
             
                  end
         | 
| 123 | 
            +
                  
         | 
| 124 | 
            +
                  protected
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                  def before_suite(suite)
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                  def after_suite(_suite)
         | 
| 130 | 
            +
                  end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                  def record_print_status(test)
         | 
| 133 | 
            +
                    test_name = test.name.gsub(/^test_: /, "test:")
         | 
| 134 | 
            +
                    print pad_test(test_name)
         | 
| 135 | 
            +
                    print_colored_status(test)
         | 
| 136 | 
            +
                    print(" (%.2fs)" % test.time) unless test.time.nil?
         | 
| 137 | 
            +
                    puts
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                  
         | 
| 140 | 
            +
                  def record_print_failures_if_any(test)
         | 
| 141 | 
            +
                    if !test.skipped? && test.failure
         | 
| 142 | 
            +
                      print_info(test.failure, test.error?)
         | 
| 143 | 
            +
                      puts
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
                  end
         | 
| 146 | 
            +
                  
         | 
| 147 | 
            +
                  def screenshots_base64(output)
         | 
| 148 | 
            +
                    return unless output
         | 
| 149 | 
            +
                    img_path = output&.scan(/\\[Screenshot Image\\]: (.*)$/)&.flatten&.first&.strip&.chomp ||
         | 
| 150 | 
            +
                      output&.scan(/\\[Screenshot\\]: (.*)$/)&.flatten&.first&.strip&.chomp
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                    if img_path && File.exist?(img_path)
         | 
| 153 | 
            +
                      STDOUT.puts "SCREENSHOT!"
         | 
| 154 | 
            +
                      Base64.strict_encode64(File.read(img_path))
         | 
| 155 | 
            +
                    end
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                  
         | 
| 158 | 
            +
                  def test_finished(test)
         | 
| 159 | 
            +
                    output = get_output
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                    location = if !test.source_location.join(":").start_with?(::Rails.root.join('vendor').to_s)
         | 
| 162 | 
            +
                                test.source_location.join(":")
         | 
| 163 | 
            +
                                else
         | 
| 164 | 
            +
                                if (file = `cat #{::Rails.root.join('vendor', 'bundle', 'minitest_cache_file').to_s} | grep "#{test.klass} => "`.split(" => ").last&.chomp)
         | 
| 165 | 
            +
                                  file + ":"
         | 
| 166 | 
            +
                                else
         | 
| 167 | 
            +
                                  file = `grep -rw "#{::Rails.root.to_s}" -e "#{test.klass} "`.split(":").first
         | 
| 168 | 
            +
                                  `echo "#{test.klass} => #{file}" >> #{::Rails.root.join('vendor', 'bundle', 'minitest_cache_file').to_s}`
         | 
| 169 | 
            +
                                  file + ":"
         | 
| 170 | 
            +
                                end
         | 
| 171 | 
            +
                                end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                    fully_formatted = if test.failure
         | 
| 174 | 
            +
                                        fully_formatted = "\n" + test.failure.message.split("\n").first
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                                        test.failure.backtrace.each do |l|
         | 
| 177 | 
            +
                                          if !l["/cache/"]
         | 
| 178 | 
            +
                                            fully_formatted << "\n    " + cyan + l + "\033[0m"
         | 
| 179 | 
            +
                                          end
         | 
| 180 | 
            +
                                        end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                                        fully_formatted
         | 
| 183 | 
            +
                                      end
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                                      output_inside = output&.split("\n")&.select do |line|
         | 
| 186 | 
            +
                                        !line["Screenshot"]
         | 
| 187 | 
            +
                                      end&.join("\n")
         | 
| 188 | 
            +
                    event_data = {
         | 
| 189 | 
            +
                      test_class: Suite.new(test.klass),
         | 
| 190 | 
            +
                      test_name: test.name.gsub(/^test_\\d*/, "").gsub(/^test_: /, "test:").gsub(/^_/, "").strip,
         | 
| 191 | 
            +
                      assertions_count: test.assertions,
         | 
| 192 | 
            +
                      location: location,
         | 
| 193 | 
            +
                      status: status(test),
         | 
| 194 | 
            +
                      run_time: test.time,
         | 
| 195 | 
            +
                      fully_formatted: fully_formatted,
         | 
| 196 | 
            +
                      output_inside: output_inside,
         | 
| 197 | 
            +
                      screenshots_base64: [screenshots_base64(output)]
         | 
| 198 | 
            +
                    }
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                    msg('test_finished', event_data)
         | 
| 201 | 
            +
                    if ENV['RBCI_REMOTE_TESTS'] == 'true'
         | 
| 202 | 
            +
                      send_events if @events.length >= 10
         | 
| 203 | 
            +
                    end
         | 
| 204 | 
            +
                  end
         | 
| 205 | 
            +
                  
         | 
| 206 | 
            +
                  def status(test)
         | 
| 207 | 
            +
                    if test.passed?
         | 
| 208 | 
            +
                      "passed"
         | 
| 209 | 
            +
                    elsif test.error?
         | 
| 210 | 
            +
                      "error"
         | 
| 211 | 
            +
                    elsif test.skipped?
         | 
| 212 | 
            +
                      "skipped"
         | 
| 213 | 
            +
                    elsif test.failure
         | 
| 214 | 
            +
                      "failed"
         | 
| 215 | 
            +
                    else
         | 
| 216 | 
            +
                      raise("Status not found")
         | 
| 217 | 
            +
                    end
         | 
| 218 | 
            +
                  end
         | 
| 70 219 |  | 
| 71 220 | 
             
                  private
         | 
| 72 221 |  | 
| 222 | 
            +
                  def msg(event, data)
         | 
| 223 | 
            +
                    @events << ["minitest_#{event}".upcase, data]   
         | 
| 224 | 
            +
                  end
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                  def send_events
         | 
| 227 | 
            +
                    return unless @events.length > 0
         | 
| 228 | 
            +
                
         | 
| 229 | 
            +
                    json_events = {
         | 
| 230 | 
            +
                      build_id: RubyCI.configuration.orig_build_id,
         | 
| 231 | 
            +
                      compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(@events), 9)),
         | 
| 232 | 
            +
                    }
         | 
| 233 | 
            +
              
         | 
| 234 | 
            +
                    RubyCI.send_events(json_events)
         | 
| 235 | 
            +
              
         | 
| 236 | 
            +
                    @events = []
         | 
| 237 | 
            +
                  end
         | 
| 238 | 
            +
             | 
| 73 239 | 
             
                  def test_description(name)
         | 
| 74 240 | 
             
                    test_name = name.split('test_').last
         | 
| 75 241 | 
             
                    test_name = test_name[2..-1] if test_name.starts_with?(': ')
         | 
    
        data/lib/ruby_ci/brakeman.rb
    CHANGED
    
    | @@ -6,11 +6,25 @@ require 'zlib' | |
| 6 6 | 
             
            module RubyCI
         | 
| 7 7 | 
             
              module Brakeman
         | 
| 8 8 | 
             
                def self.start
         | 
| 9 | 
            +
                  events = []
         | 
| 10 | 
            +
                  events << ['brakeman_run'.upcase, {}]
         | 
| 9 11 | 
             
                  RubyCI::Brakeman::Commandline.start(output_files: ['tmp/brakeman.json'], ensure_ignore_notes: false)
         | 
| 10 12 |  | 
| 11 13 | 
             
                  content = File.read('tmp/brakeman.json')
         | 
| 12 14 | 
             
                  compressed_data = ::Base64.strict_encode64(Zlib::Deflate.deflate(content, 9))
         | 
| 13 | 
            -
             | 
| 15 | 
            +
             | 
| 16 | 
            +
                  events << ['brakeman_exit_status'.upcase, ['0', { exitstatus: 0, stderr: '', output: '', compressed_data: compressed_data ]]
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  if ENV['RBCI_REMOTE_TESTS'] == 'true'
         | 
| 19 | 
            +
                    json_events = {
         | 
| 20 | 
            +
                      build_id: RubyCI.configuration.orig_build_id,
         | 
| 21 | 
            +
                      compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(events), 9)),
         | 
| 22 | 
            +
                    }
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
                    RubyCI.send_events(json_events)
         | 
| 25 | 
            +
                  else
         | 
| 26 | 
            +
                    RubyCI.report_brakeman(compressed_data, 'passed')
         | 
| 27 | 
            +
                  end
         | 
| 14 28 | 
             
                end
         | 
| 15 29 | 
             
              end
         | 
| 16 30 | 
             
            end
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            module RubyCI
         | 
| 4 4 | 
             
              class Configuration
         | 
| 5 5 | 
             
                attr_accessor :run_key, :build_id, :commit_msg, :commit, :branch,
         | 
| 6 | 
            -
                              :api_url, :secret_key, :author
         | 
| 6 | 
            +
                              :api_url, :secret_key, :author, :rubyci_main_url, :rubyci_api_url, :orig_build_id
         | 
| 7 7 |  | 
| 8 8 | 
             
                def initialize
         | 
| 9 9 | 
             
                  # Settings defaults
         | 
| @@ -15,6 +15,9 @@ module RubyCI | |
| 15 15 | 
             
                  self.api_url = ENV["RUBY_CI_API_URL"] || "api.fast.ci"
         | 
| 16 16 | 
             
                  self.secret_key = ENV.fetch("RUBY_CI_SECRET_KEY")
         | 
| 17 17 | 
             
                  self.author = guess_author
         | 
| 18 | 
            +
                  self.rubyci_main_url = ENV.fetch('RUBYCI_MAIN_URL', 'https://events.ruby.ci')
         | 
| 19 | 
            +
                  self.rubyci_api_url = ENV.fetch('RUBYCI_API_RB_URL', 'https://fast.ruby.ci')
         | 
| 20 | 
            +
                  self.orig_build_id = ENV['RBCI_ORIG_BUILD_ID']
         | 
| 18 21 | 
             
                end
         | 
| 19 22 |  | 
| 20 23 | 
             
                def reset
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            require_relative "rspec_formatter"
         | 
| 3 | 
            +
            require_relative "extract_definitions"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyCI
         | 
| 6 | 
            +
              module DryrunRunnerPrepend
         | 
| 7 | 
            +
                def run(err, out)
         | 
| 8 | 
            +
                  @rspec_started_at = Time.now
         | 
| 9 | 
            +
                  super
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def exit_code(examples_passed=false)
         | 
| 13 | 
            +
                  run_time = Time.now - (@rspec_started_at || 1.second.ago)
         | 
| 14 | 
            +
                  events = @world.non_example_failure ? [['RSPEC_DRYRUN', { failed_after: run_time, test_env_number: ENV["TEST_ENV_NUMBER"], data: 'error' }]] : [['RSPEC_DRYRUN', { succeed_after: run_time, test_env_number: ENV["TEST_ENV_NUMBER"] }]]
         | 
| 15 | 
            +
                  STDOUT.puts events.inspect
         | 
| 16 | 
            +
                  json_events = {
         | 
| 17 | 
            +
                    build_id: RubyCI.configuration.orig_build_id,
         | 
| 18 | 
            +
                    compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(events), 9)),
         | 
| 19 | 
            +
                  }
         | 
| 20 | 
            +
                  RubyCI.send_events(json_events)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  return @configuration.error_exit_code || @configuration.failure_exit_code if @world.non_example_failure
         | 
| 23 | 
            +
                  return @configuration.failure_exit_code unless examples_passed
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  0
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,113 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RubyCI
         | 
| 4 | 
            +
              class RspecDryrunFormatter
         | 
| 5 | 
            +
                RSpec::Core::Formatters.register self,
         | 
| 6 | 
            +
                :start,
         | 
| 7 | 
            +
                :message,
         | 
| 8 | 
            +
                :example_passed,
         | 
| 9 | 
            +
                :example_failed,
         | 
| 10 | 
            +
                :example_pending,
         | 
| 11 | 
            +
                :example_group_finished,
         | 
| 12 | 
            +
                :example_group_started,
         | 
| 13 | 
            +
                :dump_summary,
         | 
| 14 | 
            +
                :close
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def initialize(output)
         | 
| 17 | 
            +
                  @output = output
         | 
| 18 | 
            +
                  @current_group_path = []
         | 
| 19 | 
            +
                  @current_file = nil
         | 
| 20 | 
            +
                  @current_file_count = 0
         | 
| 21 | 
            +
                  @events = []
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
                def message(message_notification)
         | 
| 25 | 
            +
                  @output.print message_notification.message
         | 
| 26 | 
            +
                  @output.print "\n"
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
                def start(example_count)
         | 
| 30 | 
            +
                  msg(:start, { "example_count" => example_count.count, "timestamp" => time_now })
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
                def close(*args)
         | 
| 34 | 
            +
                  msg(:close, { "timestamp" => time_now })
         | 
| 35 | 
            +
                  send_events
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              
         | 
| 38 | 
            +
                def dump_summary(summary_notification)
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
                def time_now
         | 
| 42 | 
            +
                  time_frozen? ? Timecop.return { Time.now } : Time.now
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              
         | 
| 45 | 
            +
                def time_frozen?
         | 
| 46 | 
            +
                  return unless defined?(Timecop)
         | 
| 47 | 
            +
                  Timecop.frozen?
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
                def example_passed(example_notification)
         | 
| 51 | 
            +
                  example_finished(example_notification)
         | 
| 52 | 
            +
                  @output.print RSpec::Core::Formatters::ConsoleCodes.wrap('.', :success)
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                def example_failed(example_notification)
         | 
| 56 | 
            +
                  example_finished(example_notification)
         | 
| 57 | 
            +
                  @output.print RSpec::Core::Formatters::ConsoleCodes.wrap('F', :failure)
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              
         | 
| 60 | 
            +
                def example_pending(example_notification)
         | 
| 61 | 
            +
                  example_finished(example_notification)
         | 
| 62 | 
            +
                  @output.print RSpec::Core::Formatters::ConsoleCodes.wrap('*', :pending)
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              
         | 
| 65 | 
            +
                def start_dump(_notification)
         | 
| 66 | 
            +
                  @output.print "\n"
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def example_group_finished(_group_notification)
         | 
| 70 | 
            +
                  @current_group_path.pop
         | 
| 71 | 
            +
                  if @current_group_path.empty? # its a file
         | 
| 72 | 
            +
                    msg(:file_examples_count, [@current_file, @current_file_count])
         | 
| 73 | 
            +
                    @current_file_count = 0
         | 
| 74 | 
            +
                    @current_file = nil
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              
         | 
| 78 | 
            +
                def example_group_started(group_notification)
         | 
| 79 | 
            +
                  if @current_group_path.size == 0
         | 
| 80 | 
            +
                    @current_file = group_notification.group.metadata[:file_path].gsub("./".freeze, "".freeze)
         | 
| 81 | 
            +
                    @current_file_count = 0
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                  @current_group_path << 1
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                private
         | 
| 87 | 
            +
              
         | 
| 88 | 
            +
                def example_finished(example_notification)
         | 
| 89 | 
            +
                  @current_file_count += 1
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              
         | 
| 92 | 
            +
                def send_events
         | 
| 93 | 
            +
                  return unless @events.length > 0
         | 
| 94 | 
            +
              
         | 
| 95 | 
            +
                  json_events = {
         | 
| 96 | 
            +
                    build_id: RubyCI.configuration.orig_build_id,
         | 
| 97 | 
            +
                    compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(@events), 9)),
         | 
| 98 | 
            +
                  }
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  RubyCI.send_events(json_events)
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  @events = []
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
              
         | 
| 105 | 
            +
                def msg(event, data)
         | 
| 106 | 
            +
                  @events << ["rspec_dryrun_#{event}".upcase, ['0', data]]
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
              
         | 
| 109 | 
            +
                def get_scope_id(metadata)
         | 
| 110 | 
            +
                  metadata[:scoped_id].split(":").last || raise("No scoped id")
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
            end
         | 
| @@ -4,9 +4,57 @@ module RubyCI | |
| 4 4 | 
             
              class RspecFormatter
         | 
| 5 5 | 
             
                attr_reader :current_test_key
         | 
| 6 6 |  | 
| 7 | 
            -
                def initialize
         | 
| 8 | 
            -
                  @output =  | 
| 7 | 
            +
                def initialize(output)
         | 
| 8 | 
            +
                  @output = output
         | 
| 9 | 
            +
                  @event_output = {}
         | 
| 9 10 | 
             
                  @is_failed = false
         | 
| 11 | 
            +
                  @current_path = []
         | 
| 12 | 
            +
                  @current_path_started_at = []
         | 
| 13 | 
            +
                  @max_heap_live_num = 0
         | 
| 14 | 
            +
                  @dup_stdout = STDOUT.clone
         | 
| 15 | 
            +
                  @events = []
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  $stdout = StringIO.new()
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  @log_thread = Thread.new do
         | 
| 20 | 
            +
                    loop do
         | 
| 21 | 
            +
                      sleep 10
         | 
| 22 | 
            +
                      check_heap_live_num
         | 
| 23 | 
            +
                      @should_send_events = true
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def time_now
         | 
| 29 | 
            +
                  time_frozen? ? Timecop.return { Time.now } : Time.now
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def time_frozen?
         | 
| 33 | 
            +
                  return unless defined?(Timecop)
         | 
| 34 | 
            +
                  Timecop.frozen?
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def rspec_runner_index
         | 
| 38 | 
            +
                  ENV["TEST_ENV_NUMBER"]
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def send_events
         | 
| 42 | 
            +
                  @should_send_events = false
         | 
| 43 | 
            +
              
         | 
| 44 | 
            +
                  if @events.length > 0
         | 
| 45 | 
            +
                    json_events = {
         | 
| 46 | 
            +
                      build_id: RubyCI.configuration.orig_build_id,
         | 
| 47 | 
            +
                      compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(@events), 9)),
         | 
| 48 | 
            +
                    }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    RubyCI.send_events(json_events)
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    @events = []
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              
         | 
| 56 | 
            +
                def check_heap_live_num
         | 
| 57 | 
            +
                  @max_heap_live_num = [@max_heap_live_num, GC.stat[:heap_live_slots] || GC.stat[:heap_live_num]].max
         | 
| 10 58 | 
             
                end
         | 
| 11 59 |  | 
| 12 60 | 
             
                def passed?
         | 
| @@ -17,13 +65,100 @@ module RubyCI | |
| 17 65 | 
             
                  @current_test_key = value
         | 
| 18 66 | 
             
                end
         | 
| 19 67 |  | 
| 68 | 
            +
                def start(start_notification)
         | 
| 69 | 
            +
                  # $stderr = $stdout
         | 
| 70 | 
            +
              
         | 
| 71 | 
            +
                  data = {
         | 
| 72 | 
            +
                    load_time: start_notification.load_time,
         | 
| 73 | 
            +
                    example_count: start_notification.count,
         | 
| 74 | 
            +
                    started_at: time_now.to_s
         | 
| 75 | 
            +
                  }
         | 
| 76 | 
            +
              
         | 
| 77 | 
            +
                  return if running_only_failed? ||
         | 
| 78 | 
            +
                    running_gem_or_engine? ||
         | 
| 79 | 
            +
                    ENV["EXTRA_SLOWER_RUN"]
         | 
| 80 | 
            +
              
         | 
| 81 | 
            +
                  msg(:start, data)
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
              
         | 
| 84 | 
            +
                def close(null_notification)
         | 
| 85 | 
            +
                  # check_heap_live_num
         | 
| 86 | 
            +
                  msg(:gc_stat, GC.stat.merge(max_heap_live_num: @max_heap_live_num))
         | 
| 87 | 
            +
                  unless running_only_failed? || ENV["EXTRA_SLOWER_RUN"] || running_gem_or_engine?
         | 
| 88 | 
            +
                    msg(:close, {final_output: get_output})
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
                  send_events
         | 
| 91 | 
            +
                  $stdout = @dup_stdout
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
              
         | 
| 94 | 
            +
                def example_group_started(group_notification)
         | 
| 95 | 
            +
                  metadata = group_notification.group.metadata
         | 
| 96 | 
            +
                  @current_path_started_at << time_now
         | 
| 97 | 
            +
              
         | 
| 98 | 
            +
                  if @current_path.size == 0
         | 
| 99 | 
            +
                    @example_failed_index = 0
         | 
| 100 | 
            +
                    file_path = metadata[:file_path].gsub("./".freeze, "".freeze)
         | 
| 101 | 
            +
                    file_path = [ENV["DIR_PREFIX"], file_path].join("/") if ENV["DIR_PREFIX"]
         | 
| 102 | 
            +
                    @current_path << file_path
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
              
         | 
| 105 | 
            +
                  @current_path << id(metadata)
         | 
| 106 | 
            +
              
         | 
| 107 | 
            +
                  msg(:group_started, [
         | 
| 108 | 
            +
                    path_with_file(group_notification.group),
         | 
| 109 | 
            +
                    {
         | 
| 110 | 
            +
                      line_number: metadata[:line_number],
         | 
| 111 | 
            +
                      description: metadata[:description],
         | 
| 112 | 
            +
                    }
         | 
| 113 | 
            +
                  ])
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
              
         | 
| 116 | 
            +
                def example_started(example_notification)
         | 
| 117 | 
            +
                  @output_before = get_output
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
              
         | 
| 120 | 
            +
                def example_passed(example_notification)
         | 
| 121 | 
            +
                  metadata = example_notification.example.metadata
         | 
| 122 | 
            +
                  broadcast_example_finished(serialize_example(metadata, "passed".freeze), example_notification.example)
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
              
         | 
| 125 | 
            +
                def example_failed(example_notification)
         | 
| 126 | 
            +
                  @example_failed_index += 1
         | 
| 127 | 
            +
                  metadata = example_notification.example.metadata
         | 
| 128 | 
            +
                  fully_formatted = example_notification.fully_formatted(@example_failed_index, ::RSpec::Core::Formatters::ConsoleCodes)
         | 
| 129 | 
            +
              
         | 
| 130 | 
            +
                  broadcast_example_finished(
         | 
| 131 | 
            +
                    serialize_example(metadata, "failed".freeze, fully_formatted),
         | 
| 132 | 
            +
                    example_notification.example
         | 
| 133 | 
            +
                  )
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
              
         | 
| 136 | 
            +
                def example_pending(example_notification)
         | 
| 137 | 
            +
                  metadata = example_notification.example.metadata
         | 
| 138 | 
            +
                  broadcast_example_finished(
         | 
| 139 | 
            +
                    serialize_example(metadata, "pending".freeze),
         | 
| 140 | 
            +
                    example_notification.example
         | 
| 141 | 
            +
                  )
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                def example_group_finished(group_notification)
         | 
| 145 | 
            +
                  run_time = time_now - @current_path_started_at.pop
         | 
| 146 | 
            +
                  if (run_time < 0) || (run_time > 2400)
         | 
| 147 | 
            +
                    run_time = 0.525
         | 
| 148 | 
            +
                  end
         | 
| 149 | 
            +
                    msg(:group_finished, [path_with_file(group_notification.group), {run_time: run_time}])
         | 
| 150 | 
            +
                    # msg(:group_finished, [@current_path.map(&:to_s), {run_time: run_time}])
         | 
| 151 | 
            +
                  @current_path.pop
         | 
| 152 | 
            +
                  @current_path.pop if @current_path.size == 1 # Remove the file_path at the beggining
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 20 155 | 
             
                def example_finished(notification)
         | 
| 21 156 | 
             
                  example =  notification.example
         | 
| 22 157 | 
             
                  metadata = example.metadata
         | 
| 23 158 |  | 
| 24 159 | 
             
                  *example_group_ids, example_id = metadata[:scoped_id].split(":")
         | 
| 25 160 |  | 
| 26 | 
            -
                  file_output = @ | 
| 161 | 
            +
                  file_output = @event_output[current_test_key] ||= {}
         | 
| 27 162 |  | 
| 28 163 | 
             
                  example_group = example_group_ids.reduce(file_output) do |output, scope_id|
         | 
| 29 164 | 
             
                    output[scope_id] ||= {}
         | 
| @@ -49,9 +184,91 @@ module RubyCI | |
| 49 184 | 
             
                end
         | 
| 50 185 |  | 
| 51 186 | 
             
                def dump_and_reset
         | 
| 52 | 
            -
                   | 
| 53 | 
            -
                  @ | 
| 54 | 
            -
                   | 
| 187 | 
            +
                  event_output = @event_output
         | 
| 188 | 
            +
                  @event_output = {}
         | 
| 189 | 
            +
                  event_output
         | 
| 190 | 
            +
                end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                def path_with_file(group)
         | 
| 193 | 
            +
                  file_path = group.parent_groups.last.file_path.gsub("./".freeze, "".freeze)
         | 
| 194 | 
            +
              
         | 
| 195 | 
            +
                  group.metadata[:scoped_id].split(":").unshift(file_path)
         | 
| 196 | 
            +
                end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                private
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                def running_gem_or_engine?
         | 
| 201 | 
            +
                  !!ENV["DIR_PREFIX"]
         | 
| 202 | 
            +
                end
         | 
| 203 | 
            +
              
         | 
| 204 | 
            +
                def running_only_failed?
         | 
| 205 | 
            +
                  !!ENV["RERUN_FAILED_FILES"]
         | 
| 206 | 
            +
                end
         | 
| 207 | 
            +
              
         | 
| 208 | 
            +
                def serialize_example(metadata, status, fully_formatted = nil)
         | 
| 209 | 
            +
                  run_time = metadata[:execution_result].run_time
         | 
| 210 | 
            +
                  if (run_time < 0) || (run_time > 2400)
         | 
| 211 | 
            +
                    run_time = 0.525
         | 
| 212 | 
            +
                  end
         | 
| 213 | 
            +
              
         | 
| 214 | 
            +
                  result = {
         | 
| 215 | 
            +
                    id: id(metadata),
         | 
| 216 | 
            +
                    status: status,
         | 
| 217 | 
            +
                    line_number: metadata[:line_number].to_s,
         | 
| 218 | 
            +
                    description: metadata[:description],
         | 
| 219 | 
            +
                    run_time: run_time,
         | 
| 220 | 
            +
                    fully_formatted: fully_formatted,
         | 
| 221 | 
            +
                    scoped_id: metadata[:scoped_id],
         | 
| 222 | 
            +
                  }.compact
         | 
| 223 | 
            +
              
         | 
| 224 | 
            +
                  result[:gem_or_engine] = true if running_gem_or_engine?
         | 
| 225 | 
            +
              
         | 
| 226 | 
            +
                  if running_only_failed?
         | 
| 227 | 
            +
                    result[:reruned] = true
         | 
| 228 | 
            +
                  elsif status == "failed" && !running_gem_or_engine?
         | 
| 229 | 
            +
                    File.write('tmp/rspec_failures', "#{@current_path.first}[#{metadata[:scoped_id]}]", mode: 'a+')
         | 
| 230 | 
            +
                  end
         | 
| 231 | 
            +
              
         | 
| 232 | 
            +
                  if status == "failed"
         | 
| 233 | 
            +
                    img_path = metadata.dig(:screenshot, :image) ||
         | 
| 234 | 
            +
                      fully_formatted&.scan(/\[Screenshot Image\]: (.*)$/).flatten.first&.strip&.chomp ||
         | 
| 235 | 
            +
                      fully_formatted&.scan(/\[Screenshot\]: (.*)$/).flatten.first&.strip&.chomp
         | 
| 236 | 
            +
              
         | 
| 237 | 
            +
                    if img_path && File.exist?(img_path)
         | 
| 238 | 
            +
                      STDOUT.puts "SCREENSHOT!"
         | 
| 239 | 
            +
                      result[:screenshots_base64] ||= []
         | 
| 240 | 
            +
                      result[:screenshots_base64] << Base64.strict_encode64(File.read(img_path))
         | 
| 241 | 
            +
                    end
         | 
| 242 | 
            +
                  end
         | 
| 243 | 
            +
                  @last_example_finished_at = time_now
         | 
| 244 | 
            +
                  # TODO annalyze this: run_time: metadata[:execution_result].run_time,
         | 
| 245 | 
            +
                  result
         | 
| 246 | 
            +
                end
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                def msg(event, data)
         | 
| 249 | 
            +
                  @events << ["rspec_#{event}".upcase, [rspec_runner_index, data]]
         | 
| 250 | 
            +
                end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                def id(metadata)
         | 
| 253 | 
            +
                  metadata[:scoped_id].split(":").last || raise("No scoped id")
         | 
| 254 | 
            +
                end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                def broadcast_example_finished(data, example)
         | 
| 257 | 
            +
                  msg(:example_finished, [
         | 
| 258 | 
            +
                    path_with_file(example.example_group),
         | 
| 259 | 
            +
                    data.merge(output_inside: get_output, output_before: @output_before)
         | 
| 260 | 
            +
                  ])
         | 
| 261 | 
            +
              
         | 
| 262 | 
            +
                  send_events if @should_send_events
         | 
| 263 | 
            +
                end
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                def get_output
         | 
| 266 | 
            +
                  return if $stdout.pos == 0
         | 
| 267 | 
            +
                  $stdout.rewind
         | 
| 268 | 
            +
                  res = $stdout.read
         | 
| 269 | 
            +
                  $stdout.flush
         | 
| 270 | 
            +
                  $stdout.rewind
         | 
| 271 | 
            +
                  res
         | 
| 55 272 | 
             
                end
         | 
| 56 273 | 
             
              end
         | 
| 57 274 | 
             
            end
         | 
| @@ -10,6 +10,8 @@ module RubyCI | |
| 10 10 | 
             
                module Cli
         | 
| 11 11 | 
             
                  class Application < ::RubyCritic::Cli::Application
         | 
| 12 12 | 
             
                    def execute
         | 
| 13 | 
            +
                      events = []
         | 
| 14 | 
            +
                      events << ['ruby_critic_run'.upcase, {}]
         | 
| 13 15 | 
             
                      status = super
         | 
| 14 16 |  | 
| 15 17 | 
             
                      content = File.read('tmp/rubycritic/report.json')
         | 
| @@ -29,8 +31,18 @@ module RubyCI | |
| 29 31 | 
             
                      end
         | 
| 30 32 |  | 
| 31 33 | 
             
                      compressed_data = ::Base64.strict_encode64(Zlib::Deflate.deflate(report.to_json, 9))
         | 
| 32 | 
            -
                       | 
| 34 | 
            +
                      events << ['ruby_critic_exit_status'.upcase, { exitstatus: status, output: '', compressed_data: compressed_data }]
         | 
| 33 35 |  | 
| 36 | 
            +
                      if ENV['RBCI_REMOTE_TESTS'] == 'true'
         | 
| 37 | 
            +
                        json_events = {
         | 
| 38 | 
            +
                          build_id: RubyCI.configuration.orig_build_id,
         | 
| 39 | 
            +
                          compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(events), 9)),
         | 
| 40 | 
            +
                        }
         | 
| 41 | 
            +
                  
         | 
| 42 | 
            +
                        RubyCI.send_events(json_events)
         | 
| 43 | 
            +
                      else
         | 
| 44 | 
            +
                        RubyCI.report_ruby_critic(compressed_data, 'passed')
         | 
| 45 | 
            +
                      end
         | 
| 34 46 | 
             
                      return status
         | 
| 35 47 | 
             
                    end
         | 
| 36 48 | 
             
                  end
         | 
| @@ -5,6 +5,13 @@ require_relative "extract_definitions" | |
| 5 5 | 
             
            module RubyCI
         | 
| 6 6 | 
             
              module RunnerPrepend
         | 
| 7 7 | 
             
                def run_specs(example_groups)
         | 
| 8 | 
            +
                  @rspec_started_at = Time.now
         | 
| 9 | 
            +
                  json_events = {
         | 
| 10 | 
            +
                    build_id: RubyCI.configuration.orig_build_id,
         | 
| 11 | 
            +
                    compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate([['RSPEC_RUN', { started_at: @rspec_started_at, test_env_number: ENV["TEST_ENV_NUMBER"] }]]), 9)),
         | 
| 12 | 
            +
                  }
         | 
| 13 | 
            +
                  RubyCI.send_events(json_events)
         | 
| 14 | 
            +
             | 
| 8 15 | 
             
                  examples_count = @world.example_count(example_groups)
         | 
| 9 16 |  | 
| 10 17 | 
             
                  example_groups = example_groups.reduce({}) do |acc, ex_group|
         | 
| @@ -43,9 +50,19 @@ module RubyCI | |
| 43 50 | 
             
                        return @configuration.failure_exit_code
         | 
| 44 51 | 
             
                      end
         | 
| 45 52 |  | 
| 46 | 
            -
                      formatter = RubyCI::RspecFormatter.new
         | 
| 53 | 
            +
                      formatter = RubyCI::RspecFormatter.new(STDOUT)
         | 
| 47 54 |  | 
| 48 55 | 
             
                      reporter.register_listener(formatter, :example_finished)
         | 
| 56 | 
            +
                      if ENV['RBCI_REMOTE_TESTS'] == 'true'
         | 
| 57 | 
            +
                        reporter.register_listener(formatter, :start)
         | 
| 58 | 
            +
                        reporter.register_listener(formatter, :example_group_started)
         | 
| 59 | 
            +
                        reporter.register_listener(formatter, :example_started)
         | 
| 60 | 
            +
                        reporter.register_listener(formatter, :example_passed)
         | 
| 61 | 
            +
                        reporter.register_listener(formatter, :example_failed)
         | 
| 62 | 
            +
                        reporter.register_listener(formatter, :example_pending)
         | 
| 63 | 
            +
                        reporter.register_listener(formatter, :example_group_finished)
         | 
| 64 | 
            +
                        reporter.register_listener(formatter, :close)
         | 
| 65 | 
            +
                      end
         | 
| 49 66 |  | 
| 50 67 | 
             
                      RubyCI.rspec_ws.on(:deq) do |tests|
         | 
| 51 68 | 
             
                        tests.each do |test|
         | 
| @@ -71,6 +88,14 @@ module RubyCI | |
| 71 88 | 
             
                end
         | 
| 72 89 |  | 
| 73 90 | 
             
                def exit_code(examples_passed=false)
         | 
| 91 | 
            +
                  run_time = Time.now - (@rspec_started_at || 1.second.ago)
         | 
| 92 | 
            +
                  events = @world.non_example_failure ? [['RSPEC_RUN', { failed_after: run_time, test_env_number: ENV["TEST_ENV_NUMBER"] }]] : [['RSPEC_RUN', { succeed_after: run_time, test_env_number: ENV["TEST_ENV_NUMBER"] }]]
         | 
| 93 | 
            +
                  json_events = {
         | 
| 94 | 
            +
                    build_id: RubyCI.configuration.orig_build_id,
         | 
| 95 | 
            +
                    compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(events), 9)),
         | 
| 96 | 
            +
                  }
         | 
| 97 | 
            +
                  RubyCI.send_events(json_events)
         | 
| 98 | 
            +
             | 
| 74 99 | 
             
                  return @configuration.error_exit_code || @configuration.failure_exit_code if @world.non_example_failure
         | 
| 75 100 | 
             
                  return @configuration.failure_exit_code unless examples_passed
         | 
| 76 101 |  | 
    
        data/lib/ruby_ci/simple_cov.rb
    CHANGED
    
    | @@ -2,6 +2,67 @@ require_relative "simple_cov/reporting" | |
| 2 2 |  | 
| 3 3 | 
             
            module RubyCI
         | 
| 4 4 | 
             
              module SimpleCov
         | 
| 5 | 
            -
                 | 
| 5 | 
            +
                if ENV['RBCI_REMOTE_TESTS'] == 'true' && ENV["SIMPLECOV_ACTIVE"] && ENV['DRYRUN'] != 'true'
         | 
| 6 | 
            +
                  ::SimpleCov.send(:at_exit) do
         | 
| 7 | 
            +
                    ::SimpleCov.result.format!
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    config = {
         | 
| 10 | 
            +
                      minimum_coverage: ::SimpleCov.minimum_coverage,
         | 
| 11 | 
            +
                      maximum_coverage_drop: ::SimpleCov.maximum_coverage_drop,
         | 
| 12 | 
            +
                      minimum_coverage_by_file: ::SimpleCov.minimum_coverage_by_file,
         | 
| 13 | 
            +
                    }
         | 
| 14 | 
            +
                    rspec_runner_index = ENV["TEST_ENV_NUMBER".freeze].to_i
         | 
| 15 | 
            +
                    events = [['simplecov_config'.upcase, [ rspec_runner_index, config ]]]
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    json_events = {
         | 
| 18 | 
            +
                      build_id: RubyCI.configuration.orig_build_id,
         | 
| 19 | 
            +
                      compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(events), 9)),
         | 
| 20 | 
            +
                    }
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
                    RubyCI.send_events(json_events)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  module PrependSc
         | 
| 26 | 
            +
                    def start(*args, &block)
         | 
| 27 | 
            +
                      add_filter "tmp"
         | 
| 28 | 
            +
                      merge_timeout 3600
         | 
| 29 | 
            +
                      command_name "RSpec_#{ENV["TEST_ENV_NUMBER".freeze].to_i}"
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      if ENV["NO_COVERAGE"]
         | 
| 32 | 
            +
                        use_merging false
         | 
| 33 | 
            +
                        return
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
                      super
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  ::SimpleCov.singleton_class.prepend(PrependSc)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  module Scf
         | 
| 41 | 
            +
                    def format!
         | 
| 42 | 
            +
                      return if ENV["NO_COVERAGE"]
         | 
| 43 | 
            +
                      rspec_runner_index = ENV["TEST_ENV_NUMBER".freeze].to_i
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      original_result_json = if ENV['CI_PROJECT_DIR'].present?
         | 
| 46 | 
            +
                        JSON.fast_generate(original_result.transform_keys {|key| key.sub(ENV['CI_PROJECT_DIR'], '/app') })
         | 
| 47 | 
            +
                      else
         | 
| 48 | 
            +
                        JSON.fast_generate(original_result)
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                      compressed_data = Base64.strict_encode64(Zlib::Deflate.deflate(original_result_json, 9))
         | 
| 51 | 
            +
                      events = [['simplecov_result'.upcase, [ rspec_runner_index, compressed_data ]]]
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      json_events = {
         | 
| 54 | 
            +
                        build_id: RubyCI.configuration.orig_build_id,
         | 
| 55 | 
            +
                        compressed_data: Base64.strict_encode64(Zlib::Deflate.deflate(JSON.fast_generate(events), 9)),
         | 
| 56 | 
            +
                      }
         | 
| 57 | 
            +
                
         | 
| 58 | 
            +
                      RubyCI.send_events(json_events)
         | 
| 59 | 
            +
                      super
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  ::SimpleCov::Result.prepend(Scf)
         | 
| 64 | 
            +
                else
         | 
| 65 | 
            +
                  ::SimpleCov.send(:include, RubyCI::SimpleCov::Reporting) unless ENV['DRYRUN'] == 'true'
         | 
| 66 | 
            +
                end
         | 
| 6 67 | 
             
              end
         | 
| 7 68 | 
             
            end
         | 
    
        data/lib/ruby_ci/version.rb
    CHANGED
    
    
    
        data/lib/ruby_ci.rb
    CHANGED
    
    | @@ -67,7 +67,12 @@ module RubyCI | |
| 67 67 | 
             
                end
         | 
| 68 68 |  | 
| 69 69 | 
             
                def post_report(data)
         | 
| 70 | 
            -
                  uri = URI( | 
| 70 | 
            +
                  uri = URI("#{RubyCI.configuration.rubyci_api_url}/api/runs")
         | 
| 71 | 
            +
                  res = Net::HTTP.post_form(uri, data)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def send_events(data)
         | 
| 75 | 
            +
                  uri = URI("#{RubyCI.configuration.rubyci_main_url}/api/v1/gitlab_events")
         | 
| 71 76 | 
             
                  res = Net::HTTP.post_form(uri, data)
         | 
| 72 77 | 
             
                end
         | 
| 73 78 | 
             
              end
         | 
    
        data/ruby_ci.gemspec
    CHANGED
    
    | @@ -30,5 +30,6 @@ Gem::Specification.new do |spec| | |
| 30 30 | 
             
              spec.add_dependency "async-websocket", '<= 0.20.0'
         | 
| 31 31 | 
             
              spec.add_dependency "rubycritic", "~> 4.8.0"
         | 
| 32 32 | 
             
              spec.add_dependency "brakeman", "~> 5.4.1"
         | 
| 33 | 
            +
              spec.add_dependency "minitest-rails", ">= 5.1"
         | 
| 33 34 | 
             
              spec.add_development_dependency "pry"
         | 
| 34 35 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ruby_ci
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.2. | 
| 4 | 
            +
              version: 0.2.6
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ale ∴
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-07-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: console
         | 
| @@ -66,6 +66,20 @@ dependencies: | |
| 66 66 | 
             
                - - "~>"
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: 5.4.1
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: minitest-rails
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '5.1'
         | 
| 76 | 
            +
              type: :runtime
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ">="
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '5.1'
         | 
| 69 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 84 | 
             
              name: pry
         | 
| 71 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -109,8 +123,10 @@ files: | |
| 109 123 | 
             
            - lib/ruby_ci/brakeman.rb
         | 
| 110 124 | 
             
            - lib/ruby_ci/brakeman/commandline.rb
         | 
| 111 125 | 
             
            - lib/ruby_ci/configuration.rb
         | 
| 126 | 
            +
            - lib/ruby_ci/dryrun_runner_prepend.rb
         | 
| 112 127 | 
             
            - lib/ruby_ci/exceptions.rb
         | 
| 113 128 | 
             
            - lib/ruby_ci/extract_definitions.rb
         | 
| 129 | 
            +
            - lib/ruby_ci/rspec_dryrun_formatter.rb
         | 
| 114 130 | 
             
            - lib/ruby_ci/rspec_formatter.rb
         | 
| 115 131 | 
             
            - lib/ruby_ci/ruby_critic/cli/application.rb
         | 
| 116 132 | 
             
            - lib/ruby_ci/runner_prepend.rb
         |