Class: Locallingo::StateStore
- Inherits:
-
Object
- Object
- Locallingo::StateStore
- Defined in:
- lib/locallingo/state_store.rb
Overview
Reads and writes the source-hash drift state under state_dir.
State is split into one JSON file per top-level namespace and locale
(accounts.de.json, ...) so diffs stay small and reviewable. Each entry
records the source hash a key was translated from, so a later source change
marks the translation outdated. Optionally a target_hash and manual flag
are tracked so hand-edited target values can be protected from overwrites.
Instance Attribute Summary collapse
-
#state_dir ⇒ Object
readonly
Returns the value of attribute state_dir.
Class Method Summary collapse
-
.hash(text) ⇒ Object
CRC32 hash — fast and compact (8 hex chars).
Instance Method Summary collapse
- #hash(text) ⇒ Object
-
#initialize(state_dir) ⇒ StateStore
constructor
A new instance of StateStore.
-
#load(locale) ⇒ Object
Load the combined state for a locale (merged across its namespace files).
-
#save(locale, locale_state) ⇒ Object
Save a locale's state, split back into per-namespace files.
Constructor Details
#initialize(state_dir) ⇒ StateStore
Returns a new instance of StateStore.
18 19 20 21 |
# File 'lib/locallingo/state_store.rb', line 18 def initialize(state_dir) @state_dir = state_dir FileUtils.mkdir_p(@state_dir) end |
Instance Attribute Details
#state_dir ⇒ Object (readonly)
Returns the value of attribute state_dir.
16 17 18 |
# File 'lib/locallingo/state_store.rb', line 16 def state_dir @state_dir end |
Class Method Details
.hash(text) ⇒ Object
CRC32 hash — fast and compact (8 hex chars).
24 25 26 |
# File 'lib/locallingo/state_store.rb', line 24 def self.hash(text) format("%08x", Zlib.crc32(text.to_s)) end |
Instance Method Details
#hash(text) ⇒ Object
28 |
# File 'lib/locallingo/state_store.rb', line 28 def hash(text) = self.class.hash(text) |
#load(locale) ⇒ Object
Load the combined state for a locale (merged across its namespace files).
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/locallingo/state_store.rb', line 31 def load(locale) combined = {} Dir.glob(File.join(state_dir, "*.#{locale}.json")).each do |file| combined.merge!(JSON.parse(File.read(file))) end combined rescue JSON::ParserError => e raise Error, "Corrupted state file: #{e.}\n" \ "This would cause state loss. Fix the JSON manually or restore from git." end |
#save(locale, locale_state) ⇒ Object
Save a locale's state, split back into per-namespace files. Files whose content is unchanged are left untouched so unrelated namespaces never churn in diffs. Namespace files that no longer have keys are removed.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/locallingo/state_store.rb', line 46 def save(locale, locale_state) by_namespace = locale_state.each_with_object({}) do |(key, value), groups| namespace = key.split(".").first (groups[namespace] ||= {})[key] = value end by_namespace.each do |namespace, keys| state_file = File.join(state_dir, "#{namespace}.#{locale}.json") content = JSON.pretty_generate(keys.sort.to_h) next if File.exist?(state_file) && File.read(state_file) == content File.write(state_file, content) end Dir.glob(File.join(state_dir, "*.#{locale}.json")).each do |file| namespace = File.basename(file).delete_suffix(".#{locale}.json") File.delete(file) unless by_namespace.key?(namespace) end end |