lib/ruboclean/path_cleanup.rb
# frozen_string_literal: true
module Ruboclean
# Cleans up any `Include` or `Exclude` paths that don't exist.
# The `Include` and `Exclude` paths are relative to the directory
# where the `.rubocop.yml` file is located. If a path includes a
# regexp, it's assumed to be valid.
# If all entries in `Include` or `Exclude` are removed, the entire property is removed.
# If a Cop gets entirely truncated due to removing all `Includes` and/or `Exclude`, the Cop itself will be removed.
class PathCleanup
def initialize(configuration_hash, root_directory)
@configuration_hash = configuration_hash
@root_directory = root_directory
end
def cleanup
configuration_hash.each_with_object({}) do |(top_level_key, top_level_value), hash|
result = process_top_level_value(top_level_value)
next if Array(result).empty? # No configuration keys left in the cop, remove the entire cop
hash[top_level_key] = result
end
end
private
attr_reader :configuration_hash, :root_directory
# top_level_value could be something like this:
#
# {
# Include: [...],
# Exclude: [...],
# EnforcedStyle: "..."
# }
#
# We process it further in case of a Hash.
def process_top_level_value(top_level_value)
return top_level_value unless top_level_value.is_a?(Hash)
top_level_value.each_with_object({}) do |(cop_property_key, cop_property_value), hash|
result = process_cop_property(cop_property_key, cop_property_value)
next if Array(result).empty? # No entries left, will skip adding the key to the hash
hash[cop_property_key] = result
end
end
def process_cop_property(cop_property_key, cop_property_value)
return cop_property_value unless %w[Include Exclude].include?(cop_property_key.to_s)
return cop_property_value unless cop_property_value.respond_to?(:filter_map)
cop_property_value.find_all do |item|
path_exists?(item)
end
end
def path_exists?(item)
regexp_pattern?(item) ||
specific_path_exists?(item) ||
any_global_command_pattern?(item)
end
def specific_path_exists?(item)
root_directory.join(item).exist?
end
def any_global_command_pattern?(item)
root_directory.glob(item).any?
end
# We don't support Regexp, so we just say it exists.
def regexp_pattern?(item)
item.is_a?(Regexp)
end
end
end