Class: Canopus::Git::State

Inherits:
Object
  • Object
show all
Defined in:
lib/canopus/git/state.rb

Defined Under Namespace

Classes: Snapshot

Constant Summary collapse

CACHE_LIMIT =
20

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repository) ⇒ State

Returns a new instance of State.



13
14
15
16
17
# File 'lib/canopus/git/state.rb', line 13

def initialize(repository)
  @repository = repository
  @repository_lock = Mutex.new
  @diff_cache = {}
end

Instance Attribute Details

#snapshot ⇒ Object (readonly)

Returns the value of attribute snapshot.



11
12
13
# File 'lib/canopus/git/state.rb', line 11

def snapshot
  @snapshot
end

Instance Method Details

#cached_diff(key) ⇒ Object



50
# File 'lib/canopus/git/state.rb', line 50

def cached_diff(key) = @diff_cache[key]

#capture ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/canopus/git/state.rb', line 19

def capture
  synchronize do |repository|
    3.times do
      before = repository_identity
      entries = repository.status.to_h do |entry|
        [entry.path.dup.freeze, entry.code.dup.freeze]
      end.freeze
      after = repository_identity
      return Snapshot.new(*after, entries) if before == after
    end
    raise Thuban::RefLockError, "Git HEAD or index changed while reading status"
  end
end

#identity ⇒ Object



33
34
35
36
37
# File 'lib/canopus/git/state.rb', line 33

def identity
  synchronize do |repository|
    [freeze_string(repository.head), freeze_string(repository.branch), index_stamp(repository)].freeze
  end
end

#install(snapshot) ⇒ Object

Raises:

  • (ArgumentError)


39
40
41
42
43
# File 'lib/canopus/git/state.rb', line 39

def install(snapshot)
  raise ArgumentError, "invalid Git snapshot" unless snapshot.is_a?(Snapshot)

  @snapshot = snapshot
end

#invalidate ⇒ Object



45
46
47
48
# File 'lib/canopus/git/state.rb', line 45

def invalidate
  @snapshot = nil
  @diff_cache.clear
end

#store_diff(key, diff) ⇒ Object



52
53
54
55
# File 'lib/canopus/git/state.rb', line 52

def store_diff(key, diff)
  @diff_cache.clear if @diff_cache.length >= CACHE_LIMIT && !@diff_cache.key?(key)
  @diff_cache[key] = diff
end

#synchronize(snapshot: nil, index_lock: false, &block) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/canopus/git/state.rb', line 57

def synchronize(snapshot: nil, index_lock: false, &block)
  @repository_lock.synchronize do
    operation = lambda do
      if snapshot && snapshot.identity != repository_identity
        raise Thuban::RefLockError, "Git HEAD or index changed since it was displayed"
      end

      block.call(@repository)
    end
    index_lock ? with_index_lock(&operation) : operation.call
  end
end