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 auto_correct 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.
80 81 82 83 84 85 86 87 88 |
# File 'lib/rubocop/result_cache.rb', line 80 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.
158 159 160 |
# File 'lib/rubocop/result_cache.rb', line 158 def inhibit_cleanup @inhibit_cleanup end |
.source_checksum ⇒ Object
Returns the value of attribute source_checksum.
158 159 160 |
# File 'lib/rubocop/result_cache.rb', line 158 def source_checksum @source_checksum end |
Class Method Details
.allow_symlinks_in_cache_location?(config_store) ⇒ Boolean
76 77 78 |
# File 'lib/rubocop/result_cache.rb', line 76 def self.allow_symlinks_in_cache_location?(config_store) config_store.for('.').for_all_cops['AllowSymlinksInCacheRootDirectory'] end |
.cache_root(config_store) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/rubocop/result_cache.rb', line 64 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 29 |
# 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
94 95 96 |
# File 'lib/rubocop/result_cache.rb', line 94 def load @cached_data.from_json(IO.read(@path, encoding: Encoding::UTF_8)) end |
#save(offenses) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/rubocop/result_cache.rb', line 98 def save(offenses) dir = File.dirname(@path) begin FileUtils.mkdir_p(dir) rescue Errno::EACCES => e warn "Couldn't create cache directory. Continuing without cache."\ "\n #{e.}" return end 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
90 91 92 |
# File 'lib/rubocop/result_cache.rb', line 90 def valid? File.exist?(@path) end |