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 =
[:color, :format, :formatters, :out, :debug, :fail_level, :cache, :fail_fast, :stdin].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.
78 79 80 81 82 83 84 85 86 |
# File 'lib/rubocop/result_cache.rb', line 78 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.
143 144 145 |
# File 'lib/rubocop/result_cache.rb', line 143 def inhibit_cleanup @inhibit_cleanup end |
.source_checksum ⇒ Object
Returns the value of attribute source_checksum.
143 144 145 |
# File 'lib/rubocop/result_cache.rb', line 143 def source_checksum @source_checksum end |
Class Method Details
.allow_symlinks_in_cache_location?(config_store) ⇒ Boolean
74 75 76 |
# File 'lib/rubocop/result_cache.rb', line 74 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 |
# File 'lib/rubocop/result_cache.rb', line 64 def self.cache_root(config_store) root = config_store.for('.').for_all_cops['CacheRootDirectory'] if root == '/tmp' tmpdir = File.realpath(Dir.tmpdir) # Include user ID in the path to make sure the user has write access. root = File.join(tmpdir, Process.uid.to_s) 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.
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/rubocop/result_cache.rb', line 20 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
92 93 94 |
# File 'lib/rubocop/result_cache.rb', line 92 def load @cached_data.from_json(IO.read(@path, encoding: Encoding::UTF_8)) end |
#save(offenses) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rubocop/result_cache.rb', line 96 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
88 89 90 |
# File 'lib/rubocop/result_cache.rb', line 88 def valid? File.exist?(@path) end |