moduleBundlerclassDirectorySourceError<StandardError;endclassGitSourceError<StandardError;end# Represents a source of rubygems. Initially, this is only gem repositories, but# eventually, this will be git, svn, HTTPclassSourceattr_accessor:repository,:localdefinitialize(options);endprivatedefprocess_source_gems(gems)new_gems=Hash.new{|h,k|h[k]=[]}gems.values.eachdo|spec|spec.source=selfnew_gems[spec.name]<<specendnew_gemsendendclassGemSource<Sourceattr_reader:uridefinitialize(options)@uri=options[:uri]@uri=URI.parse(@uri)unless@uri.is_a?(URI)raiseArgumentError,"The source must be an absolute URI"unless@uri.absolute?enddefcan_be_local?falseenddefgems@specs||=fetch_specsenddef==(other)uri==other.urienddefto_s@uri.to_sendclassRubygemsRetardation<StandardError;enddefdownload(spec)Bundler.logger.info"Downloading #{spec.full_name}.gem"destination=repository.pathunlessdestination.writable?raiseRubygemsRetardation,"destination: #{destination} is not writable"end# Download the gemGem::RemoteFetcher.fetcher.download(spec,uri,destination)# Re-read the gemspec from the downloaded gem to correct# any errors that were present in the Rubyforge specification.new_spec=Gem::Format.from_file_by_path(destination.join('cache',"#{spec.full_name}.gem")).specspec.__swap__(new_spec)endprivatedeffetch_specsBundler.logger.info"Updating source: #{to_s}"fetcher=Gem::RemoteFetcher.fetchermain_index=fetcher.fetch_path("#{uri}/specs.4.8.gz")beginprerelease_index=fetcher.fetch_path("#{uri}/prerelease_specs.4.8.gz")index=Marshal.load(main_index)+Marshal.load(prerelease_index)rescueGem::RemoteFetcher::FetchErrorBundler.logger.warn"Source '#{uri}' does not support prerelease gems"index=Marshal.load(main_index)endgems=Hash.new{|h,k|h[k]=[]}index.eachdo|name,version,platform|spec=RemoteSpecification.new(name,version,platform,@uri)spec.source=selfgems[spec.name]<<specifGem::Platform.match(spec.platform)endgemsrescueGem::RemoteFetcher::FetchError=>eraiseArgumentError,"#{to_s} is not a valid source: #{e.message}"endendclassSystemGemSource<Sourcedefself.instance@instance||=new({})enddefinitialize(options)@source=Gem::SourceIndex.from_installed_gemsenddefcan_be_local?falseenddefgems@gems||=process_source_gems(@source.gems)enddef==(other)other.is_a?(SystemGemSource)enddefto_s"system"enddefdownload(spec)gemfile=Pathname.new(spec.loaded_from)gemfile=gemfile.dirname.join('..','cache',"#{spec.full_name}.gem")repository.cache(gemfile)endprivateendclassGemDirectorySource<Sourceattr_reader:locationdefinitialize(options)@location=options[:location]enddefcan_be_local?trueenddefgems@specs||=fetch_specsenddef==(other)location==other.locationenddefto_slocation.to_senddefdownload(spec)# raise NotImplementedErrorendprivatedeffetch_specsspecs=Hash.new{|h,k|h[k]=[]}Dir["#{@location}/*.gem"].eachdo|gemfile|spec=Gem::Format.from_file_by_path(gemfile).specspec.source=selfspecs[spec.name]<<specendspecsendendclassDirectorySource<Sourceattr_reader:location,:specs,:required_specsdefinitialize(options)ifoptions[:location]@location=Pathname.new(options[:location]).expand_pathend@glob=options[:glob]||"**/*.gemspec"@specs={}@required_specs=[]enddefadd_spec(path,name,version,require_paths=%w(lib))raiseDirectorySourceError,"already have a gem defined for '#{path}'"if@specs[path.to_s]@specs[path.to_s]=Gem::Specification.newdo|s|s.name=names.version=Gem::Version.new(version)endenddefcan_be_local?trueenddefgems@gems||=begin# Locate all gemspecs from the directoryspecs=locate_gemspecsspecs=merge_defined_specs(specs)required_specs.eachdo|required|unlessspecs.any?{|k,v|v.name==required}raiseDirectorySourceError,"No gemspec for '#{required}' was found in"\" '#{location}'. Please explicitly specify a version."endendprocess_source_gems(specs)endenddeflocate_gemspecsDir["#{location}/#{@glob}"].inject({})do|specs,file|file=Pathname.new(file)ifspec=eval(File.read(file))andvalidate_gemspec(file.dirname,spec)spec.location=file.dirname.expand_pathspecs[spec.full_name]=specendspecsendenddefmerge_defined_specs(specs)@specs.eachdo|path,spec|# Set the spec locationspec.location="#{location}/#{path}"ifexisting=specs.values.find{|s|s.name==spec.name}ifexisting.version!=spec.versionraiseDirectorySourceError,"The version you specified for #{spec.name}"\" is #{spec.version}. The gemspec is #{existing.version}."# Not sure if this is needed# ====# elsif File.expand_path(existing.location) != File.expand_path(spec.location)# raise DirectorySourceError, "The location you specified for #{spec.name}" \# " is '#{spec.location}'. The gemspec was found at '#{existing.location}'."endelsif!validate_gemspec(spec.location,spec)raise"Your gem definition is not valid: #{spec}"elsespecs[spec.full_name]=specendendspecsenddefvalidate_gemspec(path,spec)path=Pathname.new(path)msg="Gemspec for #{spec.name} (#{spec.version}) is invalid:"# Check the require_paths(spec.require_paths||[]).eachdo|require_path|unlesspath.join(require_path).directory?Bundler.logger.warn"#{msg} Missing require path: '#{require_path}'"returnfalseendend# Check the executables(spec.executables||[]).eachdo|exec|unlesspath.join(spec.bindir,exec).file?Bundler.logger.warn"#{msg} Missing executable: '#{File.join(spec.bindir,exec)}'"returnfalseendendtrueenddef==(other)# TMP HAXother.is_a?(DirectorySource)enddefto_s"#{@name} (#{@version}) Located at: '#{location}'"enddefdownload(spec)# Nothing needed hereendendclassGitSource<DirectorySourceattr_reader:ref,:uri,:branchdefinitialize(options)super@uri=options[:uri]@ref=options[:ref]@branch=options[:branch]enddeflocation# TMP HAX to get the *.gemspec reading to workrepository.path.join('dirs',File.basename(@uri,'.git'))enddefgemsunlesslocation.directory?# Raise an error if the source should run in local mode,# but it has not been cached yet.iflocalraiseSourceNotCached,"Git repository '#{@uri}' has not been cloned yet"endFileUtils.mkdir_p(location.dirname)Bundler.logger.info"Cloning git repository at: #{@uri}"`git clone #{@uri}#{location} --no-hardlinks`if@refDir.chdir(location){`git checkout --quiet #{@ref}`}elsif@branch&&@branch!="master"Dir.chdir(location){`git checkout --quiet origin/#{@branch}`}endendsuperenddefdownload(spec)# Nothing needed hereendendend