jbundler 0.8.0.pre → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/jbundler/pom.rb CHANGED
@@ -1,35 +1,153 @@
1
- bdir = java.lang.System.getProperty( "jbundler.basedir" )
2
- jfile = java.lang.System.getProperty( "jbundler.jarfile" )
1
+ #
2
+ # Copyright (C) 2013 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'fileutils'
22
+ require 'tempfile'
23
+ require 'maven/tools/coordinate'
24
+ require 'securerandom'
3
25
 
4
- basedir( bdir )
5
- if basedir != bdir
6
- # older maven-tools needs this
7
- self.instance_variable_set( :@basedir, bdir )
8
- end
26
+ module JBundler
9
27
 
10
- ( 0..10000 ).each do |i|
11
- coord = java.lang.System.getProperty( "jbundler.jars.#{i}" )
12
- break unless coord
13
- artifact = Maven::Tools::Artifact.from_coordinate( coord.to_s )
14
- # HACK around broken maven-tools
15
- if artifact.exclusions
16
- ex = artifact.classifier[1..-1] + ':' + artifact.exclusions.join(':')
17
- artifact.classifier = nil
18
- artifact.exclusions = ex.split /,/
19
- end
20
- dependency_artifact( artifact )
21
- end
28
+ class Pom
29
+
30
+ include Maven::Tools::Coordinate
31
+
32
+ private
33
+
34
+ def temp_dir
35
+ @temp_dir ||=
36
+ begin
37
+ # on travis the mktmpdir failed
38
+ d = Dir.mktmpdir rescue FileUtils.mkdir( ".tmp" + SecureRandom.hex( 12) ).first
39
+ at_exit { FileUtils.rm_rf(d.dup) }
40
+ # for jruby-1.7.4 1.8 mode add expand_path
41
+ File.expand_path( d )
42
+ end
43
+ end
44
+
45
+ def writeElement(xmlWriter,element_name, text)
46
+ xmlWriter.writeStartElement(element_name.to_java)
47
+ xmlWriter.writeCharacters(text.to_java)
48
+ xmlWriter.writeEndElement
49
+ end
50
+
51
+ def java_imports
52
+ %w(
53
+ javax.xml.stream.XMLStreamWriter
54
+ javax.xml.stream.XMLOutputFactory
55
+ javax.xml.stream.XMLStreamException
56
+ ).each {|i| java_import i }
57
+ end
58
+
59
+ GROUP_ID = 'ruby.bundler'
60
+
61
+ def start_write_pom( out, name, version, packaging )
62
+ outputFactory = XMLOutputFactory.newFactory()
63
+ xmlStreamWriter = outputFactory.createXMLStreamWriter( out )
64
+
65
+ xmlStreamWriter.writeStartDocument
66
+ xmlStreamWriter.writeStartElement("project")
67
+
68
+ writeElement(xmlStreamWriter,"modelVersion","4.0.0")
69
+ writeElement(xmlStreamWriter,"groupId", GROUP_ID)
70
+ writeElement(xmlStreamWriter,"artifactId", name)
71
+ writeElement(xmlStreamWriter,"version", version.to_s.to_java)
72
+ writeElement(xmlStreamWriter,"packaging", packaging) if packaging
73
+ xmlStreamWriter
74
+ end
22
75
 
23
- jarfile( jfile )
76
+ def to_classifier_version( coords )
77
+ if coords.size == 4
78
+ [ nil, coords[3] ]
79
+ else
80
+ [ coords[3], coords[4] ]
81
+ end
82
+ end
24
83
 
25
- properties( 'project.build.sourceEncoding' => 'utf-8' )
84
+ def write_dep( xmlStreamWriter, coord )
85
+ coords = coord.split(/:/)
86
+ group_id = coords[0]
87
+ artifact_id = coords[1]
88
+ extension = coords[2]
89
+ classifier, version = to_classifier_version( coords )
90
+
91
+ xmlStreamWriter.writeStartElement("dependency".to_java)
92
+ writeElement(xmlStreamWriter,"groupId", group_id)
93
+ writeElement(xmlStreamWriter,"artifactId", artifact_id)
94
+ writeElement(xmlStreamWriter,"version", version)
95
+
96
+ writeElement(xmlStreamWriter,"type", extension) if extension != 'jar'
97
+ writeElement(xmlStreamWriter,"classifier", classifier) if classifier
98
+ xmlStreamWriter.writeEndElement #dependency
99
+ end
26
100
 
