Class: TestIds::Git
- Inherits:
-
Object
- Object
- TestIds::Git
- 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: PathToLocal
Instance Attribute Summary collapse
-
#local ⇒ Object
readonly
Returns the value of attribute local.
-
#repo ⇒ Object
readonly
Returns the value of attribute repo.
Class Method Summary collapse
-
.path_to_local ⇒ Object
Returns a path to the local test IDs repo, if multiple are found the user will be prompted to choose one.
Instance Method Summary collapse
- #available_to_lock? ⇒ Boolean
- #exec(cmd) ⇒ Object
- #get_lock ⇒ Object
-
#initialize(options) ⇒ Git
constructor
A new instance of Git.
- #lock_content ⇒ Object
- #lock_expires ⇒ Object
- #lock_minutes_remaining ⇒ Object
- #lock_user ⇒ Object
- #minutes(number) ⇒ Object
- #publish ⇒ Object
- #release_lock ⇒ Object
-
#rollback(id) ⇒ Object
Roll the repo back to the given commit ID.
-
#write(path, data = nil) ⇒ Object
Writes the data to the given file and pushes to the remote repo.
Constructor Details
#initialize(options) ⇒ Git
Returns a new instance of Git.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/test_ids/git.rb', line 52 def initialize() unless File.exist?("#{[:local]}/.git") FileUtils.rm_rf([:local]) if File.exist?([:local]) FileUtils.mkdir_p([:local]) Dir.chdir [:local] do `git clone #{[: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 = [:local] @repo = ::Git.open([: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.
15 16 17 |
# File 'lib/test_ids/git.rb', line 15 def local @local end |
#repo ⇒ Object (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
.path_to_local ⇒ Object
Returns a path to the local test IDs repo, if multiple are found the user will be prompted to choose one
47 48 49 50 |
# File 'lib/test_ids/git.rb', line 47 def self.path_to_local # Implemented as a class as a hack to get access to InputCapture PathToLocal.new.find end |
Instance Method Details
#available_to_lock? ⇒ Boolean
154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/test_ids/git.rb', line 154 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
103 104 105 106 107 108 |
# File 'lib/test_ids/git.rb', line 103 def exec(cmd) r = system(cmd) unless r fail "Something went wrong running command: #{cmd}" end end |
#get_lock ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/test_ids/git.rb', line 126 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_content ⇒ Object
180 181 182 183 |
# File 'lib/test_ids/git.rb', line 180 def lock_content f = File.join(local, 'lock.json') JSON.load(File.read(f)) if File.exist?(f) end |
#lock_expires ⇒ Object
172 173 174 |
# File 'lib/test_ids/git.rb', line 172 def lock_expires lock_content['expires'] end |
#lock_minutes_remaining ⇒ Object
168 169 170 |
# File 'lib/test_ids/git.rb', line 168 def lock_minutes_remaining ((lock_expires - Time.now.to_f) / 60).ceil end |
#lock_user ⇒ Object
176 177 178 |
# File 'lib/test_ids/git.rb', line 176 def lock_user lock_content['user'] end |
#minutes(number) ⇒ Object
185 186 187 |
# File 'lib/test_ids/git.rb', line 185 def minutes(number) number * 60 end |
#publish ⇒ Object
110 111 112 113 114 115 116 117 |
# File 'lib/test_ids/git.rb', line 110 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_lock ⇒ Object
146 147 148 149 150 151 152 |
# File 'lib/test_ids/git.rb', line 146 def release_lock data = { 'user' => nil, 'expires' => nil } write('lock.json', JSON.pretty_generate(data)) end |
#rollback(id) ⇒ Object
Roll the repo back to the given commit ID
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/test_ids/git.rb', line 76 def rollback(id) name = Pathname.new(local).basename.to_s begin commit = repo.object(id) rescue ::Git::GitExecuteError puts 'The given commit ID cannot be found in that repository' exit end # day = 24 * 60 * 60 # if commit.date < Time.now - (7 * day) # puts "Sorry, that commit is more than a week old and I'm too scared to rollback that far." # puts 'You will need to do that manually if you must.' # exit # end puts puts "About to rollback the TestIds repository #{name} to commit #{id}." puts puts 'This will permanently delete any IDs assigned by anyone, anywhere, since that commit.' puts puts 'ARE YOU SURE YOU KNOW WHAT YOU ARE DOING?' puts get_text(confirm: true, default: 'no') repo.reset_hard(id) repo.push('origin', 'master', force: true) puts 'As you wish, rolled back successfully!' end |
#write(path, data = nil) ⇒ Object
Writes the data to the given file and pushes to the remote repo
120 121 122 123 124 |
# File 'lib/test_ids/git.rb', line 120 def write(path, data = nil) f = File.join(local, path) File.write(f, data) if data repo.add(f) end |