Class: Lumin::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/lumin/cache.rb

Constant Summary collapse

PathEntry =
CacheManifest::PathEntry
MANIFEST =
"manifest".freeze
LOCK_FILE =
"manifest.lock".freeze
MANIFEST_VERSION =
CacheManifest::VERSION
LEGACY_DIRECTORY_PATTERN =
/\A[0-9a-f]{2}\z/
MANIFEST_TEMPORARY_PATTERN =
/\A#{Regexp.escape(MANIFEST)}\.\d+\.tmp\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config:, registry: Registry, directory: self.class.default_directory) ⇒ Cache

Returns a new instance of Cache.



28
29
30
31
32
33
34
35
36
# File 'lib/lumin/cache.rb', line 28

def initialize(config:, registry: Registry, directory: self.class.default_directory)
  @config = config
  @registry = registry
  @directory = File.expand_path(directory)
  @environment_digest = build_environment_digest
  @manifest = nil
  @pending_paths = {}
  @pending_offenses = {}
end

Instance Attribute Details

#directoryObject (readonly)

Returns the value of attribute directory.



20
21
22
# File 'lib/lumin/cache.rb', line 20

def directory
  @directory
end

Class Method Details

.default_directoryObject



22
23
24
25
26
# File 'lib/lumin/cache.rb', line 22

def self.default_directory
  base = ENV["XDG_CACHE_HOME"]
  base = File.join(Dir.home, ".cache") if base.nil? || base.empty?
  File.join(base, "lumin")
end

Instance Method Details

#clearObject



80
81
82
83
84
85
86
87
88
89
# File 'lib/lumin/cache.rb', line 80

def clear
  with_lock do
    FileUtils.rm_f(manifest_path)
    remove_legacy_entries
    @manifest = CacheManifest.empty
    @pending_paths.clear
    @pending_offenses.clear
  end
  true
end

#fetch(path, source = nil) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/lumin/cache.rb', line 38

def fetch(path, source = nil)
  expanded_path = File.expand_path(path)
  entry = @pending_paths.fetch(expanded_path) { manifest.paths[expanded_path] }
  if valid_entry?(entry, path)
    cached = cached_offenses(entry.key)
    return rebase(cached, path) if cached
  end
  return unless source

  cached = cached_offenses(key(source))
  rebase(cached, path) if cached
end

#flushObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/lumin/cache.rb', line 65

def flush
  return false if @pending_paths.empty?

  with_lock do
    merged = merge_pending(CacheManifest.load(manifest_path))
    compacted = compact(merged)
    atomic_write(manifest_path) { |file| file.write(CacheManifest.serialize(compacted)) }
    remove_legacy_entries
    @manifest = compacted
    @pending_paths.clear
    @pending_offenses.clear
  end
  true
end

#key(source) ⇒ Object



91
92
93
# File 'lib/lumin/cache.rb', line 91

def key(source)
  key_for_digest(Digest::SHA256.hexdigest(source))
end

#put(path:, offenses:, source: nil, content_digest: nil, fingerprint: nil) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/lumin/cache.rb', line 51

def put(path:, offenses:, source: nil, content_digest: nil, fingerprint: nil)
  current_fingerprint = SourceSnapshot.fingerprint(path)
  return false if fingerprint && fingerprint != current_fingerprint

  cache_key = key_for_digest(content_digest || digest_source(source))
  @pending_offenses[cache_key] = offenses
  @pending_paths[File.expand_path(path)] = PathEntry.new(
    fingerprint: current_fingerprint,
    environment_digest: @environment_digest,
    key: cache_key
  )
  offenses
end