class Omnibus::GitFetcher
Fetcher
implementation for projects in git.
Attributes
project_dir[R]
source[R]
version[R]
Public Class Methods
new(software)
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 29 def initialize(software) @name = software.name @source = software.source @version = software.version @project_dir = software.project_dir end
Public Instance Methods
clean()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 48 def clean if existing_git_clone? log "cleaning existing build" clean_cmd = "git clean -fdx" shell = Mixlib::ShellOut.new(clean_cmd, :live_stream => STDOUT, :cwd => project_dir) shell.run_command shell.error! end rescue Exception => e ErrorReporter.new(e, self).explain("Failed to clean git repository '#{@source[:git]}'") raise end
description()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 36 def description s=<<-E repo URI: #{@source[:git]} local location: #{@project_dir} E end
fetch()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 65 def fetch retries ||= 0 if existing_git_clone? fetch_updates unless current_rev_matches_target_rev? else clone checkout end rescue Exception => e if retries >= 3 ErrorReporter.new(e, self).explain("Failed to fetch git repository '#{@source[:git]}'") raise else # Deal with github failing all the time :( time_to_sleep = 5 * (2 ** retries) retries += 1 log "git clone/fetch failed for #{@source} #{retries} time(s), retrying in #{time_to_sleep}s" sleep(time_to_sleep) retry end end
fetch_required?()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 61 def fetch_required? !existing_git_clone? || !current_rev_matches_target_rev? end
version_guid()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 43 def version_guid "git:#{current_revision}".chomp rescue end
Private Instance Methods
checkout()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 97 def checkout sha_ref = target_revision checkout_cmd = "git checkout #{sha_ref}" shell = Mixlib::ShellOut.new(checkout_cmd, :live_stream => STDOUT, :cwd => project_dir) shell.run_command shell.error! end
clone()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 89 def clone puts "cloning the source from git" clone_cmd = "git clone #{@source[:git]} #{project_dir}" shell = Mixlib::ShellOut.new(clone_cmd, :live_stream => STDOUT) shell.run_command shell.error! end
current_rev_matches_target_rev?()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 118 def current_rev_matches_target_rev? current_revision && current_revision.strip.to_i(16) == target_revision.strip.to_i(16) end
current_revision()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 122 def current_revision @current_rev ||= begin rev_cmd = "git rev-parse HEAD" shell = Mixlib::ShellOut.new(rev_cmd, :live_stream => STDOUT, :cwd => project_dir) shell.run_command shell.error! output = shell.stdout sha_hash?(output) ? output : nil end end
existing_git_clone?()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 114 def existing_git_clone? File.exist?("#{project_dir}/.git") end
fetch_updates()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 106 def fetch_updates puts "fetching updates and resetting to revision #{target_revision}" fetch_cmd = "git fetch origin && git fetch origin --tags && git reset --hard #{target_revision}" shell = Mixlib::ShellOut.new(fetch_cmd, :live_stream => STDOUT, :cwd => project_dir) shell.run_command shell.error! end
process_remote_list(stdout, ref)
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 179 def process_remote_list(stdout, ref) # Dereference annotated tags. # # Output will look like this: # # a2ed66c01f42514bcab77fd628149eccb4ecee28 refs/tags/rel-0.11.0 # f915286abdbc1907878376cce9222ac0b08b12b8 refs/tags/rel-0.11.0^{} # # The SHA with ^{} is the commit pointed to by an annotated # tag. If ref isn't an annotated tag, there will not be a line # with trailing ^{}. # # We'll return the SHA corresponding to the ^{} which is the # commit pointed to by an annotated tag. If no such commit # exists (not an annotated tag) then we return the SHA of the # ref. If nothing matches, return "". lines = stdout.split("\n") matches = lines.map { |line| line.split("\t") } # first try for ^{} indicating the commit pointed to by an # annotated tag tagged_commit = matches.find { |m| m[1].end_with?("#{ref}^{}") } if tagged_commit tagged_commit[0] else found = matches.find { |m| m[1].end_with?("#{ref}") } if found found[0] else nil end end end
revision_from_remote_reference(ref)
click to toggle source
Return the SHA corresponding to ref. If ref is an annotated tag, return the SHA that was tagged not the SHA of the tag itself.
# File lib/omnibus/fetchers/git_fetcher.rb, line 150 def revision_from_remote_reference(ref) retries ||= 0 # execute `git ls-remote` the trailing '*' does globbing. This # allows us to return the SHA of the tagged commit for annotated # tags. We take care to only return exact matches in # process_remote_list. cmd = "git ls-remote origin #{ref}*" shell = Mixlib::ShellOut.new(cmd, :live_stream => STDOUT, :cwd => project_dir) shell.run_command shell.error! commit_ref = process_remote_list(shell.stdout, ref) if !commit_ref raise "Could not parse SHA reference" end commit_ref rescue Exception => e if retries >= 3 ErrorReporter.new(e, self).explain("Failed to fetch git repository '#{@source[:git]}'") raise else # Deal with github failing all the time :( time_to_sleep = 5 * (2 ** retries) retries += 1 log "git ls-remote failed for #{@source} #{retries} time(s), retrying in #{time_to_sleep}s" sleep(time_to_sleep) retry end end
sha_hash?(rev)
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 144 def sha_hash?(rev) rev =~ /^[0-9a-f]{40}$/ end
target_revision()
click to toggle source
# File lib/omnibus/fetchers/git_fetcher.rb, line 134 def target_revision @target_rev ||= begin if sha_hash?(version) version else revision_from_remote_reference(version) end end end