Class: Nandi::Lockfile
- Inherits:
-
Object
- Object
- Nandi::Lockfile
- Defined in:
- lib/nandi/lockfile.rb
Instance Attribute Summary collapse
-
#db_name ⇒ Object
readonly
Returns the value of attribute db_name.
Class Method Summary collapse
- .clear_instances! ⇒ Object
-
.for(db_name) ⇒ Object
Registry pattern using class variables to maintain singleton instances per database.
Instance Method Summary collapse
- #add(file_name:, source_digest:, compiled_digest:) ⇒ Object
- #create! ⇒ Object
- #file_present? ⇒ Boolean
- #get(file_name) ⇒ Object
-
#initialize(db_name = nil) ⇒ Lockfile
constructor
A new instance of Lockfile.
- #load! ⇒ Object
- #persist! ⇒ Object
Constructor Details
Instance Attribute Details
#db_name ⇒ Object (readonly)
Returns the value of attribute db_name.
8 9 10 |
# File 'lib/nandi/lockfile.rb', line 8 def db_name @db_name end |
Class Method Details
.clear_instances! ⇒ Object
21 22 23 |
# File 'lib/nandi/lockfile.rb', line 21 def clear_instances! @instances = {} end |
.for(db_name) ⇒ Object
Registry pattern using class variables to maintain singleton instances per database. This ensures that lockfile operations for the same database always work with the same instance, maintaining consistency.
14 15 16 17 18 19 |
# File 'lib/nandi/lockfile.rb', line 14 def for(db_name) @instances ||= {} # Handle nil by using :primary as default key = db_name.nil? ? :primary : db_name.to_sym @instances[key] ||= new(key) end |
Instance Method Details
#add(file_name:, source_digest:, compiled_digest:) ⇒ Object
42 43 44 45 46 47 48 49 |
# File 'lib/nandi/lockfile.rb', line 42 def add(file_name:, source_digest:, compiled_digest:) load! @lockfile[file_name] = { source_digest: source_digest, compiled_digest: compiled_digest, } end |
#create! ⇒ Object
36 37 38 39 40 |
# File 'lib/nandi/lockfile.rb', line 36 def create! return if file_present? File.write(path, {}.to_yaml) end |
#file_present? ⇒ Boolean
32 33 34 |
# File 'lib/nandi/lockfile.rb', line 32 def file_present? File.exist?(path) end |
#get(file_name) ⇒ Object
51 52 53 54 55 56 57 58 |
# File 'lib/nandi/lockfile.rb', line 51 def get(file_name) load! { source_digest: @lockfile.dig(file_name, :source_digest), compiled_digest: @lockfile.dig(file_name, :compiled_digest), } end |
#load! ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/nandi/lockfile.rb', line 60 def load! return @lockfile if @lockfile create! unless file_present? @lockfile = YAML.safe_load_file(path).with_indifferent_access end |
#persist! ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/nandi/lockfile.rb', line 68 def persist! load! # This is a somewhat ridiculous trick to avoid merge conflicts in git. # # Normally, new migrations are added to the bottom of the Nandi lockfile. # This is relatively unfriendly to git's merge algorithm, and means that # if someone merges a pull request with a completely unrelated migration, # you'll have to rebase to get yours merged as the last line of the file # will be seen as a conflict (both branches added content there). # # This is in contrast to something like Gemfile.lock, where changes tend # to be distributed throughout the file. The idea behind sorting by # SHA-256 hash is to distribute new Nandi lockfile entries evenly, but # also stably through the file. It needs to be stable or we'd have even # worse merge conflict problems (e.g. if we randomised the order on # writing the file, the whole thing would conflict pretty much every time # it was regenerated). content = @lockfile.to_h.deep_stringify_keys.sort_by do |k, _| Digest::SHA256.hexdigest(k) end.to_h.to_yaml File.write(path, content) end |