Class: GitBinaryCache::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/git_binary_cache/manager.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Manager


Raises:

  • (ArgumentError)


8
9
10
11
12
13
14
15
# File 'lib/git_binary_cache/manager.rb', line 8

def initialize(config)
  raise ArgumentError, "Need a hash!" unless config.kind_of?(Hash)

  @name = config[:name] or raise ArgumentError, "Need a :name for the cache"
  @git_url = config[:git_url] or raise ArgumentError, "Need a :name for the cache"

  @logger = config[:logger]
end

Instance Attribute Details

#git_urlObject (readonly)

Returns the value of attribute git_url.



5
6
7
# File 'lib/git_binary_cache/manager.rb', line 5

def git_url
  @git_url
end

#loggerObject (readonly)

Returns the value of attribute logger.



5
6
7
# File 'lib/git_binary_cache/manager.rb', line 5

def logger
  @logger
end

#nameObject (readonly)

Returns the value of attribute name.



5
6
7
# File 'lib/git_binary_cache/manager.rb', line 5

def name
  @name
end

Instance Method Details

#cache_base_dirObject




23
24
25
# File 'lib/git_binary_cache/manager.rb', line 23

def cache_base_dir
  ENV['GIT_BINARY_CACHE'] || "/usr/local/var/git-binary-cache"
end

#cache_dirObject



27
28
29
# File 'lib/git_binary_cache/manager.rb', line 27

def cache_dir
  File.join(cache_base_dir, name)
end

#cache_exists?Boolean


Returns:

  • (Boolean)


172
173
174
175
176
177
# File 'lib/git_binary_cache/manager.rb', line 172

def cache_exists?
  open_cache!
  return true
rescue GitBinaryCache::Error
  return false
end

#clone_cache_from_upstream!Object




136
137
138
139
140
141
142
143
144
145
146
# File 'lib/git_binary_cache/manager.rb', line 136

def clone_cache_from_upstream!
  # Create base directory
  FileUtils.mkdir_p(cache_base_dir)

  # Nuke any remaining files in the cache directory
  FileUtils.rm_rf(cache_dir)

  # Clone the repo
  log("Cloning git repo #{git_url} to #{cache_dir}")
  Git.clone(git_url, cache_dir)
end

#get_repo_remote_urlObject




98
99
100
101
102
103
104
# File 'lib/git_binary_cache/manager.rb', line 98

def get_repo_remote_url
  # Open the cache with git
  git = open_cache!

  # Get origin remote url
  git.remote('origin').url
end

#get_revision_info(revision) ⇒ Object




107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/git_binary_cache/manager.rb', line 107

def get_revision_info(revision)
  # Open the cache with git
  git = open_cache!

  # Check the revision
  begin
    git.object(revision)
  rescue Git::GitExecuteError => e
    # Return nil if revision does not exist
    return false if e.message =~ /Not a valid object name/

    # Re-raise unexpected error
    raise
  end
end

#log(message) ⇒ Object



17
18
19
20
# File 'lib/git_binary_cache/manager.rb', line 17

def log(message)
  return unless logger
  logger.info("cache[#{name}]: #{message}")
end

#need_cache!Object




72
73
74
# File 'lib/git_binary_cache/manager.rb', line 72

def need_cache!
  get_revision_info('HEAD')
end

#need_revision!(revision) ⇒ Object




77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/git_binary_cache/manager.rb', line 77

def need_revision!(revision)
  # Check if we have the revision
  revision_info = get_revision_info(revision)
  unless revision_info
    error = "Could not find revision '#{revision}' for cache #{name}. Try to update the cache!"
    raise GitBinaryCache::UnknownRevisionError, error
  end
  log("Revision #{revision} exists in cache repository...")

  # Then check if we have the revision applied already
  unless revision_applied?(revision)
    error = "Revision '#{revision}' is available, but the cache #{name} is outdated. Try to update the cache!"
    raise GitBinaryCache::OutdatedCacheError, error
  end
  log("Revision #{revision} has been applied!")

  # We're good
  return true
end

#open_cache!Object




180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/git_binary_cache/manager.rb', line 180

def open_cache!
  # Check if cache directory exists
  unless Dir.exists?(cache_dir)
    error = "Cache directory is missing for cache '#{name}'. Try to update the cache!"
    raise GitBinaryCache::CacheMissingError, error
  end

  # Open the cache
  git = Git.open(cache_dir)

  # Check if cache directory is a valid git clone
  unless Dir.exists?(File.join(cache_dir, '.git')) && git.index.readable?
    error = "Cache directory is invalid for cache '#{name}'. Try to update the cache!"
    raise GitBinaryCache::CacheCorruptedError, error
  end

  # Return our git repo information
  return git
end

#revision_applied?(revision) ⇒ Boolean


Returns:

  • (Boolean)


124
125
126
127
128
129
130
131
132
133
# File 'lib/git_binary_cache/manager.rb', line 124

def revision_applied?(revision)
  # Open the cache with git
  git = open_cache!

  # Get log between two revisions
  log = git.log(100).between('HEAD', revision)

  # If revision has already been applied, there will be nothing in the log
  return log.count == 0
end

#switch_to_revision!(revision) ⇒ Object



161
162
163
164
165
166
167
168
169
# File 'lib/git_binary_cache/manager.rb', line 161

def switch_to_revision!(revision)
  # Open the cache
  git = Git.open(cache_dir)

  # Switch to specified revision
  log("Switching cache #{name} to revision #{revision}...")
  git.checkout(revision)
  log("Done!")
end

#update_cache!(revision = nil) ⇒ Object




32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/git_binary_cache/manager.rb', line 32

def update_cache!(revision = nil)
  # Make sure cache exists and its remote url is correct
  if cache_exists?
    log("Cache repository exists for #{name}, checking remote URL...")
    remote_url = get_repo_remote_url

    if remote_url != git_url
      log("Remote URL for existing cache repository is invalid: #{remote_url} != #{git_url}, resetting the cache!")
      clone_cache_from_upstream!
    else
      log("Git remote is correct!")
    end
  else
    clone_cache_from_upstream!
  end

  # Update the cache
  update_cache_from_upstream!

  # If a revision give, switch to it
  if revision
    log("Revision provided, checking if it exists in the cache repository...")
    revision_info = get_revision_info(revision)
    unless revision_info
      error = "Could not find revision '#{revision}' for cache #{name}. Check revision value!"
      raise GitBinaryCache::UnknownRevisionError, error
    end

    if revision_applied?(revision)
      log("Revision #{revision} has alrealy been applied!")
    else
      switch_to_revision!(revision)
    end
  else
    log("No revision provided, switching to the most recent one...")
    switch_to_revision!('master')
  end
end

#update_cache_from_upstream!Object




149
150
151
152
153
154
155
156
157
158
159
# File 'lib/git_binary_cache/manager.rb', line 149

def update_cache_from_upstream!
  # Open the cache
  git = Git.open(cache_dir)

  # Reset the repo
  git.reset_hard('HEAD')

  # Fetch updates
  log("Fetching origin updates for cache directory #{cache_dir}")
  git.fetch('origin')
end