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

#local ⇒ Object (readonly)

Returns the value of attribute local.



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

def local
  @local
end

#repo ⇒ Object (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
# File 'lib/test_ids/git.rb', line 87

def available_to_lock?
  result = false
  Origen.profile 'Checking for lock' do
    repo.pull
    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_lock ⇒ Object



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_content ⇒ Object



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

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

#lock_expires ⇒ Object



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

def lock_expires
  lock_content['expires']
end

#lock_minutes_remaining ⇒ Object



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

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

#lock_user ⇒ Object



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

def lock_user
  lock_content['user']
end

#minutes(number) ⇒ Object



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

def minutes(number)
  number * 60
end

#publish ⇒ Object



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')
  end
end

#release_lock ⇒ Object



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