Module: AsciidoctorExtensions::KrokiCache
- Defined in:
- lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb
Overview
Persistent, content-addressed cache for fetched diagrams, independent of the output directory. Ports src/cache.js so both language bindings behave the same way: the cache key is derived from the diagram request itself (server URL, type, format, encoded source, options), not from the output file name, so it also survives builds that wipe the output directory between runs (e.g. Antora) and correctly detects unchanged content for diagrams with a stable, user-defined name (see #90, #113).
Constant Summary collapse
- VALID_CACHE_MODES =
['', 'true', 'false', 'refresh'].freeze
Class Method Summary collapse
-
.content_key(kroki_diagram, server_url) ⇒ Object
Computes the content-addressed cache key for a diagram.
-
.exists_in_cache?(cache_dir, key, format) ⇒ Boolean
Whether a diagram is already present in the cache.
-
.read_from_cache(cache_dir, key, format) ⇒ Object
Reads a cached diagram.
-
.resolve_cache_dir(doc) ⇒ Object
Resolves the persistent cache directory.
-
.resolve_cache_mode(doc, logger) ⇒ Hash{Symbol => Boolean}
Resolves the
kroki-cacheattribute into a cache mode. -
.write_to_cache(cache_dir, key, format, contents) ⇒ Object
Writes a diagram to the cache, creating the cache directory if needed.
Class Method Details
.content_key(kroki_diagram, server_url) ⇒ Object
Computes the content-addressed cache key for a diagram.
Deliberately host-dependent: the server URL is part of the key because two Kroki servers are not guaranteed to render the same source identically (they may run different versions of the underlying diagram libraries). Options are sorted so the key does not depend on their insertion order.
56 57 58 59 60 |
# File 'lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb', line 56 def content_key(kroki_diagram, server_url) sorted_opts = kroki_diagram.opts.sort_by { |k, _| k.to_s } material = [server_url, kroki_diagram.type, kroki_diagram.format, kroki_diagram.encode, sorted_opts.to_json].join('/') Digest::SHA256.hexdigest(material) end |
.exists_in_cache?(cache_dir, key, format) ⇒ Boolean
Whether a diagram is already present in the cache.
63 64 65 |
# File 'lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb', line 63 def exists_in_cache?(cache_dir, key, format) File.exist?(cache_file_path(cache_dir, key, format)) end |
.read_from_cache(cache_dir, key, format) ⇒ Object
Reads a cached diagram.
68 69 70 |
# File 'lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb', line 68 def read_from_cache(cache_dir, key, format) File.read(cache_file_path(cache_dir, key, format), mode: 'rb') end |
.resolve_cache_dir(doc) ⇒ Object
Resolves the persistent cache directory.
Uses the kroki-cache-dir attribute when set; otherwise defaults to the XDG cache
directory ($XDG_CACHE_HOME/kroki or ~/.cache/kroki).
21 22 23 24 25 26 27 |
# File 'lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb', line 21 def resolve_cache_dir(doc) configured = doc.attr('kroki-cache-dir') return configured if configured && !configured.empty? xdg_cache_home = ENV['XDG_CACHE_HOME'] || File.join(Dir.home, '.cache') File.join(xdg_cache_home, 'kroki') end |
.resolve_cache_mode(doc, logger) ⇒ Hash{Symbol => Boolean}
Resolves the kroki-cache attribute into a cache mode.
Recognised values are: unset (defaults to enabled), `` (set with no value, e.g.
:kroki-cache:) and true (both enabled), false (disabled), and refresh (enabled,
but bypasses cached reads and re-fetches + updates the cache). Any other value is
invalid: it is logged and treated as if unset.
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb', line 37 def resolve_cache_mode(doc, logger) raw = doc.attr('kroki-cache') return { enabled: true, refresh: false } if raw.nil? value = raw.to_s.strip.downcase unless VALID_CACHE_MODES.include?(value) logger.warn "Invalid value '#{raw}' for kroki-cache attribute. The value must be either: " \ "'true', 'false' or 'refresh'. Proceeding using: 'true'." return { enabled: true, refresh: false } end { enabled: value != 'false', refresh: value == 'refresh' } end |
.write_to_cache(cache_dir, key, format, contents) ⇒ Object
Writes a diagram to the cache, creating the cache directory if needed.
73 74 75 76 |
# File 'lib/asciidoctor/extensions/asciidoctor_kroki/cache.rb', line 73 def write_to_cache(cache_dir, key, format, contents) FileUtils.mkdir_p(cache_dir) File.write(cache_file_path(cache_dir, key, format), contents, mode: 'wb') end |