Permalink
Browse files

Somewhat hacky modifications to allow RubyGems to install Maven artif…

…acts. Incorporates maven_gem into main repository for now.
  • Loading branch information...
1 parent 373815b commit eeda76472c6271b05f5571449b98a27f2ef844d8 @headius headius committed Sep 17, 2010
@@ -4,6 +4,7 @@
require 'uri'
require 'rubygems'
+require 'maven_gem'
##
# RemoteFetcher handles the details of fetching gems and gem information from
@@ -93,73 +94,81 @@ def download(spec, source_uri, install_dir = Gem.dir)
URI.escape(source_uri))
end
- scheme = source_uri.scheme
+ if source_uri.to_s[/^maven:/]
+ pom_uri = source_uri.to_s.sub("maven:", "")
+ pom_uri += "#{spec.name.gsub('.', '/')}/#{spec.version}/#{spec.name.split('.')[-1]}-#{spec.version}.pom"
+ pom_doc = MavenGem::PomFetcher.fetch(pom_uri)
+ pom = MavenGem::PomSpec.parse_pom(pom_doc)
+ gem_dir = MavenGem::PomSpec.create_gem(spec, pom, local_gem_path)
+ FileUtils.mv "/tmp/" + pom.gem_file, local_gem_path
+ else
+ scheme = source_uri.scheme
- # URI.parse gets confused by MS Windows paths with forward slashes.
- scheme = nil if scheme =~ /^[a-z]$/i
+ # URI.parse gets confused by MS Windows paths with forward slashes.
+ scheme = nil if scheme =~ /^[a-z]$/i
+ case scheme
+ when 'http', 'https' then
+ unless File.exist? local_gem_path then
+ begin
+ say "Downloading gem #{gem_file_name}" if
+ Gem.configuration.really_verbose
- case scheme
- when 'http', 'https' then
- unless File.exist? local_gem_path then
- begin
- say "Downloading gem #{gem_file_name}" if
- Gem.configuration.really_verbose
+ remote_gem_path = source_uri + "gems/#{gem_file_name}"
- remote_gem_path = source_uri + "gems/#{gem_file_name}"
+ gem = self.fetch_path remote_gem_path
+ rescue Gem::RemoteFetcher::FetchError
+ raise if spec.original_platform == spec.platform
- gem = self.fetch_path remote_gem_path
- rescue Gem::RemoteFetcher::FetchError
- raise if spec.original_platform == spec.platform
+ alternate_name = "#{spec.original_name}.gem"
- alternate_name = "#{spec.original_name}.gem"
+ say "Failed, downloading gem #{alternate_name}" if
+ Gem.configuration.really_verbose
- say "Failed, downloading gem #{alternate_name}" if
- Gem.configuration.really_verbose
+ remote_gem_path = source_uri + "gems/#{alternate_name}"
- remote_gem_path = source_uri + "gems/#{alternate_name}"
+ gem = self.fetch_path remote_gem_path
+ end
- gem = self.fetch_path remote_gem_path
+ File.open local_gem_path, 'wb' do |fp|
+ fp.write gem
+ end
end
+ when 'file' then
+ begin
+ path = source_uri.path
+ path = File.dirname(path) if File.extname(path) == '.gem'
+
+ remote_gem_path = File.join(path, 'gems', gem_file_name)
- File.open local_gem_path, 'wb' do |fp|
- fp.write gem
+ FileUtils.cp(remote_gem_path, local_gem_path)
+ rescue Errno::EACCES
+ local_gem_path = source_uri.to_s
end
- end
- when 'file' then
- begin
- path = source_uri.path
- path = File.dirname(path) if File.extname(path) == '.gem'
- remote_gem_path = File.join(path, 'gems', gem_file_name)
+ say "Using local gem #{local_gem_path}" if
+ Gem.configuration.really_verbose
+ when nil then # TODO test for local overriding cache
+ source_path = if Gem.win_platform? && source_uri.scheme &&
+ !source_uri.path.include?(':') then
+ "#{source_uri.scheme}:#{source_uri.path}"
+ else
+ source_uri.path
+ end
- FileUtils.cp(remote_gem_path, local_gem_path)
- rescue Errno::EACCES
- local_gem_path = source_uri.to_s
- end
+ source_path = URI.unescape source_path
- say "Using local gem #{local_gem_path}" if
- Gem.configuration.really_verbose
- when nil then # TODO test for local overriding cache
- source_path = if Gem.win_platform? && source_uri.scheme &&
- !source_uri.path.include?(':') then
- "#{source_uri.scheme}:#{source_uri.path}"
- else
- source_uri.path
- end
-
- source_path = URI.unescape source_path
-
- begin
- FileUtils.cp source_path, local_gem_path unless
- File.expand_path(source_path) == File.expand_path(local_gem_path)
- rescue Errno::EACCES
- local_gem_path = source_uri.to_s
- end
+ begin
+ FileUtils.cp source_path, local_gem_path unless
+ File.expand_path(source_path) == File.expand_path(local_gem_path)
+ rescue Errno::EACCES
+ local_gem_path = source_uri.to_s
+ end
- say "Using local gem #{local_gem_path}" if
- Gem.configuration.really_verbose
- else
- raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
+ say "Using local gem #{local_gem_path}" if
+ Gem.configuration.really_verbose
+ else
+ raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
+ end
end
local_gem_path
@@ -1,5 +1,6 @@
require 'zlib'
require 'fileutils'
+require 'rexml/document'
require 'rubygems/remote_fetcher'
require 'rubygems/user_interaction'
@@ -57,6 +58,9 @@ def initialize
# Returns the local directory to write +uri+ to.
def cache_dir(uri)
+ if uri.to_s[/^maven:/]
+ uri = URI.parse(uri.to_s.sub("maven:", ""))
+ end
File.join @dir, "#{uri.host}%#{uri.port}", File.dirname(uri.path)
end
@@ -101,10 +105,18 @@ def fetch_spec(spec, source_uri)
if File.exist? local_spec then
spec = Gem.read_binary local_spec
else
- uri.path << '.rz'
+ if source_uri.to_s[/^maven:/]
+ pom_uri = source_uri.to_s.sub("maven:", "")
+ pom_uri += "#{spec[0].gsub('.', '/')}/#{spec[1]}/#{spec[0].split('.')[-1]}-#{spec[1]}.pom"
+ pom_doc = MavenGem::PomFetcher.fetch(pom_uri)
+ pom = MavenGem::PomSpec.parse_pom(pom_doc)
+ spec = Marshal.dump(MavenGem::PomSpec.generate_spec(pom))
+ else
+ uri.path << '.rz'
- spec = @fetcher.fetch_path uri
- spec = Gem.inflate spec
+ spec = @fetcher.fetch_path uri
+ spec = Gem.inflate spec
+ end
if @update_cache then
FileUtils.mkdir_p cache_dir
@@ -123,35 +135,85 @@ def fetch_spec(spec, source_uri)
# Find spec names that match +dependency+. If +all+ is true, all
# matching released versions are returned. If +matching_platform+
# is false, gems for all platforms are returned.
+
+ def get_type(all, prerelease)
+ if all
+ :all
+ elsif prerelease
+ :prerelease
+ else
+ :latest
+ end
+ end
+
+ SPEC_FILES = {
+ :latest => 'latest_specs',
+ :prerelease => 'prerelease_specs',
+ :all => 'specs'
+ }
def find_matching_with_errors(dependency, all = false, matching_platform = true, prerelease = false)
- found = {}
+ # TODO: make type the only argument
+ type = get_type(all, prerelease)
+ file = SPEC_FILES[type]
+ cache = { :latest => @latest_specs,
+ :prerelease => @prerelease_specs,
+ :all => @specs }[type]
+
+ specs_and_sources = []
rejected_specs = {}
- list(all, prerelease).each do |source_uri, specs|
- found[source_uri] = specs.select do |spec_name, version, spec_platform|
- if dependency.match?(spec_name, version)
- if matching_platform and !Gem::Platform.match(spec_platform)
- pm = (rejected_specs[dependency] ||= Gem::PlatformMismatch.new(spec_name, version))
- pm.add_platform spec_platform
- false
- else
- true
+ Gem.sources.each do |source_uri|
+ if source_uri[/^maven:/]
+ # maven processing
+
+ # peel off maven:
+ maven_repo = source_uri.sub("maven:", "")
+ # add metadata xml
+ maven_repo += dependency.name.gsub(".", "/") + "/maven-metadata.xml"
+
+ # fetch and process metadata XML
+ maven_uri = URI.parse(maven_repo)
+ begin
+ xml_data = @fetcher.fetch_path(maven_uri)
+
+ xml = REXML::Document.new(xml_data)
+
+ # scan all versions for matching ones
+ REXML::XPath.each(xml, "//versions/version") do |version|
+ if dependency.match?(dependency.name, version.text)
+ # no platform check here, since maven jars are a jruby-specific feature
+ specs_and_sources.push [[dependency.name, version.text, "java"], source_uri.to_s]
+ end
+ end
+ end
+ else
+ source_uri = URI.parse source_uri
+
+ unless cache.include? source_uri
+ cache[source_uri] = load_specs source_uri, file
+ end
+
+ cache[source_uri].each do |gem|
+ # filter out prereleases
+ next if type == all && (!gems[1] || gems[1].prerelease?)
+
+ spec_name, version, spec_platform = gem
+ if dependency.match?(spec_name, version) and
+ if matching_platform and !Gem::Platform.match(spec_platform)
+ pm = (rejected_specs[dependency] ||= Gem::PlatformMismatch.new(spec_name, version))
+ pm.add_platform spec_platform
+ else
+ specs_and_sources.push [gem, source_uri.to_s]
+ end
end
end
end
end
-
+
errors = rejected_specs.values
- specs_and_sources = []
-
- found.each do |source_uri, specs|
- uri_str = source_uri.to_s
- specs_and_sources.push(*specs.map { |spec| [spec, uri_str] })
- end
-
[specs_and_sources, errors]
end
@@ -208,6 +270,7 @@ def list(all = false, prerelease = false)
:all => @specs }[type]
Gem.sources.each do |source_uri|
+ next if source_uri[/^maven:/]
source_uri = URI.parse source_uri
unless cache.include? source_uri
@@ -0,0 +1,26 @@
+$:.unshift(File.dirname(__FILE__)) unless
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
+
+require 'maven_gem/xml_utils'
+require 'maven_gem/pom_spec'
+require 'maven_gem/pom_fetcher'
+require 'rubygems'
+require 'rubygems/gem_runner'
+
+module MavenGem
+ def self.install(group, artifact = nil, version = nil)
+ gem = build(group, artifact, version)
+ Gem::GemRunner.new.run(["install", gem])
+ ensure
+ FileUtils.rm_f(gem) if gem
+ end
+
+ def self.build(group, artifact = nil, version = nil)
+ gem = if artifact
+ url = MavenGem::PomSpec.to_maven_url(group, artifact, version)
+ MavenGem::PomSpec.build(url)
+ else
+ MavenGem::PomSpec.build(group)
+ end
+ end
+end
@@ -0,0 +1,31 @@
+require 'net/http'
+require 'uri'
+
+module MavenGem
+ class PomFetcher
+
+ def self.fetch(path, options = {})
+ puts "Reading POM from #{path}" if options[:verbose]
+
+ fetch_pom(path, options)
+ end
+
+ def self.clean_pom(pom) #avoid namespaces errors and gotchas
+ pom.gsub(/<project[^>]+/, '<project>')
+ end
+
+ def self.fetch_pom(path, options = {})
+ path =~ /^http:\/\// ? fetch_from_url(path, options) :
+ fetch_from_file(path, options)
+ end
+
+ private
+ def self.fetch_from_url(path, options = {})
+ Net::HTTP.get(URI.parse(path))
+ end
+
+ def self.fetch_from_file(path, options = {})
+ File.read(path)
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit eeda764

Please sign in to comment.