class GitDis
Attributes
dry_run[RW]
redis[RW]
repo_dir[RW]
Public Class Methods
concatenate(filenames)
click to toggle source
concatenate file contents into a single string separate by newlines, including CRs if any CRs are detected anywhere include a filetype-specific separator if recognized filenames is an array, and all lengths 0-N are handled
# File lib/gitdis.rb, line 55 def self.concatenate(filenames) filetypes = filenames.map { |fname| File.extname(fname) }.uniq case filetypes.length when 0 return "" if filenames.length == 0 raise "filetype detection failure: #{filenames}" when 1 sep = self.separator(filetypes.first) else raise "refusing to concatenate disparate filetypes: #{filetypes}" end newline = "\n" payload = filenames.map { |fname| contents = File.read(fname) || raise("could not read #{fname}") newline = "\r\n" if !newline.include?("\r") and contents.include?("\r") contents if !contents.empty? }.compact sep = sep.empty? ? newline : "#{newline}#{sep}#{newline}" payload.join(sep) end
dump(keys, redis_options)
click to toggle source
# File lib/gitdis.rb, line 38 def self.dump(keys, redis_options) redis = Redis.new(redis_options) keys.each { |base_key| self.keyset(base_key).each { |rkey| val = redis.get(rkey) if val and val.include?("\n") val = "\n" << val.split("\n").map { |line| "\t#{line}" }.join("\n") puts ["[#{rkey}]", val].join(' ') end } } end
exec(cmd, bytes=1024)
click to toggle source
return Process::Status, stream through STDOUT and STDERR
# File lib/gitdis.rb, line 7 def self.exec(cmd, bytes=1024) Open3.popen3(cmd) { |sin, sout, serr, thr| sin.close_write while !sout.eof or !serr.eof ready = IO.select [sout, serr] if ready ready[0].each { |f| # ready for reading begin (f == sout ? $stdout : $stderr).print f.read_nonblock(bytes) rescue EOFError => e # ok end } end end thr.value # Process::Status } end
exec!(cmd)
click to toggle source
raise on nonzero exit code
# File lib/gitdis.rb, line 27 def self.exec!(cmd) status = self.exec(cmd) raise "`#{cmd}` #{status}" unless status.exitstatus == 0 0 end
keyset(base_key)
click to toggle source
file contents, version, md5
# File lib/gitdis.rb, line 34 def self.keyset(base_key) [base_key, [base_key, 'version'].join(':'), [base_key, 'md5'].join(':')] end
new(repo_dir, redis_options = {})
click to toggle source
# File lib/gitdis.rb, line 92 def initialize(repo_dir, redis_options = {}) @dry_run = false @repo_dir = File.expand_path(repo_dir) raise "#{@repo_dir} does not exist!" unless Dir.exist? @repo_dir @redis = Redis.new(redis_options) end
separator(filetype)
click to toggle source
return a specific separator for known filetypes e.g. yaml document separator: —
# File lib/gitdis.rb, line 80 def self.separator(filetype) filetype = filetype[1..-1] if filetype[0] == '.' case filetype.downcase when 'yaml', 'yml' '---' else '' end end
Public Instance Methods
git_pull(git_branch)
click to toggle source
# File lib/gitdis.rb, line 99 def git_pull(git_branch) Dir.chdir @repo_dir do if self.class.exec("git diff --quiet HEAD").exitstatus != 0 raise "please stash your local changes" end self.class.exec! "git checkout #{git_branch}" self.class.exec! "git pull" end self end
update(base_key, relpath)
click to toggle source
e.g. update(‘foo:bar:baz’, ‘foo/bar/*.baz’) return nil # path does not exist
false # no update needed true # update was needed, but just a dry run [ver, md5] # updated
# File lib/gitdis.rb, line 133 def update(base_key, relpath) # handle e.g. "foo/bar/*.yaml" files = Dir.glob(File.join(@repo_dir, relpath)) case files.length when 0 then nil when 1 then self.update_redis(base_key, File.read(files.first)) else self.update_redis(base_key, self.class.concatenate(files)) end end
update_redis(base_key, file_contents)
click to toggle source
quick false if calculated md5 == redis md5 return true if dry run and update needed otherwise update contents and md5; increment version
# File lib/gitdis.rb, line 113 def update_redis(base_key, file_contents) md5 = Digest::MD5.hexdigest(file_contents) fkey, vkey, mkey = self.class.keyset(base_key) return false if @redis.get(mkey) == md5 if @dry_run true else @redis.set(fkey, file_contents) @redis.set(mkey, md5) ver = @redis.incr(vkey) [ver, md5] end end