Class: RuboCop::ResultCache
- Inherits:
-
Object
- Object
- RuboCop::ResultCache
- Defined in:
- lib/rubocop/result_cache.rb
Overview
Provides functionality for caching rubocop runs.
Constant Summary collapse
- NON_CHANGING =
%i[color format formatters out debug fail_level cache fail_fast stdin parallel].freeze
Class Attribute Summary collapse
-
.inhibit_cleanup ⇒ Object
Returns the value of attribute inhibit_cleanup.
-
.source_checksum ⇒ Object
Returns the value of attribute source_checksum.
Class Method Summary collapse
- .allow_symlinks_in_cache_location?(config_store) ⇒ Boolean
- .cache_root(config_store) ⇒ Object
-
.cleanup(config_store, verbose, cache_root = nil) ⇒ Object
Remove old files so that the cache doesn’t grow too big.
Instance Method Summary collapse
-
#initialize(file, options, config_store, cache_root = nil) ⇒ ResultCache
constructor
A new instance of ResultCache.
- #load ⇒ Object
- #save(offenses) ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(file, options, config_store, cache_root = nil) ⇒ ResultCache
Returns a new instance of ResultCache.
79 80 81 82 83 84 85 86 87 |
# File 'lib/rubocop/result_cache.rb', line 79 def initialize(file, , config_store, cache_root = nil) cache_root ||= ResultCache.cache_root(config_store) @allow_symlinks_in_cache_location = ResultCache.allow_symlinks_in_cache_location?(config_store) @path = File.join(cache_root, rubocop_checksum, (), file_checksum(file, config_store)) @cached_data = CachedData.new(file) end |
Class Attribute Details
.inhibit_cleanup ⇒ Object
Returns the value of attribute inhibit_cleanup.
145 146 147 |
# File 'lib/rubocop/result_cache.rb', line 145 def inhibit_cleanup @inhibit_cleanup end |
.source_checksum ⇒ Object
Returns the value of attribute source_checksum.
145 146 147 |
# File 'lib/rubocop/result_cache.rb', line 145 def source_checksum @source_checksum end |
Class Method Details
.allow_symlinks_in_cache_location?(config_store) ⇒ Boolean
75 76 77 |
# File 'lib/rubocop/result_cache.rb', line 75 def self.allow_symlinks_in_cache_location?(config_store) config_store.for('.').for_all_cops['AllowSymlinksInCacheRootDirectory'] end |
.cache_root(config_store) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rubocop/result_cache.rb', line 63 def self.cache_root(config_store) root = config_store.for('.').for_all_cops['CacheRootDirectory'] root ||= if ENV.key?('XDG_CACHE_HOME') # Include user ID in the path to make sure the user has write # access. File.join(ENV['XDG_CACHE_HOME'], Process.uid.to_s) else File.join(ENV['HOME'], '.cache') end File.join(root, 'rubocop_cache') end |
.cleanup(config_store, verbose, cache_root = nil) ⇒ Object
Remove old files so that the cache doesn’t grow too big. When the threshold MaxFilesInCache has been exceeded, the oldest 50% of all the files in the cache are removed. The reason for removing so much is that cleaning should be done relatively seldom, since there is a slight risk that some other RuboCop process was just about to read the file, when there’s parallel execution and the cache is shared.
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/rubocop/result_cache.rb', line 19 def self.cleanup(config_store, verbose, cache_root = nil) return if inhibit_cleanup # OPTIMIZE: For faster testing cache_root ||= cache_root(config_store) return unless File.exist?(cache_root) files, dirs = Find.find(cache_root).partition { |path| File.file?(path) } return unless requires_file_removal?(files.length, config_store) remove_oldest_files(files, dirs, cache_root, verbose) end |
Instance Method Details
#load ⇒ Object
93 94 95 |
# File 'lib/rubocop/result_cache.rb', line 93 def load @cached_data.from_json(IO.read(@path, encoding: Encoding::UTF_8)) end |
#save(offenses) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rubocop/result_cache.rb', line 97 def save(offenses) dir = File.dirname(@path) FileUtils.mkdir_p(dir) preliminary_path = "#{@path}_#{rand(1_000_000_000)}" # RuboCop must be in control of where its cached data is stored. A # symbolic link anywhere in the cache directory tree can be an # indication that a symlink attack is being waged. return if symlink_protection_triggered?(dir) File.open(preliminary_path, 'w', encoding: Encoding::UTF_8) do |f| f.write(@cached_data.to_json(offenses)) end # The preliminary path is used so that if there are multiple RuboCop # processes trying to save data for the same inspected file # simultaneously, the only problem we run in to is a competition who gets # to write to the final file. The contents are the same, so no corruption # of data should occur. FileUtils.mv(preliminary_path, @path) end |
#valid? ⇒ Boolean
89 90 91 |
# File 'lib/rubocop/result_cache.rb', line 89 def valid? File.exist?(@path) end |