27
- plugin_repository :id => 'sonatype-snapshots', :url => 'https://oss.sonatype.org/content/repositories/snapshots'
28
- jruby_plugin :gem, '1.0.10-SNAPSHOT'
101
+ def write_dependencies( xmlStreamWriter, deps )
102
+ xmlStreamWriter.writeStartElement("dependencies".to_java)
103
+
104
+ deps.each do |line|
105
+ coord = to_coordinate(line)
106
+ write_dep( xmlStreamWriter, coord ) if coord
107
+ end
29
108
 
30
- plugin :dependency, '2.8'
109
+ xmlStreamWriter.writeEndElement #dependencies
110
+ end
31
111
 
32
- # some output
33
- model.dependencies.each do |d|
34
- puts " " + d.group_id + ':' + d.artifact_id + (d.classifier ? ":" + d.classifier : "" ) + ":" + d.version + ':' + (d.scope || 'compile')
112
+ def end_write_pom( xmlStreamWriter )
113
+ xmlStreamWriter.writeEndElement #project
114
+
115
+ xmlStreamWriter.writeEndDocument
116
+ xmlStreamWriter.close
117
+ end
118
+
119
+ public
120
+
121
+ def coordinate
122
+ @coord ||= "#{GROUP_ID}:#{@name}:#{@packaging}:#{@version}"
123
+ end
124
+
125
+ def file
126
+ @file
127
+ end
128
+
129
+ def initialize(name, version, deps, packaging = nil)
130
+ unless defined? XMLOutputFactory
131
+ java_imports
132
+ end
133
+
134
+ @name = name
135
+ @packaging = packaging || 'jar'
136
+ @version = version
137
+
138
+ @file = File.join(temp_dir, 'pom.xml')
139
+
140
+ out = java.io.BufferedOutputStream.new( java.io.FileOutputStream.new( @file.to_java ) )
141
+
142
+ xmlStreamWriter = start_write_pom( out, name, version, packaging )
143
+
144
+ write_dependencies( xmlStreamWriter, deps )
145
+
146
+ end_write_pom( xmlStreamWriter )
147
+
148
+ ensure
149
+ out.close
150
+ end
151
+
152
+ end
35
153
  end
