Class: TestIds::Git

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

Overview

The Git driver is responsible for committing and fetching the store from the central Git repository.

All operations are automatically pushed immediately to the central repository and a lock will be taken out whenever a program generation operation is done in production mode to prevent the need to merge with other users.

An instance of this class is instantiated as TestIds.git

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Git

Returns a new instance of Git.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/test_ids/git.rb', line 15

def initialize(options)
  unless File.exist?("#{options[:local]}/.git")
    FileUtils.rm_rf(options[:local]) if File.exist?(options[:local])
    FileUtils.mkdir_p(options[:local])
    Dir.chdir options[:local] do
      `git clone #{options[:remote]} .`
      if !File.exist?('store.json') || !File.exist?('lock.json')
        # Should really try to use the Git driver for this
        exec 'touch store.json lock.json'
        exec 'git add store.json lock.json'
        exec 'git commit -m "Initial commit"'
        exec 'git push'
      end
    end
  end
  @local = options[:local]
  @repo = ::Git.open(options[:local])
  @repo.reset_hard
  @repo.pull unless options[:no_pull]
end

Instance Attribute Details

#localObject (readonly)

Returns the value of attribute local.



13
14
15
# File 'lib/test_ids/git.rb', line 13

def local
  @local
end

#repoObject (readonly)

Returns the value of attribute repo.



13
14
15
# File 'lib/test_ids/git.rb', line 13

def repo
  @repo
end

Instance Method Details

#available_to_lock?Boolean

Returns:

  • (Boolean)


86
87
88
89
90
91
92
93
# File 'lib/test_ids/git.rb', line 86

def available_to_lock?
  repo.pull
  if lock_content && lock_user && lock_user != User.current.name
    Time.now.to_f > lock_expires
  else
    true
  end
end

#exec(cmd) ⇒ Object



36
37
38
39
40
41
# File 'lib/test_ids/git.rb', line 36

def exec(cmd)
  r = system(cmd)
  unless r
    fail "Something went wrong running command: #{cmd}"
  end
end

#get_lockObject



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

def get_lock
  until available_to_lock?
    puts "Waiting for lock, currently locked by #{lock_user} (the lock will expire in less than #{lock_minutes_remaining} #{'minute'.pluralize(lock_minutes_remaining)} if not released before that)"
    sleep 5
  end
  data = {
    'user'    => User.current.name,
    'expires' => (Time.now + minutes(5)).to_f
  }
  write('lock.json', JSON.pretty_generate(data))
  repo.commit('Obtaining lock')
  repo.push('origin')
end

#lock_contentObject



107
108
109
110
# File 'lib/test_ids/git.rb', line 107

def lock_content
  f = File.join(local, 'lock.json')
  JSON.load(File.read(f)) if File.exist?(f)
end

#lock_expiresObject



99
100
101
# File 'lib/test_ids/git.rb', line 99

def lock_expires
  lock_content['expires']
end

#lock_minutes_remainingObject



95
96
97
# File 'lib/test_ids/git.rb', line 95

def lock_minutes_remaining
  ((lock_expires - Time.now.to_f) / 60).ceil
end

#lock_userObject



103
104
105
# File 'lib/test_ids/git.rb', line 103

def lock_user
  lock_content['user']
end

#minutes(number) ⇒ Object



112
113
114
# File 'lib/test_ids/git.rb', line 112

def minutes(number)
  number * 60
end

#publishObject



43
44
45
46
47
48
# File 'lib/test_ids/git.rb', line 43

def publish
  write('store.json')
  release_lock
  repo.commit('Publishing latest store')
  repo.push('origin')
end

#release_lockObject



71
72
73
74
75
76
77
# File 'lib/test_ids/git.rb', line 71

def release_lock
  data = {
    'user'    => nil,
    'expires' => nil
  }
  write('lock.json', JSON.pretty_generate(data))
end

#with_lockObject



79
80
81
82
83
84
# File 'lib/test_ids/git.rb', line 79

def with_lock
  get_lock
  yield
ensure
  release_lock
end

#write(path, data = nil) ⇒ Object

Writes the data to the given file and pushes to the remote repo



51
52
53
54
55
# File 'lib/test_ids/git.rb', line 51

def write(path, data = nil)
  f = File.join(local, path)
  File.write(f, data) if data
  repo.add(f)
end