require 'jar_dependencies' module Jars class JarInstaller class Dependency attr_reader :path, :file, :gav, :scope, :type, :coord def self.new( line ) if line.match /:jar:|:pom:/ super end end def setup_type( line ) if line.match /:pom:/ @type = :pom elsif line.match /:jar:/ @type = :jar end end private :setup_type def setup_scope( line ) @scope = case line when /:provided:/ :provided when /:test:/ :test else :runtime end end private :setup_scope def initialize( line ) setup_type( line ) line.sub!( /^\s+/, '' ) @coord = line.sub( /:[^:]+:[^:]+$/, '' ) first, second = line.sub( /:[^:]+:[^:]+$/, '' ).split( /:#{type}:/ ) group_id, artifact_id = first.split( /:/ ) parts = group_id.split( '.' ) parts << artifact_id parts << second.split( /:/ )[ -1 ] parts << File.basename( line.sub /.:/, '' ) @path = File.join( parts ).strip setup_scope( line ) line.gsub!( /:jar:|:pom:|:test:|:compile:|:runtime:|:provided:/, ':' ) @file = line.sub( /^.*:/, '' ).strip @gav = line.sub( /:[^:]+$/, '' ) end end def self.install_jars new.install_jars end def self.load_from_maven( file ) result = [] File.read( file ).each_line do |line| dep = Dependency.new( line ) result << dep if dep end result end def self.write_require_file( require_filename ) FileUtils.mkdir_p( File.dirname( require_filename ) ) comment = '# this is a generated file, to avoid over-writing it just delete this comment' if ! File.exists?( require_filename ) || File.read( require_filename ).match( comment ) f = File.open( require_filename, 'w' ) f.puts comment f.puts "require 'jar_dependencies'" f.puts f end end def self.vendor_file( dir, dep ) vendored = File.join( dir, dep.path ) FileUtils.mkdir_p( File.dirname( vendored ) ) FileUtils.cp( dep.file, vendored ) end def self.install_deps( deps, dir, require_filename, vendor ) f = write_require_file( require_filename ) if require_filename deps.each do |dep| next if dep.type != :jar || dep.scope != :runtime args = dep.gav.gsub( /:/, "', '" ) vendor_file( dir, dep ) if vendor f.puts( "require_jar( '#{args}' )" ) if f end yield f if block_given? ensure f.close if f end def find_spec specs = Dir[ '*.gemspec' ] case specs.size when 0 raise 'no gemspec found' when 1 specs.first else raise 'more then one gemspec found. please specify a specfile' end end private :find_spec def initialize( spec = nil ) spec ||= find_spec case spec when String @basedir = File.dirname( File.expand_path( spec ) ) @specfile = spec spec = eval( File.read( spec ) ) when if File.exists?( spec.spec_file ) @basedir = spec.gem_dir @specfile = spec.spec_file else initialize( nil ) end end @spec = spec end def ruby_maven_install_options=( options ) @options = options.dup end def vendor_jars return unless has_jars? # do not vendor only if set explicitly via ENV/system-properties do_install( Jars.to_prop( Jars::VENDOR ) != 'false', false ) end def install_jars return unless has_jars? do_install( false, true ) end private def has_jars? # first look if there are any requirements in the spec # and then if gem depends on jar-dependencies # only then install the jars declared in the requirements ! @spec.requirements.empty? && @spec.dependencies.detect { |d| d.name == 'jar-dependencies' && d.type == :runtime } end def do_install( vendor, write_require_file ) vendor_dir = File.join( @basedir, @spec.require_path ) if write_require_file jars_file = File.join( vendor_dir, "#{@spec.name}_jars.rb" ) # do not generate file if specfile is older then the generated file if File.exists?( jars_file ) && File.mtime( @specfile ) < File.mtime( jars_file ) jars_file = nil end end self.class.install_deps( install_dependencies, vendor_dir, jars_file, vendor ) end def setup_arguments( deps ) args = [ 'dependency:list', "-DoutputFile=#{deps}", '-DincludeScope=runtime', '-DoutputAbsoluteArtifactFilename=true', '-DincludeTypes=jar', '-DoutputScope=true', '-f', @specfile ] if Jars.debug? args << '-X' elsif not Jars.verbose? args << '--quiet' end if defined? JRUBY_VERSION args << "-Dmaven.repo.local=#{java.io.File.new( Jars.home ).absolute_path}" else args << "-Dmaven.repo.local=#{File.expand_path( Jars.home )}" end args end def lazy_load_maven require 'maven/ruby/maven' rescue LoadError install_ruby_maven require 'maven/ruby/maven' end def install_ruby_maven require 'rubygems/dependency_installer' jars = Gem.loaded_specs[ 'jar-dependencies' ] dep = jars.dependencies.detect { |d| d.name == 'ruby-maven' } req = dep.nil? ? Gem::Requirement.create( '>0' ) : dep.requirement inst = Gem::DependencyInstaller.new( @options || {} ) inst.install 'ruby-maven', req rescue => e warn e.backtrace.join( "\n" ) if Jars.verbose? raise "there was an error installing 'ruby-maven'. please install it manually: " + e.message end def monkey_path_gem_dependencies # monkey patch to NOT include gem dependencies require 'maven/tools/gemspec_dependencies' eval <