Class: TestIds::Git

Inherits:
Object
  • Object
show all
Includes:
Origen::Utility::InputCapture
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

Defined Under Namespace

Classes: Rollback

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Git

Returns a new instance of Git.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/test_ids/git.rb', line 73

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.



15
16
17
# File 'lib/test_ids/git.rb', line 15

def local
  @local
end

#repoObject (readonly)

Returns the value of attribute repo.



15
16
17
# File 'lib/test_ids/git.rb', line 15

def repo
  @repo
end

Class Method Details

.rollback(id) ⇒ Object



68
69
70
71
# File 'lib/test_ids/git.rb', line 68

def self.rollback(id)
  # Implemented as a class as a hack to get access to InputCapture
  Rollback.new(id)
end

Instance Method Details

#available_to_lock?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/test_ids/git.rb', line 147

def available_to_lock?
  result = false
  Origen.profile 'Checking for lock' do
    repo.fetch
    repo.reset_hard('origin/master')
    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



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

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

#get_lockObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/test_ids/git.rb', line 119

def get_lock
  return if @lock_open
  Origen.profile 'Obtaining test IDs lock' do
    until available_to_lock?
      puts
      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)"
      puts
      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



173
174
175
176
# File 'lib/test_ids/git.rb', line 173

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

#lock_expiresObject



165
166
167
# File 'lib/test_ids/git.rb', line 165

def lock_expires
  lock_content['expires']
end

#lock_minutes_remainingObject



161
162
163
# File 'lib/test_ids/git.rb', line 161

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

#lock_userObject



169
170
171
# File 'lib/test_ids/git.rb', line 169

def lock_user
  lock_content['user']
end

#minutes(number) ⇒ Object



178
179
180
# File 'lib/test_ids/git.rb', line 178

def minutes(number)
  number * 60
end

#publishObject



103
104
105
106
107
108
109
110
# File 'lib/test_ids/git.rb', line 103

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



139
140
141
142
143
144
145
# File 'lib/test_ids/git.rb', line 139

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



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

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