From 7a183da267f343bde0a7ec2add80164a08e1a875 Mon Sep 17 00:00:00 2001 From: Dan Mayer Date: Sat, 20 Apr 2024 16:46:18 -0600 Subject: [PATCH] re-apply standardrb, my editor applied rubocop ;( --- lib/coverband/adapters/hash_redis_store.rb | 83 +++++----- lib/coverband/configuration.rb | 173 +++++++++++---------- lib/coverband/reporters/json_report.rb | 26 ++-- 3 files changed, 143 insertions(+), 139 deletions(-) diff --git a/lib/coverband/adapters/hash_redis_store.rb b/lib/coverband/adapters/hash_redis_store.rb index fc5b1caf..503b9bd3 100644 --- a/lib/coverband/adapters/hash_redis_store.rb +++ b/lib/coverband/adapters/hash_redis_store.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -require 'securerandom' +require "securerandom" module Coverband module Adapters class HashRedisStore < Base class GetCoverageNullCacheStore - def self.clear!(*_local_types); end + def self.clear!(*_local_types) + end def self.fetch(_local_type) yield(0) @@ -18,7 +19,7 @@ class GetCoverageRedisCacheStore def initialize(redis, key_prefix) @redis = redis - @key_prefix = [key_prefix, 'get-coverage'].join('.') + @key_prefix = [key_prefix, "get-coverage"].join(".") end def fetch(local_type) @@ -72,7 +73,7 @@ def set(local_type, value) # lock for at most 60 minutes def lock!(local_type) - @redis.set("#{@key_prefix}.lock.#{local_type}", '1', nx: true, ex: LOCK_LIMIT) + @redis.set("#{@key_prefix}.lock.#{local_type}", "1", nx: true, ex: LOCK_LIMIT) end def unlock!(local_type) @@ -80,15 +81,15 @@ def unlock!(local_type) end end - FILE_KEY = 'file' - FILE_LENGTH_KEY = 'file_length' + FILE_KEY = "file" + FILE_LENGTH_KEY = "file_length" META_DATA_KEYS = [DATA_KEY, FIRST_UPDATED_KEY, LAST_UPDATED_KEY, FILE_HASH].freeze ### # This key isn't related to the coverband version, but to the internal format # used to store data to redis. It is changed only when breaking changes to our # redis format are required. ### - REDIS_STORAGE_FORMAT_VERSION = 'coverband_hash_4_0' + REDIS_STORAGE_FORMAT_VERSION = "coverband_hash_4_0" JSON_PAYLOAD_EXPIRATION = 5 * 60 @@ -100,24 +101,24 @@ def initialize(redis, opts = {}) @save_report_batch_size = opts[:save_report_batch_size] || 100 @format_version = REDIS_STORAGE_FORMAT_VERSION @redis = redis - raise 'HashRedisStore requires redis >= 2.6.0' unless supported? + raise "HashRedisStore requires redis >= 2.6.0" unless supported? @ttl = opts[:ttl] @relative_file_converter = opts[:relative_file_converter] || Utils::RelativeFileConverter @get_coverage_cache = if opts[:get_coverage_cache] - key_prefix = [REDIS_STORAGE_FORMAT_VERSION, @redis_namespace].compact.join('.') - GetCoverageRedisCacheStore.new(redis, key_prefix) - else - GetCoverageNullCacheStore - end + key_prefix = [REDIS_STORAGE_FORMAT_VERSION, @redis_namespace].compact.join(".") + GetCoverageRedisCacheStore.new(redis, key_prefix) + else + GetCoverageNullCacheStore + end end def supported? - Gem::Version.new(@redis.info['redis_version']) >= Gem::Version.new('2.6.0') + Gem::Version.new(@redis.info["redis_version"]) >= Gem::Version.new("2.6.0") rescue Redis::CannotConnectError => e Coverband.configuration.logger.info "Redis is not available (#{e}), Coverband not configured" - Coverband.configuration.logger.info 'If this is a setup task like assets:precompile feel free to ignore' + Coverband.configuration.logger.info "If this is a setup task like assets:precompile feel free to ignore" end def clear! @@ -145,7 +146,7 @@ def clear_file!(file) def save_report(report) report_time = Time.now.to_i - updated_time = type == Coverband::EAGER_TYPE ? nil : report_time + updated_time = (type == Coverband::EAGER_TYPE) ? nil : report_time keys = [] report.each_slice(@save_report_batch_size) do |slice| files_data = slice.map do |(file, data)| @@ -164,8 +165,8 @@ def save_report(report) end next unless files_data.any? - arguments_key = [@redis_namespace, SecureRandom.uuid].compact.join('.') - @redis.set(arguments_key, { ttl: @ttl, files_data: files_data }.to_json, ex: JSON_PAYLOAD_EXPIRATION) + arguments_key = [@redis_namespace, SecureRandom.uuid].compact.join(".") + @redis.set(arguments_key, {ttl: @ttl, files_data: files_data}.to_json, ex: JSON_PAYLOAD_EXPIRATION) @redis.evalsha(hash_incr_script, [arguments_key]) end @redis.sadd(files_key, keys) if keys.any? @@ -177,16 +178,16 @@ def coverage(local_type = nil, opts = {}) page_size = opts[:page_size] || 250 cached_results = @get_coverage_cache.fetch(local_type || type) do |sleep_time| files_set = if opts[:page] - raise 'call coverage_for_types with paging' - elsif opts[:filename] - type_key_prefix = key_prefix(local_type) - # NOTE: a better way to extract filename from key would be better - files_set(local_type).select do |cache_key| - cache_key.sub(type_key_prefix, '').match(short_name(opts[:filename])) - end || {} - else - files_set(local_type) - end + raise "call coverage_for_types with paging" + elsif opts[:filename] + type_key_prefix = key_prefix(local_type) + # NOTE: a better way to extract filename from key would be better + files_set(local_type).select do |cache_key| + cache_key.sub(type_key_prefix, "").match(short_name(opts[:filename])) + end || {} + else + files_set(local_type) + end # below uses batches with a sleep in between to avoid overloading redis files_set.each_slice(page_size).flat_map do |key_batch| sleep sleep_time @@ -233,9 +234,9 @@ def coverage_for_types(_types, opts = {}) eager_key_pre = key_prefix(Coverband::EAGER_TYPE) runtime_key_pre = key_prefix(Coverband::RUNTIME_TYPE) matched_file_set = files_set(Coverband::EAGER_TYPE) - .select do |eager_key, _val| + .select do |eager_key, _val| runtime_file_set.any? do |runtime_key| - (eager_key.sub(eager_key_pre, '') == runtime_key.sub(runtime_key_pre, '')) + (eager_key.sub(eager_key_pre, "") == runtime_key.sub(runtime_key_pre, "")) end end || [] hash_data[Coverband::EAGER_TYPE] = matched_file_set.each_slice(page_size).flat_map do |key_batch| @@ -255,8 +256,8 @@ def coverage_for_types(_types, opts = {}) end def short_name(filename) - filename.sub(/^#{Coverband.configuration.root}/, '.') - .gsub(%r{^\./}, '') + filename.sub(/^#{Coverband.configuration.root}/, ".") + .gsub(%r{^\./}, "") end def file_count(local_type = nil) @@ -272,11 +273,11 @@ def raw_store end def size - 'not available' + "not available" end def size_in_mib - 'not available' + "not available" end private @@ -290,11 +291,11 @@ def add_coverage_for_file(data_from_redis, hash) data = coverage_data_from_redis(data_from_redis) hash[file] = data_from_redis.select do |meta_data_key, _value| META_DATA_KEYS.include?(meta_data_key) - end.merge!('data' => data) + end.merge!("data" => data) hash[file][LAST_UPDATED_KEY] = - hash[file][LAST_UPDATED_KEY].nil? || hash[file][LAST_UPDATED_KEY] == '' ? nil : hash[file][LAST_UPDATED_KEY].to_i + (hash[file][LAST_UPDATED_KEY].nil? || hash[file][LAST_UPDATED_KEY] == "") ? nil : hash[file][LAST_UPDATED_KEY].to_i hash[file].merge!(LAST_UPDATED_KEY => hash[file][LAST_UPDATED_KEY], - FIRST_UPDATED_KEY => hash[file][FIRST_UPDATED_KEY].to_i) + FIRST_UPDATED_KEY => hash[file][FIRST_UPDATED_KEY].to_i) end def coverage_data_from_redis(data_from_redis) @@ -330,8 +331,8 @@ def hash_incr_script def lua_script_content File.read(File.join( - File.dirname(__FILE__), '../../../lua/lib/persist-coverage.lua' - )) + File.dirname(__FILE__), "../../../lua/lib/persist-coverage.lua" + )) end def values_from_redis(local_type, files) @@ -355,12 +356,12 @@ def files_key(local_type = nil) end def key(file, local_type = nil, file_hash:) - [key_prefix(local_type), file, file_hash].join('.') + [key_prefix(local_type), file, file_hash].join(".") end def key_prefix(local_type = nil) local_type ||= type - [@format_version, @redis_namespace, local_type].compact.join('.') + [@format_version, @redis_namespace, local_type].compact.join(".") end end end diff --git a/lib/coverband/configuration.rb b/lib/coverband/configuration.rb index 04c4699a..c66c2242 100644 --- a/lib/coverband/configuration.rb +++ b/lib/coverband/configuration.rb @@ -1,23 +1,26 @@ # frozen_string_literal: true module Coverband + ### + # Configuration parsing and options for the coverband gem. + ### class Configuration attr_accessor :root_paths, :root, - :verbose, - :reporter, :redis_namespace, :redis_ttl, - :background_reporting_enabled, - :test_env, :web_enable_clear, :gem_details, :web_debug, :report_on_exit, - :simulate_oneshot_lines_coverage, - :view_tracker, :defer_eager_loading_data, - :track_routes, :route_tracker, - :track_translations, :translations_tracker, - :trackers, :csp_policy, :hide_settings + :verbose, + :reporter, :redis_namespace, :redis_ttl, + :background_reporting_enabled, + :test_env, :web_enable_clear, :gem_details, :web_debug, :report_on_exit, + :simulate_oneshot_lines_coverage, + :view_tracker, :defer_eager_loading_data, + :track_routes, :route_tracker, + :track_translations, :translations_tracker, + :trackers, :csp_policy, :hide_settings attr_writer :logger, :s3_region, :s3_bucket, :s3_access_key_id, - :s3_secret_access_key, :password, :api_key, :service_url, :coverband_timeout, :service_dev_mode, - :service_test_mode, :process_type, :track_views, :redis_url, - :background_reporting_sleep_seconds, :reporting_wiggle, - :send_deferred_eager_loading_data, :paged_reporting + :s3_secret_access_key, :password, :api_key, :service_url, :coverband_timeout, :service_dev_mode, + :service_test_mode, :process_type, :track_views, :redis_url, + :background_reporting_sleep_seconds, :reporting_wiggle, + :send_deferred_eager_loading_data, :paged_reporting attr_reader :track_gems, :ignore, :use_oneshot_lines_coverage @@ -27,21 +30,21 @@ class Configuration # # * Perhaps detect heroku deployment ENV var opposed to tasks? ##### - IGNORE_TASKS = ['coverband:clear', - 'coverband:coverage', - 'coverband:coverage_server', - 'coverband:migrate', - 'assets:precompile', - 'webpacker:compile', - 'db:version', - 'db:create', - 'db:drop', - 'db:seed', - 'db:setup', - 'db:test:prepare', - 'db:structure:dump', - 'db:structure:load', - 'db:version'] + IGNORE_TASKS = ["coverband:clear", + "coverband:coverage", + "coverband:coverage_server", + "coverband:migrate", + "assets:precompile", + "webpacker:compile", + "db:version", + "db:create", + "db:drop", + "db:seed", + "db:setup", + "db:test:prepare", + "db:structure:dump", + "db:structure:load", + "db:version"] # Heroku when building assets runs code from a dynamic directory # /tmp was added to avoid coverage from /tmp/build directories during @@ -62,7 +65,7 @@ def reset @ignore = IGNORE_DEFAULTS.dup @search_paths = TRACKED_DEFAULT_PATHS.dup @verbose = false - @reporter = 'scov' + @reporter = "scov" @logger = nil @store = nil @background_reporting_enabled = true @@ -79,8 +82,8 @@ def reset @translations_tracker = nil @web_debug = false @report_on_exit = true - @use_oneshot_lines_coverage = ENV['ONESHOT'] || false - @simulate_oneshot_lines_coverage = ENV['SIMULATE_ONESHOT'] || false + @use_oneshot_lines_coverage = ENV["ONESHOT"] || false + @simulate_oneshot_lines_coverage = ENV["SIMULATE_ONESHOT"] || false @current_root = nil @all_root_paths = nil @all_root_patterns = nil @@ -125,28 +128,28 @@ def railtie! if Coverband.configuration.track_views Coverband.configuration.view_tracker = if Coverband.coverband_service? - Coverband::Collectors::ViewTrackerService.new - else - Coverband::Collectors::ViewTracker.new - end + Coverband::Collectors::ViewTrackerService.new + else + Coverband::Collectors::ViewTracker.new + end trackers << Coverband.configuration.view_tracker end trackers.each { |tracker| tracker.railtie! } rescue Redis::CannotConnectError => e Coverband.configuration.logger.info "Redis is not available (#{e}), Coverband not configured" - Coverband.configuration.logger.info 'If this is a setup task like assets:precompile feel free to ignore' + Coverband.configuration.logger.info "If this is a setup task like assets:precompile feel free to ignore" end def logger @logger ||= if defined?(Rails.logger) && Rails.logger - Rails.logger - else - Logger.new(STDOUT) - end + Rails.logger + else + Logger.new(STDOUT) + end end def password - @password || ENV['COVERBAND_PASSWORD'] + @password || ENV["COVERBAND_PASSWORD"] end # The adjustments here either protect the redis or service from being overloaded @@ -154,14 +157,14 @@ def password # if running your own redis increasing this number reduces load on the redis CPU def background_reporting_sleep_seconds @background_reporting_sleep_seconds ||= if service? - # default to 10m for service - Coverband.configuration.coverband_env == 'production' ? 600 : 60 - elsif store.is_a?(Coverband::Adapters::HashRedisStore) - # Default to 5 minutes if using the hash redis store - 300 - else - 60 - end + # default to 10m for service + (Coverband.configuration.coverband_env == "production") ? 600 : 60 + elsif store.is_a?(Coverband::Adapters::HashRedisStore) + # Default to 5 minutes if using the hash redis store + 300 + else + 60 + end end def reporting_wiggle @@ -170,25 +173,25 @@ def reporting_wiggle def store @store ||= if service? - if ENV['COVERBAND_REDIS_URL'] - raise 'invalid configuration: unclear default store coverband expects either api_key or redis_url' - end + if ENV["COVERBAND_REDIS_URL"] + raise "invalid configuration: unclear default store coverband expects either api_key or redis_url" + end - require 'coverband/adapters/web_service_store' - Coverband::Adapters::WebServiceStore.new(service_url) - else - Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_store_options) - end + require "coverband/adapters/web_service_store" + Coverband::Adapters::WebServiceStore.new(service_url) + else + Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_store_options) + end end def store=(store) - raise 'Pass in an instance of Coverband::Adapters' unless store.is_a?(Coverband::Adapters::Base) - if api_key && store.class.to_s != 'Coverband::Adapters::WebServiceStore' - raise 'invalid configuration: only coverband service expects an API Key' + raise "Pass in an instance of Coverband::Adapters" unless store.is_a?(Coverband::Adapters::Base) + if api_key && store.class.to_s != "Coverband::Adapters::WebServiceStore" + raise "invalid configuration: only coverband service expects an API Key" end - if ENV['COVERBAND_REDIS_URL'] && - defined?(::Coverband::Adapters::WebServiceStore) && - store.instance_of?(::Coverband::Adapters::WebServiceStore) + if ENV["COVERBAND_REDIS_URL"] && + defined?(::Coverband::Adapters::WebServiceStore) && + store.instance_of?(::Coverband::Adapters::WebServiceStore) raise "invalid configuration: coverband service shouldn't have redis url set" end @@ -205,7 +208,7 @@ def track_views # Search Paths ### def tracked_search_paths - "#{Coverband.configuration.current_root}/{#{@search_paths.join(',')}}/**/*.{rb}" + "#{Coverband.configuration.current_root}/{#{@search_paths.join(",")}}/**/*.{rb}" end ### @@ -222,7 +225,7 @@ def ignore=(ignored_array) ignored_array.map { |ignore_str| Regexp.new(ignore_str) } @ignore = (@ignore + ignored_array).uniq rescue RegexpError - logger.error "an invalid regular expression was passed in, ensure string are valid regex patterns #{ignored_array.join(',')}" + logger.error "an invalid regular expression was passed in, ensure string are valid regex patterns #{ignored_array.join(",")}" end def current_root @@ -245,53 +248,53 @@ def all_root_patterns def to_h instance_variables .each_with_object({}) do |var, hash| - hash[var.to_s.delete('@')] = instance_variable_get(var) unless SKIPPED_SETTINGS.include?(var.to_s) + hash[var.to_s.delete("@")] = instance_variable_get(var) unless SKIPPED_SETTINGS.include?(var.to_s) end end def use_oneshot_lines_coverage=(value) unless one_shot_coverage_implemented_in_ruby_version? || !value raise(StandardError, - 'One shot line coverage is only available in ruby >= 2.6') + "One shot line coverage is only available in ruby >= 2.6") end @use_oneshot_lines_coverage = value end def one_shot_coverage_implemented_in_ruby_version? - Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6.0') + Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0") end def redis_url - @redis_url ||= ENV['COVERBAND_REDIS_URL'] || ENV['REDIS_URL'] + @redis_url ||= ENV["COVERBAND_REDIS_URL"] || ENV["REDIS_URL"] end def api_key - @api_key ||= ENV['COVERBAND_API_KEY'] + @api_key ||= ENV["COVERBAND_API_KEY"] end def service_url - @service_url ||= ENV['COVERBAND_URL'] || 'https://coverband.io' + @service_url ||= ENV["COVERBAND_URL"] || "https://coverband.io" end def coverband_env - ENV['RACK_ENV'] || ENV['RAILS_ENV'] || (defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : 'unknown') + ENV["RACK_ENV"] || ENV["RAILS_ENV"] || ((defined?(Rails) && Rails.respond_to?(:env)) ? Rails.env : "unknown") end def coverband_timeout - @coverband_timeout ||= coverband_env == 'development' ? 5 : 2 + @coverband_timeout ||= (coverband_env == "development") ? 5 : 2 end def service_dev_mode - @service_dev_mode ||= ENV['COVERBAND_ENABLE_DEV_MODE'] || false + @service_dev_mode ||= ENV["COVERBAND_ENABLE_DEV_MODE"] || false end def service_test_mode - @service_test_mode ||= ENV['COVERBAND_ENABLE_TEST_MODE'] || false + @service_test_mode ||= ENV["COVERBAND_ENABLE_TEST_MODE"] || false end def process_type - @process_type ||= ENV['PROCESS_TYPE'] || 'unknown' + @process_type ||= ENV["PROCESS_TYPE"] || "unknown" end def service? @@ -313,35 +316,35 @@ def paged_reporting def service_disabled_dev_test_env? return false unless service? - (coverband_env == 'test' && !Coverband.configuration.service_test_mode) || - (coverband_env == 'development' && !Coverband.configuration.service_dev_mode) + (coverband_env == "test" && !Coverband.configuration.service_test_mode) || + (coverband_env == "development" && !Coverband.configuration.service_dev_mode) end def s3_bucket - puts 'deprecated, s3 is no longer support' + puts "deprecated, s3 is no longer support" end def s3_region - puts 'deprecated, s3 is no longer support' + puts "deprecated, s3 is no longer support" end def s3_access_key_id - puts 'deprecated, s3 is no longer support' + puts "deprecated, s3 is no longer support" end def s3_secret_access_key - puts 'deprecated, s3 is no longer support' + puts "deprecated, s3 is no longer support" end def track_gems=(_value) - puts 'gem tracking is deprecated, setting this will be ignored' + puts "gem tracking is deprecated, setting this will be ignored & eventually removed" end private def redis_store_options - { ttl: Coverband.configuration.redis_ttl, - redis_namespace: Coverband.configuration.redis_namespace } + {ttl: Coverband.configuration.redis_ttl, + redis_namespace: Coverband.configuration.redis_namespace} end end end diff --git a/lib/coverband/reporters/json_report.rb b/lib/coverband/reporters/json_report.rb index bd4be553..a22afdea 100644 --- a/lib/coverband/reporters/json_report.rb +++ b/lib/coverband/reporters/json_report.rb @@ -12,16 +12,16 @@ def initialize(store, options = {}) self.page = options.fetch(:page) { nil } self.filename = options.fetch(:filename) { nil } self.as_report = options.fetch(:as_report) { false } - self.base_path = options.fetch(:base_path) { './' } + self.base_path = options.fetch(:base_path) { "./" } self.store = store coverband_reports = Coverband::Reporters::Base.report(store, options) # NOTE: paged reports can't find and add in files that has never been loaded self.filtered_report_files = if page || filename - coverband_reports - else - self.class.fix_reports(coverband_reports) - end + coverband_reports + else + self.class.fix_reports(coverband_reports) + end end def report @@ -32,13 +32,13 @@ def report def coverage_css_class(covered_percent) if covered_percent.nil? - '' + "" elsif covered_percent > 90 - 'green' + "green" elsif covered_percent > 80 - 'yellow' + "yellow" else - 'red' + "red" end end @@ -54,7 +54,7 @@ def report_as_json if as_report row_data = [] data[:files].each_pair do |key, data| - source_class = data[:never_loaded] ? 'strong red' : 'strong' + source_class = data[:never_loaded] ? "strong red" : "strong" data_loader_url = "#{base_path}load_file_details?filename=#{data[:filename]}" link = "#{key}" # Hack to ensure the sorting works on percentage columns, the span is hidden but colors the cell and the text is used for sorting @@ -73,9 +73,9 @@ def report_as_json ] end filesreported = store.cached_file_count - data['iTotalRecords'] = filesreported - data['iTotalDisplayRecords'] = filesreported - data['aaData'] = row_data + data["iTotalRecords"] = filesreported + data["iTotalDisplayRecords"] = filesreported + data["aaData"] = row_data data.delete(:files) data = data.as_json end