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
35
36
# 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]} .`
      unless File.exist?('lock.json')
        # Should really try to use the Git driver for this
        exec 'touch lock.json'
        exec 'git add lock.json'
        exec 'git commit -m "Initial commit"'
        exec 'git push'
      end
    end
  end
  @local = options[:local]
  @repo = ::Git.open(options[:local])
  # Get rid of any local edits coming in here, this is only called once at the start
  # of the program generation run.
  # No need to pull latest as that will be done when we obtain a lock.
  @repo.reset_hard
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)


87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/test_ids/git.rb', line 87

def available_to_lock?
  result = false
  Origen.profile 'Checking for lock' do
    repo.fetch
    repo.reset_hard
    if lock_content && lock_user && lock_user != User.current.name
      result = Time.now.to_f > lock_expires
    else
      result = true
    end
  end
  result
end

#exec(cmd) ⇒ Object



38
39
40
41
42
43
# File 'lib/test_ids/git.rb', line 38

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

#get_lockObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/test_ids/git.rb', line 61

def get_lock
  return if @lock_open
  Origen.profile 'Obtaining test IDs lock' do
    until available_to_lock?
      Origen.log "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_open = true
end

#lock_contentObject



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

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

#lock_expiresObject



105
106
107
# File 'lib/test_ids/git.rb', line 105

def lock_expires
  lock_content['expires']
end

#lock_minutes_remainingObject



101
102
103
# File 'lib/test_ids/git.rb', line 101

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

#lock_userObject



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

def lock_user
  lock_content['user']
end

#minutes(number) ⇒ Object



118
119
120
# File 'lib/test_ids/git.rb', line 118

def minutes(number)
  number * 60
end

#publishObject



45
46
47
48
49
50
51
52
# File 'lib/test_ids/git.rb', line 45

def publish
  Origen.profile 'Publishing the test IDs store' do
    release_lock
    repo.add  # Checkin everything
    repo.commit('Publishing latest store')
    repo.push('origin', 'master', force: true)
  end
end

#release_lockObject



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

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

#write(path, data = nil) ⇒ Object

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



55
56
57
58
59
# File 'lib/test_ids/git.rb', line 55

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