@@ -0,0 +1,71 @@
1
+ require 'maven/ruby/maven'
2
+ module JBundler
3
+
4
+ class PomRunner
5
+
6
+ def initialize( config )
7
+ @config = config
8
+ end
9
+
10
+ def method_missing( m, *args )
11
+ result = @config[ m ] || @config[ m.to_s ]
12
+ result.nil? ? super : result
13
+ end
14
+
15
+ def maven_new
16
+ m = Maven::Ruby::Maven.new
17
+ m.property( 'base.dir', File.expand_path( basedir ) )
18
+ m.property( 'work.dir', File.expand_path( workdir ) ) if workdir
19
+ m.property( 'verbose', debug || verbose )
20
+ if debug
21
+ m.options[ '-X' ] = nil
22
+ elsif verbose
23
+ m.options[ '-e' ] = nil
24
+ else
25
+ m.options[ '-q' ] = nil
26
+ end
27
+ m.verbose = debug
28
+ m
29
+ end
30
+ private :maven_new
31
+
32
+ def maven
33
+ @m ||= maven_new
34
+ end
35
+
36
+ def basedir
37
+ File.expand_path( '.' )
38
+ end
39
+
40
+ def workdir
41
+ @config[ 'workdir' ]
42
+ end
43
+
44
+ def work_dir
45
+ # needs default here
46
+ workdir || 'pkg'
47
+ end
48
+
49
+ def debug
50
+ @config[ 'debug' ] || false
51
+ end
52
+
53
+ def verbose
54
+ @config[ 'verbose' ] || false
55
+ end
56
+
57
+ def clean?
58
+ @config[ 'clean' ] || false
59
+ end
60
+
61
+ def pom_file
62
+ raise 'overwrite this method'
63
+ end
64
+
65
+ def exec( *args )
66
+ maven.options[ '-f' ] ||= pom_file
67
+ args.unshift :clean if clean?
68
+ maven.exec( *args )
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,53 @@
1
+ require 'jbundler/configurator'
2
+ require 'jbundler/classpath_file'
3
+ require 'jbundler/vendor'
4
+ require 'jbundler/gemfile_lock'
5
+ require 'maven/tools/jarfile'
6
+ require 'maven/ruby/maven'
7
+ require 'fileutils'
8
+ module JBundler
9
+ class Show
10
+
11
+ def initialize( config )
12
+ @config = config
13
+ @classpath_file = JBundler::ClasspathFile.new( @config.classpath_file )
14
+ end
15
+
16
+ def show_classpath
17
+ return if ! @config.verbose
18
+ vendor = JBundler::Vendor.new(@config.vendor_dir)
19
+ if vendor.vendored?
20
+ vendor.require_jars
21
+ warn "complete classpath:"
22
+ $CLASSPATH.each do |path|
23
+ warn "\t#{path}"
24
+ end
25
+ else
26
+ @classpath_file.load_classpath
27
+ warn ''
28
+ warn 'jbundler provided classpath:'
29
+ warn '----------------'
30
+ JBUNDLER_JRUBY_CLASSPATH.each do |path|
31
+ warn "#{path}"
32
+ end
33
+ warn ''
34
+ warn 'jbundler runtime classpath:'
35
+ warn '---------------------------'
36
+ JBUNDLER_CLASSPATH.each do |path|
37
+ warn "#{path}"
38
+ end
39
+ warn ''
40
+ warn 'jbundler test classpath:'
41
+ warn '------------------------'
42
+ if JBUNDLER_TEST_CLASSPATH.empty?
43
+ warn "\t--- empty ---"
44
+ else
45
+ JBUNDLER_TEST_CLASSPATH.each do |path|
46
+ warn "#{path}"
47
+ end
48
+ end
49
+ warn ''
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ require 'jbundler/configurator'
2
+ require 'maven/ruby/maven'
3
+ require 'fileutils'
4
+ module JBundler
5
+ class Tree
6
+
7
+ def initialize( config )
8
+ @config = Configurator.new( config )
9
+ end
10
+
11
+ def show_it( debug = false )
12
+ m = Maven::Ruby::Maven.new
13
+ m.options[ '-f' ] = File.join( File.dirname( __FILE__ ),
14
+ 'dependency_pom.rb' )
15
+ m.options[ '-q' ] = nil unless debug
16
+ m.verbose = debug
17
+
18
+ @config.configure( m )
19
+
20
+ puts '...'
21
+
22
+ tree = File.join( File.expand_path( @config.work_dir ),
23
+ 'tree.txt' )
24
+ m.property( 'jbundler.outputFile', tree )
25
+
26
+ m.exec( 'dependency:tree' )
27
+
28
+ puts File.read( tree )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ require 'jar_installer'
2
+ module JBundler
3
+ class Vendor
4
+
5
+ def initialize( dir )
6
+ @dir = File.expand_path( dir )
7
+ end
8
+
9
+ def vendored?
10
+ File.exists?( @dir ) && Dir[ File.join( @dir, '*' ) ].size > 0
11
+ end
12
+
13
+ def require_jars
14
+ jars = File.join( @dir, 'jbundler.rb' )
15
+ if File.exists?( jars )
16
+ $LOAD_PATH << @dir unless $LOAD_PATH.include? @dir
17
+ require jars
18
+ else
19
+ Dir[ File.join( @dir, '**', '*' ) ].each do |f|
20
+ require f
21
+ end
22
+ Jars.freeze_loading
23
+ true
24
+ end
25
+ end
26
+
27
+ def clear
28
+ FileUtils.mkdir_p( @dir )
29
+ Dir[ File.join( @dir, '*' ) ].each do |f|
30
+ FileUtils.rm_rf( f )
31
+ end
32
+ end
33
+
34
+ def vendor_dependencies( deps )
35
+ require_file = File.join( @dir, 'jbundler.rb' )
36
+ Jars::JarInstaller.install_deps( deps, @dir, require_file, true ) do |f|
37
+ f.puts
38
+ f.puts 'Jars.freeze_loading'
39
+ end
40
+ end
41
+
42
+ def setup( classpath_file )
43
+ classpath_file.require_classpath
44
+ FileUtils.mkdir_p( @dir )
45
+ JBUNDLER_CLASSPATH.each do |f|
46
+ FileUtils.cp( f, File.join( @dir,
47
+ File.basename( f ) ) )
48
+ end
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,138 @@
1
+ load File.expand_path(File.join('spec', 'setup.rb'))
2
+ require 'jbundler/classpath_file'
3
+ require 'maven/tools/jarfile'
4
+ require 'jbundler/gemfile_lock'
5
+
6
+ describe JBundler::ClasspathFile do
7
+
8
+ let(:workdir) { File.join('pkg', 'tmp') }
9
+ let(:jfile) { File.join(workdir, 'jarfile') }
10
+ let(:gfile_lock) { File.join(workdir, 'gemfile.lock') }
11
+ let(:jfile_lock) { jfile + ".lock"}
12
+ let(:cpfile) { File.join(workdir, 'cp.rb') }
13
+ let(:jarfile) { Maven::Tools::Jarfile.new(jfile) }
14
+ let(:gemfile_lock) { JBundler::GemfileLock.new(jarfile, gfile_lock) }
15
+ subject { JBundler::ClasspathFile.new(cpfile) }
16
+
17
+ before do
18
+ FileUtils.mkdir_p(workdir)
19
+ Dir[File.join(workdir, '*')].each { |f| FileUtils.rm_f f }
20
+ end
21
+
22
+ it 'needs no update when all files are missing' do
23
+ subject.needs_update?(jarfile, gemfile_lock).must_equal false
24
+ end
25
+
26
+ it 'needs update when only gemfile' do
27
+ FileUtils.touch gfile_lock
28
+ subject.needs_update?(jarfile, gemfile_lock).must_equal true
29
+ end
30
+
31
+ it 'needs update when only jarfile' do
32
+ FileUtils.touch jfile
33
+ subject.needs_update?(jarfile, gemfile_lock).must_equal true
34
+ end
35
+
36
+ it 'needs update when jarfilelock is missing' do
37
+ FileUtils.touch gfile_lock
38
+ FileUtils.touch jfile
39
+ FileUtils.touch cpfile
40
+ subject.needs_update?(jarfile, gemfile_lock).must_equal true
41
+ end
42
+
43
+ it 'needs no update when classpath file is the youngest' do
44
+ FileUtils.touch jfile
45
+ FileUtils.touch jfile_lock
46
+ FileUtils.touch cpfile
47
+ subject.needs_update?(jarfile, gemfile_lock).must_equal false
48
+ end
49
+
50
+ it 'needs update when jar file is the youngest' do
51
+ FileUtils.touch gfile_lock
52
+ FileUtils.touch jfile_lock
53
+ FileUtils.touch cpfile
54
+ sleep 1
55
+ FileUtils.touch jfile
56
+ subject.needs_update?(jarfile, gemfile_lock).must_equal true
57
+ end
58
+
59
+ it 'needs update when jar lockfile is the youngest' do
60
+ FileUtils.touch gfile_lock
61
+ FileUtils.touch jfile
62
+ FileUtils.touch cpfile
63
+ sleep 1
64
+ FileUtils.touch jfile_lock
65
+ subject.needs_update?(jarfile, gemfile_lock).must_equal true
66
+ end
67
+
68
+ it 'needs update when gem lockfile is the youngest' do
69
+ FileUtils.touch jfile
70
+ FileUtils.touch cpfile
71
+ FileUtils.touch jfile_lock
72
+ sleep 1
73
+ FileUtils.touch gfile_lock
74
+ subject.needs_update?(jarfile, gemfile_lock).must_equal true
75
+ end
76
+
77
+ it 'generates a classpath ruby file without localrepo' do
78
+ subject.generate("a:b:c:d:f:".split(File::PATH_SEPARATOR) )
79
+ File.read(cpfile).must_equal <<-EOF
80
+ JBUNDLER_JRUBY_CLASSPATH = []
81
+ JBUNDLER_JRUBY_CLASSPATH.freeze
82
+ JBUNDLER_TEST_CLASSPATH = []
83
+ JBUNDLER_TEST_CLASSPATH.freeze
84
+ JBUNDLER_CLASSPATH = []
85
+ JBUNDLER_CLASSPATH << 'a'
86
+ JBUNDLER_CLASSPATH << 'b'
87
+ JBUNDLER_CLASSPATH << 'c'
88
+ JBUNDLER_CLASSPATH << 'd'
89
+ JBUNDLER_CLASSPATH << 'f'
90
+ JBUNDLER_CLASSPATH.freeze
91
+ EOF
92
+ end
93
+
94
+ it 'generates a classpath ruby file with localrepo' do
95
+ subject.generate("a:b:c:d:f:".split(File::PATH_SEPARATOR), [], [], '/tmp')
96
+ File.read(cpfile).must_equal <<-EOF
97
+ require 'jar_dependencies'
98
+ JBUNDLER_LOCAL_REPO = Jars.home
99
+ JBUNDLER_JRUBY_CLASSPATH = []
100
+ JBUNDLER_JRUBY_CLASSPATH.freeze
101
+ JBUNDLER_TEST_CLASSPATH = []
102
+ JBUNDLER_TEST_CLASSPATH.freeze
103
+ JBUNDLER_CLASSPATH = []
104
+ JBUNDLER_CLASSPATH << (JBUNDLER_LOCAL_REPO + 'a')
105
+ JBUNDLER_CLASSPATH << (JBUNDLER_LOCAL_REPO + 'b')
106
+ JBUNDLER_CLASSPATH << (JBUNDLER_LOCAL_REPO + 'c')
107
+ JBUNDLER_CLASSPATH << (JBUNDLER_LOCAL_REPO + 'd')
108
+ JBUNDLER_CLASSPATH << (JBUNDLER_LOCAL_REPO + 'f')
109
+ JBUNDLER_CLASSPATH.freeze
110
+ EOF
111
+ end
112
+
113
+ it 'require classpath using default with generated localrepo' do
114
+ ENV[ 'JARS_HOME' ] = '/tmp'
115
+ Jars.reset
116
+ subject.generate("/a:/b:/c:/d:/f:".split(File::PATH_SEPARATOR), [], [], '/tmp')
117
+ begin
118
+ subject.require_classpath
119
+ rescue LoadError
120
+ # there are no files to require
121
+ end
122
+ JBUNDLER_CLASSPATH.must_equal ["/tmp/a", "/tmp/b", "/tmp/c", "/tmp/d", "/tmp/f"]
123
+ end
124
+
125
+ it 'require classpath with generated localrepo' do
126
+ ENV[ 'JARS_HOME' ] = '/tmp'
127
+ subject.generate("/a:/b:/c:/d:/f:".split(File::PATH_SEPARATOR), [], [], '/tmp')
128
+
129
+ begin
130
+ Jars.reset
131
+ ENV[ 'JARS_HOME' ] = '/temp'
132
+ subject.require_classpath
133
+ rescue LoadError
134
+ # there are no files to require
135
+ end
136
+ JBUNDLER_CLASSPATH.must_equal ["/temp/a", "/temp/b", "/temp/c", "/temp/d", "/temp/f"]
137
+ end
138
+ end