Skip to content

Commit

Permalink
Implement file cache
Browse files Browse the repository at this point in the history
First approach to implement a file cache.

#158

Co-authored-by: Mike Dalessio <[email protected]>
  • Loading branch information
ChrisBr and flavorjones committed Nov 4, 2020
1 parent 10eddda commit 5db0880
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/erb_lint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'rubocop'

require 'erb_lint/corrector'
require 'erb_lint/cache'
require 'erb_lint/file_loader'
require 'erb_lint/linter_config'
require 'erb_lint/linter_registry'
Expand Down
47 changes: 47 additions & 0 deletions lib/erb_lint/cache.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module ERBLint
class Cache
CACHE_DIRECTORY = '.erb-lint-cache'
private_constant :CACHE_DIRECTORY

def initialize(config)
@config = config.to_hash
end

def [](filename)
JSON.parse(File.read(File.join(CACHE_DIRECTORY, checksum(filename))))
end

def include?(filename)
File.exist?(File.join(CACHE_DIRECTORY, checksum(filename)))
end

def []=(filename, messages)
FileUtils.mkdir_p(CACHE_DIRECTORY)

File.open(File.join(CACHE_DIRECTORY, checksum(filename)), 'wb') do |f|
f.write messages.to_json
end
end

private

attr_reader :config

def checksum(file)
digester = Digest::SHA1.new
mode = File.stat(file).mode

digester.update(
"#{file}#{mode}#{config.to_s}"
)
digester.file(file)
digester.hexdigest
rescue Errno::ENOENT
# Spurious files that come and go should not cause a crash, at least not
# here.
'_'
end
end
end
37 changes: 34 additions & 3 deletions lib/erb_lint/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def run(args = ARGV)
@files = dupped_args

load_config
@cache = Cache.new(config)

if !@files.empty? && lint_files.empty?
failure!("no files found...\n")
Expand All @@ -60,7 +61,7 @@ def run(args = ARGV)
lint_files.each do |filename|
runner.clear_offenses
begin
run_with_corrections(runner, filename)
puts run_on_file(runner, filename)
rescue => e
@stats.exceptions += 1
puts "Exception occured when processing: #{relative_filename(filename)}"
Expand Down Expand Up @@ -101,10 +102,36 @@ def run(args = ARGV)

private

attr_reader :cache, :config

def run_on_file(runner, filename)
if with_cache? && !autocorrect?
run_using_cache(runner, filename)
else
run_with_corrections(runner, filename)
end
end

def run_using_cache(runner, filename)
puts cache.include?(filename)
if cache.include?(filename) && !autocorrect?
result = cache[filename]
@stats.found += result.size
result
else
result = run_with_corrections(runner, filename)
cache[filename] = result
end
end

def autocorrect?
@options[:autocorrect]
end

def with_cache?
@options[:with_cache]
end

def run_with_corrections(runner, filename)
file_content = File.read(filename, encoding: Encoding::UTF_8)

Expand All @@ -128,8 +155,8 @@ def run_with_corrections(runner, filename)
end

@stats.found += runner.offenses.size
runner.offenses.each do |offense|
puts <<~EOF
runner.offenses.map do |offense|
<<~EOF
#{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect?}
In file: #{relative_filename(filename)}:#{offense.line_range.begin}
Expand Down Expand Up @@ -266,6 +293,10 @@ def option_parser
@options[:enabled_linters] = known_linter_names
end

opts.on("--with_cache", "Enable caching") do |config|
@options[:with_cache] = config
end

opts.on("--enable-linters LINTER[,LINTER,...]", Array,
"Only use specified linter", "Known linters are: #{known_linter_names.join(', ')}") do |linters|
linters.each do |linter|
Expand Down

0 comments on commit 5db0880

Please sign in to comment.