class Bundler::Source::Git
def base_name
def base_name File.basename(uri, ".git") end
def cache
def cache if cache_path.exist? Bundler.ui.info "Updating #{uri}" in_cache { git "fetch --quiet #{uri} master:master" } else Bundler.ui.info "Fetching #{uri}" FileUtils.mkdir_p(cache_path.dirname) git "clone #{uri} #{cache_path} --bare --no-hardlinks" end end
def cache_path
def cache_path @cache_path ||= Bundler.cache.join("git", "#{base_name}-#{uri_hash}") end
def git(command)
def git(command) out = %x{git #{command}} if $? != 0 raise GitError, "An error has occurred in git. Cannot complete bundling." end out end
def in_cache(&blk)
def in_cache(&blk) Dir.chdir(cache_path, &blk) end
def initialize(options)
def initialize(options) @options = options @glob = options["glob"] || "{,*/}*.gemspec" @uri = options["uri"] @ref = options["ref"] || options["branch"] || 'master' end
def install(spec)
def install(spec) Bundler.ui.debug " * Using git #{uri}" if @installed Bundler.ui.debug " * Already checked out revision: #{ref}" else Bundler.ui.debug " * Checking out revision: #{ref}" FileUtils.mkdir_p(path) Dir.chdir(path) do unless File.exist?(".git") %x(git clone --no-checkout #{cache_path} #{path}) end git "fetch --quiet" git "reset --hard #{revision}" end @installed = true end end
def options
def options @options.merge("ref" => revision) end
def path
def path Bundler.install_path.join("#{base_name}-#{uri_hash}-#{ref}") end
def revision
def revision @revision ||= in_cache { git("rev-parse #{ref}").strip } end
def specs
def specs @specs ||= begin index = Index.new # Start by making sure the git cache is up to date cache # Find all gemspecs in the repo in_cache do out = %x(git ls-tree -r #{revision}).strip lines = out.split("\n").select { |l| l =~ /\.gemspec$/ } # Loop over the lines and extract the relative path and the # git hash lines.each do |line| next unless line =~ %r{^(\d+) (blob|tree) ([a-zf0-9]+)\t(.*)$} hash, file = $3, $4 # Read the gemspec if spec = eval(%x(git cat-file blob #{$3})) spec = Specification.from_gemspec(spec) spec.relative_loaded_from = file spec.source = self index << spec end end end index << default_spec if default_spec && index.empty? index.freeze end end
def to_s
def to_s ref = @options["ref"] ? @options["ref"][0..6] : @ref "#{@uri} (at #{ref})" end
def uri_hash
def uri_hash Digest::SHA1.hexdigest(URI.parse(uri).normalize.to_s.sub(%r{/$}, '')) end