pangolin 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.4.0
@@ -12,7 +12,7 @@ task :default => :package
12
12
  task :package => [:compile, 'dist'] do
13
13
  jar 'dist/package.jar', FileList['build/**/*.class'], :base_dir => 'build',
14
14
  :main_class => 'com.example.HelloWorld',
15
- :manifest => {'X-Test', 'foo'},
15
+ :manifest => {'X-Test' => 'foo'},
16
16
  :verbose => true
17
17
  end
18
18
 
@@ -1,15 +1,3 @@
1
- raise "Pangolin requires JRuby" unless RUBY_PLATFORM =~ /\bjava\b/
2
-
3
- $stderr.puts "Warning: JAVA_HOME not set, this may cause problems" unless ENV['JAVA_HOME']
4
-
5
-
6
- require File.expand_path(File.dirname(__FILE__)) + '/pangolin/output/formatting'
7
- require File.expand_path(File.dirname(__FILE__)) + '/pangolin/javac'
8
- require File.expand_path(File.dirname(__FILE__)) + '/pangolin/jar'
9
- require File.expand_path(File.dirname(__FILE__)) + '/pangolin/junit'
10
-
11
-
12
-
13
1
  module Pangolin # :nodoc:
14
2
 
15
3
  def self.version # :nodoc:
@@ -42,17 +30,42 @@ module Pangolin # :nodoc:
42
30
  end
43
31
  end
44
32
 
33
+ def self.is_java?
34
+ defined?(JRUBY_VERSION)
35
+ end
36
+
45
37
  end
46
38
 
47
- class Exception # :nodoc:
48
- alias exception_backtrace backtrace
39
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/output/formatting'
40
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/common/jar_common'
41
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/common/javac_common'
42
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/common/junit_common'
43
+
44
+ if Pangolin::is_java?
45
+ $stderr.puts 'Warning: JAVA_HOME not set, this may cause problems' unless ENV['JAVA_HOME']
46
+
47
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/java/javac'
48
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/java/jar'
49
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/java/junit'
49
50
 
50
- # Elide JRuby backtraces to remove all the internal stuff
51
- def backtrace
52
- exception_backtrace.reject do |line|
53
- line =~ /^(org\/jruby|com\/mysql|sun\/|java\/)/
51
+ class Exception # :nodoc:
52
+ alias exception_backtrace backtrace
53
+
54
+ # Elide JRuby backtraces to remove all the internal stuff
55
+ def backtrace
56
+ exception_backtrace.reject do |line|
57
+ line =~ /^(org\/jruby|com\/mysql|sun\/|java\/)/
58
+ end
54
59
  end
55
60
  end
61
+ else
62
+ require 'rubygems'
63
+
64
+ gem 'rubyzip', '>= 0.9.1'
65
+
66
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/exec/javac'
67
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/exec/jar'
68
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/exec/junit'
56
69
  end
57
70
 
58
71
  # Javac can be run in either command or yield mode: command mode
@@ -1,15 +1,6 @@
1
- require 'java'
2
-
3
-
4
1
  module Pangolin
2
+ module JarCommon
5
3
 
6
- include_class 'java.io.FileOutputStream'
7
- include_class 'java.util.zip.ZipOutputStream'
8
- include_class 'java.util.zip.ZipEntry'
9
-
10
-
11
- class Jar
12
-
13
4
  # The path to the directory which should be considered the root of the archive.
14
5
  #
15
6
  # If you set +base_dir+ to "build" and add the file "build/Main.class", that file
@@ -24,7 +15,6 @@ module Pangolin
24
15
 
25
16
  # The path to the JAR file that will be generated
26
17
  attr_reader :output
27
-
28
18
 
29
19
  def initialize( output, files = nil, base_dir = nil )
30
20
  @output = output
@@ -37,7 +27,7 @@ module Pangolin
37
27
 
38
28
  add_files(files) unless files.nil? || files.empty?
39
29
  end
40
-
30
+
41
31
  # Sets the attributes that will end up in the JAR manifest.
42
32
  #
43
33
  # Attribute names are treated case insensitively, so setting
@@ -64,7 +54,7 @@ module Pangolin
64
54
  def remove_manifest_attribute( name ) # :nodoc:
65
55
  @manifest.delete_if do |key, value|
66
56
  key.downcase == name.downcase
67
- end
57
+ end
68
58
  end
69
59
 
70
60
  # Convenience method for setting the Main-Class manifest attribute
@@ -144,24 +134,6 @@ module Pangolin
144
134
  true
145
135
  end
146
136
 
147
- def create_zipfile # :nodoc:
148
- buffer_size = 65536
149
-
150
- zipstream = ZipOutputStream.new(FileOutputStream.new(@output))
151
-
152
- @entries.each do |path, io|
153
- while buffer = io.read(buffer_size)
154
- zipstream.put_next_entry(ZipEntry.new(path))
155
- zipstream.write(buffer.to_java_bytes, 0, buffer.length)
156
- zipstream.close_entry
157
- end
158
-
159
- io.close
160
- end
161
-
162
- zipstream.close
163
- end
164
-
165
137
  def find_archive_path( path, base_dir ) # :nodoc:
166
138
  if base_dir
167
139
  prefix = base_dir + (base_dir =~ /\/$/ ? '' : '/')
@@ -175,5 +147,4 @@ module Pangolin
175
147
  end
176
148
 
177
149
  end
178
-
179
150
  end
@@ -1,22 +1,9 @@
1
- require 'java'
2
-
3
-
4
1
  module Pangolin
5
2
 
6
- TOOLS_PATHS = [ ]
7
- TOOLS_PATHS << File.join(ENV['JAVA_HOME'], '..', 'lib', 'tools.jar') if ENV['JAVA_HOME']
8
- TOOLS_PATHS << File.join(ENV['JAVA_HOME'], 'lib', 'tools.jar') if ENV['JAVA_HOME']
9
-
10
- # must use include_class instead of import because import interferes with Rake's import
11
- include_class 'java.io.PrintWriter'
12
- include_class 'java.io.StringWriter'
13
-
14
-
15
- class Javac
3
+ module JavacCommon
16
4
 
17
- include Output::Formatting
5
+ include ::Pangolin::Output::Formatting
18
6
 
19
-
20
7
  # The files to compile.
21
8
  attr_accessor :source_files
22
9
 
@@ -80,27 +67,6 @@ module Pangolin
80
67
  @lint = [ ]
81
68
  @colorize = false
82
69
  end
83
-
84
- # Run javac. If #verbose is true the equivalent command string for
85
- # the +javac+ command will be printed to the stream passed as +io+ (or
86
- # +$stdout+ by default)
87
- def execute( io = $stderr )
88
- output_writer = StringWriter.new
89
-
90
- io.puts 'javac …' if @verbose
91
-
92
- result = execute_compiler(output_writer)
93
-
94
- output_str = output_writer.to_s
95
-
96
- io.puts format_output(output_str) if output_str !~ /^\s*$/
97
-
98
- if 0 == result
99
- true
100
- else
101
- false
102
- end
103
- end
104
70
 
105
71
  def command_args # :nodoc:
106
72
  args = [ ]
@@ -115,36 +81,21 @@ module Pangolin
115
81
  args + lint_flags + @source_files
116
82
  end
117
83
 
118
- private
84
+ # Run javac. If #verbose is true the equivalent command string for
85
+ # the +javac+ command will be printed to the stream passed as +io+ (or
86
+ # +$stdout+ by default)
87
+ def execute( io = $stderr )
88
+ raise 'No source files' if @source_files.nil? || @source_files.empty?
119
89
 
120
- def lint_flags
121
- @lint.map { |lint| '-Xlint:' + lint }
122
- end
90
+ io.puts 'javac …' if @verbose
123
91
 
124
- def execute_compiler(output_writer)
125
- compiler.compile(command_args.to_java(java.lang.String), PrintWriter.new(output_writer))
92
+ execute_compiler(io)
126
93
  end
127
-
128
- def compiler
129
- begin
130
- return com.sun.tools.javac.Main
131
- rescue NameError
132
- TOOLS_PATHS.each do |path|
133
- if File.exists? path
134
- require path
135
94
 
136
- begin
137
- return com.sun.tools.javac.Main
138
- rescue NameError
139
- # ignore and try next
140
- end
141
- end
142
- end
143
- end
144
-
145
- raise 'Could not find com.sun.tools.javac.Main, perhaps tools.jar isn\'t in the class path?'
95
+ def lint_flags
96
+ @lint.map { |lint| '-Xlint:' + lint }
146
97
  end
147
-
98
+
148
99
  def formatted_path(items)
149
100
  if items.respond_to? :join
150
101
  items.join(':')
@@ -152,7 +103,7 @@ module Pangolin
152
103
  items.to_s
153
104
  end
154
105
  end
155
-
106
+
156
107
  def format_output(output)
157
108
  output.split(/\n/).map do |line|
158
109
  case line
@@ -167,7 +118,6 @@ module Pangolin
167
118
  end
168
119
  end.join("\n")
169
120
  end
170
-
121
+
171
122
  end
172
-
173
123
  end
@@ -0,0 +1,61 @@
1
+ module Pangolin
2
+ module JunitCommon
3
+ include Output::Formatting
4
+
5
+ JUNIT_JAR_PATH = File.expand_path(File.dirname(__FILE__) + '/../ext/junit.jar')
6
+
7
+ attr_accessor :class_path
8
+ attr_accessor :colorize
9
+ attr_accessor :verbose
10
+
11
+ def initialize(*classes)
12
+ @class_names = classes || [ ]
13
+ @class_path = [ ]
14
+ @colorize = false
15
+ @verbose = false
16
+ end
17
+
18
+ def classes
19
+ @class_names
20
+ end
21
+
22
+ def print_header(io, num_tests, num_failures, time_taken)
23
+ if num_failures == 0
24
+ io.puts(format_header('%d tests run in %.1f seconds, no failures' % [num_tests, time_taken/1000]))
25
+ else
26
+ args = [
27
+ num_tests,
28
+ time_taken/1000,
29
+ num_failures,
30
+ num_failures == 1 ? '' : 's'
31
+ ]
32
+
33
+ io.puts(format_header('%d tests run in %.1f seconds with %d failure%s' % args))
34
+ io.puts('')
35
+ end
36
+ end
37
+
38
+ def print_failure(io, test_header, message, backtrace)
39
+ io.puts(format_error_header('- ' + test_header))
40
+ io.puts(format_error(' ' + message)) unless message.nil? || message =~ /^\s*$/
41
+
42
+ filtered_stack_trace_array(backtrace).each do |trace_frame|
43
+ io.puts(format_stack_trace(' ' + trace_frame.strip))
44
+ end
45
+
46
+ io.puts('')
47
+ end
48
+
49
+ def filtered_stack_trace_array(trace)
50
+ trace.split("\n").reject do |line|
51
+ case line
52
+ when /java.lang.AssertionError/, /at org.junit/, /at sun.reflect/, /at java.lang.reflect/, /at org.jruby/, /jrake/
53
+ true
54
+ else
55
+ false
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,18 @@
1
+ require 'zip/zip'
2
+
3
+ module Pangolin
4
+ class Jar
5
+ include JarCommon
6
+ include Zip
7
+
8
+ def create_zipfile # :nodoc:
9
+ ZipFile.open(@output, ZipFile::CREATE) do |zipfile|
10
+ @entries.each do |path, io|
11
+ zipfile.get_output_stream(path) do |f|
12
+ f.write(io.read)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module Pangolin
2
+ class Javac
3
+ include JavacCommon
4
+
5
+ def execute_compiler(io)
6
+ output = %x(javac #{command_args.join(' ')} 2>&1)
7
+
8
+ io.puts(format_output(output))
9
+
10
+ $?.success?
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ module Pangolin
2
+ class Junit
3
+ include JunitCommon
4
+
5
+ def execute(io=$stderr)
6
+ raise 'No tests' if @class_names.nil? || @class_names.empty?
7
+
8
+ class_path_str = (@class_path + [JUNIT_JAR_PATH]).join(':')
9
+ test_classes = @class_names.join(' ')
10
+
11
+ output = %x(java -classpath #{class_path_str} org.junit.runner.JUnitCore #{test_classes} 2>&1)
12
+
13
+ print_result(io, output)
14
+
15
+ $?.success?
16
+ end
17
+
18
+ def print_result(io, output)
19
+ num_tests, num_failures, time_taken = 0, 0, 0
20
+
21
+ if output =~ /Time: (\d+\.\d+)/.match(output)
22
+ time_taken = ($1.to_f * 1000).to_i
23
+ end
24
+
25
+ if output =~ /There was (\d+) failure/
26
+ num_failures = $1.to_i
27
+ end
28
+
29
+ if output =~ /Tests run: (\d+)/
30
+ num_tests = $1.to_i
31
+ end
32
+
33
+ print_header(io, num_tests, num_failures, time_taken)
34
+
35
+ output.scan(/\d+\) (\w+\([^\)]+\))\n(.+?)\n(.+?)\n\n/m) do |match|
36
+ print_failure(io, match[0], match[1], match[2])
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ require 'java'
2
+
3
+
4
+ module Pangolin
5
+
6
+ include_class 'java.io.FileOutputStream'
7
+ include_class 'java.util.zip.ZipOutputStream'
8
+ include_class 'java.util.zip.ZipEntry'
9
+
10
+ class Jar
11
+ include JarCommon
12
+
13
+ def create_zipfile # :nodoc:
14
+ buffer_size = 65536
15
+
16
+ zipstream = ZipOutputStream.new(FileOutputStream.new(@output))
17
+
18
+ @entries.each do |path, io|
19
+ while buffer = io.read(buffer_size)
20
+ zipstream.put_next_entry(ZipEntry.new(path))
21
+ zipstream.write(buffer.to_java_bytes, 0, buffer.length)
22
+ zipstream.close_entry
23
+ end
24
+
25
+ io.close
26
+ end
27
+
28
+ zipstream.close
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,53 @@
1
+ require 'java'
2
+
3
+
4
+ module Pangolin
5
+
6
+ TOOLS_PATHS = [ ]
7
+ TOOLS_PATHS << File.join(ENV['JAVA_HOME'], '..', 'lib', 'tools.jar') if ENV['JAVA_HOME']
8
+ TOOLS_PATHS << File.join(ENV['JAVA_HOME'], 'lib', 'tools.jar') if ENV['JAVA_HOME']
9
+
10
+ # must use include_class instead of import because import interferes with Rake's import
11
+ include_class 'java.io.PrintWriter'
12
+ include_class 'java.io.StringWriter'
13
+
14
+
15
+ class Javac
16
+
17
+ include JavacCommon
18
+
19
+ def execute_compiler(io)
20
+ output_writer = StringWriter.new
21
+
22
+ status = compiler.compile(command_args.to_java(java.lang.String), PrintWriter.new(output_writer))
23
+
24
+ io.print(format_output(output_writer.to_s))
25
+
26
+ 0 == status
27
+ end
28
+
29
+ private
30
+
31
+ def compiler
32
+ begin
33
+ return com.sun.tools.javac.Main
34
+ rescue NameError
35
+ TOOLS_PATHS.each do |path|
36
+ if File.exists? path
37
+ require path
38
+
39
+ begin
40
+ return com.sun.tools.javac.Main
41
+ rescue NameError
42
+ # ignore and try next
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ raise 'Could not find com.sun.tools.javac.Main, perhaps tools.jar isn\'t in the class path?'
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,73 @@
1
+ include_class 'java.lang.ClassLoader'
2
+ include_class 'java.lang.ClassNotFoundException'
3
+ include_class 'java.net.URLClassLoader'
4
+ include_class 'java.net.URL'
5
+
6
+
7
+ module Pangolin
8
+
9
+ class Junit
10
+
11
+ include JunitCommon
12
+
13
+ require JUNIT_JAR_PATH
14
+
15
+ def execute(io=$stderr)
16
+ raise 'No tests' if @class_names.nil? || @class_names.empty?
17
+
18
+ io.puts 'junit …' if @verbose
19
+
20
+ junit = load_class('org.junit.runner.JUnitCore').new_instance
21
+ result = junit.run(class_instances)
22
+
23
+ print_result(io, result)
24
+
25
+ 0 == result.failure_count
26
+ end
27
+
28
+ private
29
+
30
+ def print_result(io, result)
31
+ print_header(io, result.run_count, result.failure_count, result.run_time)
32
+
33
+ unless result.was_successful
34
+ result.failures.each do |failure|
35
+ print_failure(io, failure.test_header, failure.message, failure.trace)
36
+ end
37
+ end
38
+ end
39
+
40
+ def full_class_path
41
+ @class_path + [JUNIT_JAR_PATH]
42
+ end
43
+
44
+ def pretty_class_path
45
+ full_class_path.join(':')
46
+ end
47
+
48
+ def class_path_urls
49
+ full_class_path.map do |e|
50
+ full_path = File.expand_path(e)
51
+ full_path += '/' if File.directory?(full_path) && full_path[-1] != '/'
52
+
53
+ URL.new('file', 'localhost', full_path)
54
+ end
55
+ end
56
+
57
+ def class_loader
58
+ @class_loader ||= URLClassLoader.new(class_path_urls.to_java(URL), ClassLoader.system_class_loader)
59
+ end
60
+
61
+ def class_instances
62
+ @class_names.map { |class_name| load_class(class_name) }.to_java(java.lang.Class)
63
+ end
64
+
65
+ def load_class(class_name)
66
+ class_loader.load_class(class_name)
67
+ rescue ClassNotFoundException => e
68
+ raise LoadError, "Class not found: #{class_name} (looking in #{pretty_class_path})"
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{pangolin}
8
- s.version = "0.3.3"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Theo Hultberg"]
12
- s.date = %q{2009-11-06}
12
+ s.date = %q{2009-12-07}
13
13
  s.description = %q{Ant is a nice tool for writing Java build scripts, but Rake is nicer. The only thing missing from Rake is a way to run javac and jar, and although it's easy to run these as shell scripts you have to wait for the JVM to start. In combination with JRuby this gem lets you run javac and jar in your Rake scripts without exec'ing.}
14
14
  s.email = %q{theo@iconara.net}
15
15
  s.extensions = ["Rakefile"]
@@ -32,11 +32,25 @@ Gem::Specification.new do |s|
32
32
  "examples/test/src/com/example/HelloWorld.java",
33
33
  "examples/test/test/com/example/TestHelloWorld.java",
34
34
  "lib/pangolin.rb",
35
- "lib/pangolin/jar.rb",
36
- "lib/pangolin/javac.rb",
37
- "lib/pangolin/junit.rb",
35
+ "lib/pangolin/common/jar_common.rb",
36
+ "lib/pangolin/common/javac_common.rb",
37
+ "lib/pangolin/common/junit_common.rb",
38
+ "lib/pangolin/exec/jar.rb",
39
+ "lib/pangolin/exec/javac.rb",
40
+ "lib/pangolin/exec/junit.rb",
41
+ "lib/pangolin/java/jar.rb",
42
+ "lib/pangolin/java/javac.rb",
43
+ "lib/pangolin/java/junit.rb",
38
44
  "lib/pangolin/output/formatting.rb",
39
45
  "pangolin.gemspec",
46
+ "spec/integration/data/classes/com/example/HelloWorld.class",
47
+ "spec/integration/data/sources/com/example/Error.java",
48
+ "spec/integration/data/sources/com/example/HelloWorld.java",
49
+ "spec/integration/data/tests/com/example/HelloWorld.class",
50
+ "spec/integration/data/tests/com/example/TestHelloWorld.class",
51
+ "spec/integration/jar_intg_spec.rb",
52
+ "spec/integration/javac_intg_spec.rb",
53
+ "spec/integration/junit_intg_spec.rb",
40
54
  "spec/jar_cmd_spec.rb",
41
55
  "spec/jar_spec.rb",
42
56
  "spec/javac_cmd_spec.rb",
@@ -52,10 +66,13 @@ Gem::Specification.new do |s|
52
66
  s.homepage = %q{http://github.com/iconara/pangolin}
53
67
  s.rdoc_options = ["--charset=UTF-8"]
54
68
  s.require_paths = ["lib"]
55
- s.rubygems_version = %q{1.3.3}
69
+ s.rubygems_version = %q{1.3.5}
56
70
  s.summary = %q{Ruby wrappers for javac and jar that don't just exec}
57
71
  s.test_files = [
58
- "spec/jar_cmd_spec.rb",
72
+ "spec/integration/jar_intg_spec.rb",
73
+ "spec/integration/javac_intg_spec.rb",
74
+ "spec/integration/junit_intg_spec.rb",
75
+ "spec/jar_cmd_spec.rb",
59
76
  "spec/jar_spec.rb",
60
77
  "spec/javac_cmd_spec.rb",
61
78
  "spec/javac_spec.rb",
@@ -69,8 +86,15 @@ Gem::Specification.new do |s|
69
86
  s.specification_version = 3
70
87
 
71
88
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
89
+ s.add_runtime_dependency(%q<rubyzip>, [">= 0.9.1"])
90
+ s.add_development_dependency(%q<rspec>, [">= 0"])
72
91
  else
92
+ s.add_dependency(%q<rubyzip>, [">= 0.9.1"])
93
+ s.add_dependency(%q<rspec>, [">= 0"])
73
94
  end
74
95
  else
96
+ s.add_dependency(%q<rubyzip>, [">= 0.9.1"])
97
+ s.add_dependency(%q<rspec>, [">= 0"])
75
98
  end
76
99
  end
100
+
@@ -0,0 +1,10 @@
1
+ package com.example;
2
+
3
+
4
+ public class Error {
5
+
6
+ public static void main( String[] args ) {
7
+ plink;
8
+ }
9
+
10
+ }
@@ -0,0 +1,10 @@
1
+ package com.example;
2
+
3
+
4
+ public class HelloWorld {
5
+
6
+ public static void main( String[] args ) {
7
+ System.out.println("Hello world");
8
+ }
9
+
10
+ }
@@ -0,0 +1,67 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+ require 'digest/md5'
4
+
5
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
6
+
7
+
8
+ describe Jar do
9
+
10
+ context 'a created jar file' do
11
+ before do
12
+ @output_dir = File.join(Dir.tmpdir, "jar_spec_#{rand(1_000_000)}")
13
+ @output_file = File.join(@output_dir, 'package.jar')
14
+ @base_dir = File.dirname(__FILE__) + '/data/classes'
15
+ @files = Dir["#{@base_dir}/**/*.class"]
16
+ @jar = Jar.new(@output_file, @files, @base_dir)
17
+ @jar.manifest = {'Hello' => 'World', 'Foo' => 'Bar'}
18
+
19
+ Dir.mkdir(@output_dir)
20
+
21
+ @jar.execute
22
+ end
23
+
24
+ after do
25
+ FileUtils.rm_rf(@output_dir)
26
+ end
27
+
28
+ context 'unpacked' do
29
+ before do
30
+ %x(cd #{@output_dir} && jar -xf #{@output_file})
31
+ end
32
+
33
+ it 'can be unpacked' do
34
+ Dir[@output_dir + '/**/*.class'].should_not be_empty
35
+ end
36
+
37
+ it 'contains a manifest with all attributes' do
38
+ manifest = File.read(File.join(@output_dir, 'META-INF', 'MANIFEST.MF'))
39
+ manifest.should include('Hello: World')
40
+ manifest.should include('Foo: Bar')
41
+ end
42
+
43
+ it 'contains the same files' do
44
+ @original = @base_dir + '/com/example/HelloWorld.class'
45
+ @extracted = @output_dir + '/com/example/HelloWorld.class'
46
+
47
+ @original_digest = Digest::MD5.hexdigest(File.read(@original))
48
+ @extracted_digest = Digest::MD5.hexdigest(File.read(@extracted))
49
+
50
+ @original_digest.should == @extracted_digest
51
+ end
52
+ end
53
+
54
+ context 'table of contents' do
55
+ it 'contains all files' do
56
+ file_listing = %x(jar -tf #{@output_file})
57
+ file_listing.should include('com/example/HelloWorld.class')
58
+ end
59
+
60
+ it 'contains a manifest' do
61
+ file_listing = %x(jar -tf #{@output_file})
62
+ file_listing.should include('META-INF/MANIFEST.MF')
63
+ end
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,49 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+
4
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
5
+
6
+
7
+ describe Javac do
8
+
9
+ before do
10
+ @output_dir = File.join(Dir.tmpdir, "javac_intg_spec_#{rand(1_000_000)}")
11
+ @base_dir = File.dirname(__FILE__) + '/data/sources'
12
+
13
+ @javac = Javac.new
14
+ @javac.destination = @output_dir
15
+
16
+ Dir.mkdir(@output_dir)
17
+ end
18
+
19
+ after do
20
+ FileUtils.rm_rf(@output_dir)
21
+ end
22
+
23
+ context 'compile class' do
24
+ before do
25
+ @javac.source_files = Dir["#{@base_dir}/**/HelloWorld.java"]
26
+ @javac.execute
27
+ end
28
+
29
+ it 'is runnable' do
30
+ output = %x(cd #{@output_dir} && java com.example.HelloWorld)
31
+ output.should == "Hello world\n"
32
+ end
33
+ end
34
+
35
+ context 'compile class with syntax errors' do
36
+ before do
37
+ @javac.source_files = Dir["#{@base_dir}/**/Error.java"]
38
+ end
39
+
40
+ it 'prints errors' do
41
+ io = StringIO.new
42
+
43
+ @javac.execute(io)
44
+
45
+ io.string.should include("com/example/Error.java:7")
46
+ io.string.should include("not a statement")
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+
4
+ describe Junit do
5
+
6
+ before do
7
+ @junit = Junit.new('com.example.TestHelloWorld')
8
+ @junit.class_path = [File.dirname(__FILE__) + '/data/tests']
9
+ end
10
+
11
+ it 'runs the tests' do
12
+ io = StringIO.new
13
+
14
+ @junit.execute(io)
15
+
16
+ io.string.should include('2 tests run')
17
+ io.string.should include('1 failure')
18
+ end
19
+
20
+ end
@@ -126,11 +126,11 @@ describe Jar do
126
126
  }.should_not raise_error
127
127
  end
128
128
 
129
- it "should ignore case when setting attributes" do
130
- @jar.manifest = {'Hello' => 'World', 'hello' => 'Theo'}
129
+ it "should ignore case when removing attributes" do
130
+ @jar.manifest = {'Hello' => 'World'}
131
+ @jar.remove_manifest_attribute('hello')
131
132
 
132
- @jar.manifest_string.include?('Hello: World').should be_false
133
- @jar.manifest_string.include?('hello: Theo').should be_true
133
+ @jar.manifest_string.include?('Hello:').should be_false
134
134
  end
135
135
 
136
136
  end
@@ -1,3 +1,6 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
1
4
  describe Javac do
2
5
 
3
6
  before(:each) do
@@ -199,5 +202,21 @@ describe Javac do
199
202
  end
200
203
 
201
204
  end
205
+
206
+ describe '#execute' do
207
+ before do
208
+ @javac.stub!(:execute_compiler).and_return(1)
209
+ end
210
+
211
+ it 'raises an exception if there are no source files' do
212
+ @javac.source_files = [ ]
213
+
214
+ lambda { @javac.execute }.should raise_error
215
+
216
+ @javac.source_files = nil
217
+
218
+ lambda { @javac.execute }.should raise_error
219
+ end
220
+ end
202
221
 
203
222
  end
@@ -1,3 +1,6 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
1
4
  describe Junit do
2
5
 
3
6
  describe 'defaults' do
@@ -21,4 +24,10 @@ describe Junit do
21
24
 
22
25
  end
23
26
 
27
+ describe '#execute' do
28
+ it 'raises an exception if there are no tests to run' do
29
+ lambda { @junit.execute }.should raise_error
30
+ end
31
+ end
32
+
24
33
  end
@@ -1,3 +1,3 @@
1
1
  --color
2
- --require spec/spec_helper
3
- --format specdoc
2
+ --format specdoc
3
+ --backtrace
@@ -1 +1,3 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/pangolin')
2
+
1
3
  include Pangolin
@@ -4,18 +4,21 @@ begin
4
4
  CLEAN.include('pkg')
5
5
 
6
6
  Jeweler::Tasks.new do |gemspec|
7
- gemspec.name = "pangolin"
8
- gemspec.summary = "Ruby wrappers for javac and jar that don't just exec"
9
- gemspec.description = "Ant is a nice tool for writing Java build scripts, but Rake is nicer. The only thing missing from Rake is a way to run javac and jar, and although it's easy to run these as shell scripts you have to wait for the JVM to start. In combination with JRuby this gem lets you run javac and jar in your Rake scripts without exec'ing."
10
- gemspec.email = "theo@iconara.net"
11
- gemspec.homepage = "http://github.com/iconara/pangolin"
12
- gemspec.authors = ["Theo Hultberg"]
13
- gemspec.extensions = 'Rakefile'
14
- gemspec.files.exclude '**/.gitignore'
15
- #gemspec.platform = 'java'
7
+ gemspec.name = 'pangolin'
8
+ gemspec.summary = 'Ruby wrappers for javac and jar that don\'t just exec'
9
+ gemspec.description = 'Ant is a nice tool for writing Java build scripts, but Rake is nicer. The only thing missing from Rake is a way to run javac and jar, and although it\'s easy to run these as shell scripts you have to wait for the JVM to start. In combination with JRuby this gem lets you run javac and jar in your Rake scripts without exec\'ing.'
10
+ gemspec.email = 'theo@iconara.net'
11
+ gemspec.homepage = 'http://github.com/iconara/pangolin'
12
+ gemspec.authors = ['Theo Hultberg']
13
+ gemspec.extensions = 'Rakefile'
14
+ gemspec.files.exclude '**/.gitignore'
15
+
16
+ gemspec.add_dependency 'rubyzip', '>= 0.9.1'
17
+
18
+ gemspec.add_development_dependency 'rspec'
16
19
  end
17
20
 
18
21
  Jeweler::GemcutterTasks.new
19
22
  rescue LoadError
20
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
21
24
  end
@@ -3,7 +3,12 @@ require 'spec/rake/spectask'
3
3
 
4
4
  Spec::Rake::SpecTask.new(:spec) do |spec|
5
5
  spec.spec_opts << '--options' << 'spec/spec.opts'
6
- spec.libs << 'lib'
7
6
  spec.ruby_opts << '-rpangolin'
8
- # spec.warning = true
7
+ spec.pattern = 'spec/*_spec.rb'
8
+ end
9
+
10
+ Spec::Rake::SpecTask.new(:intg_spec) do |spec|
11
+ spec.spec_opts << '--options' << 'spec/spec.opts'
12
+ spec.ruby_opts << '-rpangolin'
13
+ spec.pattern = 'spec/integration/*_spec.rb'
9
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pangolin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theo Hultberg
@@ -9,10 +9,29 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-06 00:00:00 +01:00
12
+ date: 2009-12-07 00:00:00 +01:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rubyzip
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.9.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
16
35
  description: Ant is a nice tool for writing Java build scripts, but Rake is nicer. The only thing missing from Rake is a way to run javac and jar, and although it's easy to run these as shell scripts you have to wait for the JVM to start. In combination with JRuby this gem lets you run javac and jar in your Rake scripts without exec'ing.
17
36
  email: theo@iconara.net
18
37
  executables: []
@@ -37,11 +56,25 @@ files:
37
56
  - examples/test/src/com/example/HelloWorld.java
38
57
  - examples/test/test/com/example/TestHelloWorld.java
39
58
  - lib/pangolin.rb
40
- - lib/pangolin/jar.rb
41
- - lib/pangolin/javac.rb
42
- - lib/pangolin/junit.rb
59
+ - lib/pangolin/common/jar_common.rb
60
+ - lib/pangolin/common/javac_common.rb
61
+ - lib/pangolin/common/junit_common.rb
62
+ - lib/pangolin/exec/jar.rb
63
+ - lib/pangolin/exec/javac.rb
64
+ - lib/pangolin/exec/junit.rb
65
+ - lib/pangolin/java/jar.rb
66
+ - lib/pangolin/java/javac.rb
67
+ - lib/pangolin/java/junit.rb
43
68
  - lib/pangolin/output/formatting.rb
44
69
  - pangolin.gemspec
70
+ - spec/integration/data/classes/com/example/HelloWorld.class
71
+ - spec/integration/data/sources/com/example/Error.java
72
+ - spec/integration/data/sources/com/example/HelloWorld.java
73
+ - spec/integration/data/tests/com/example/HelloWorld.class
74
+ - spec/integration/data/tests/com/example/TestHelloWorld.class
75
+ - spec/integration/jar_intg_spec.rb
76
+ - spec/integration/javac_intg_spec.rb
77
+ - spec/integration/junit_intg_spec.rb
45
78
  - spec/jar_cmd_spec.rb
46
79
  - spec/jar_spec.rb
47
80
  - spec/javac_cmd_spec.rb
@@ -77,11 +110,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
110
  requirements: []
78
111
 
79
112
  rubyforge_project:
80
- rubygems_version: 1.3.3
113
+ rubygems_version: 1.3.5
81
114
  signing_key:
82
115
  specification_version: 3
83
116
  summary: Ruby wrappers for javac and jar that don't just exec
84
117
  test_files:
118
+ - spec/integration/jar_intg_spec.rb
119
+ - spec/integration/javac_intg_spec.rb
120
+ - spec/integration/junit_intg_spec.rb
85
121
  - spec/jar_cmd_spec.rb
86
122
  - spec/jar_spec.rb
87
123
  - spec/javac_cmd_spec.rb
@@ -1,120 +0,0 @@
1
- JUNIT_JAR_PATH = File.dirname(__FILE__) + '/ext/junit.jar'
2
-
3
-
4
- require JUNIT_JAR_PATH
5
-
6
-
7
- include_class 'java.lang.ClassLoader'
8
- include_class 'java.lang.ClassNotFoundException'
9
- include_class 'java.net.URLClassLoader'
10
- include_class 'java.net.URL'
11
-
12
-
13
- module Pangolin
14
-
15
- class Junit
16
-
17
- include Output::Formatting
18
-
19
-
20
- attr_accessor :class_path
21
- attr_accessor :colorize
22
- attr_accessor :verbose
23
-
24
-
25
- def initialize(*classes)
26
- @class_names = classes || [ ]
27
- @class_path = [ ]
28
- @colorize = false
29
- @verbose = false
30
- end
31
-
32
- def classes
33
- @class_names
34
- end
35
-
36
- def execute(io=$stderr)
37
- io.puts 'junit …' if @verbose
38
-
39
- junit = load_class('org.junit.runner.JUnitCore').new_instance
40
- result = junit.run(class_instances)
41
-
42
- print_result(result)
43
-
44
- 0 == result.failure_count
45
- end
46
-
47
- private
48
-
49
- def print_result(result)
50
- if result.was_successful
51
- puts format_header('%d tests run in %.1f seconds, no failures' % [result.run_count, result.run_time/1000])
52
- else
53
- args = [
54
- result.run_count,
55
- result.run_time/1000,
56
- result.failure_count,
57
- result.failure_count == 1 ? '' : 's'
58
- ]
59
-
60
- puts format_header('%d tests run in %.1f seconds with %d failure%s' % args)
61
- puts ''
62
-
63
- result.failures.each do |failure|
64
- puts format_error_header('- ' + failure.test_header)
65
- puts format_error(' ' + failure.message) unless failure.message.nil? || failure.message =~ /^\s*$/
66
-
67
- filtered_stack_trace_array(failure.trace).each do |trace_frame|
68
- puts format_stack_trace(' ' + trace_frame.strip)
69
- end
70
-
71
- puts '' #unless failure == result.failures.to_a.last
72
- end
73
- end
74
- end
75
-
76
- def filtered_stack_trace_array(trace)
77
- trace.split("\n").reject do |line|
78
- case line
79
- when /java.lang.AssertionError/, /at org.junit/, /at sun.reflect/, /at java.lang.reflect/, /at org.jruby/, /jrake/
80
- true
81
- else
82
- false
83
- end
84
- end
85
- end
86
-
87
- def full_class_path
88
- @class_path + [JUNIT_JAR_PATH]
89
- end
90
-
91
- def pretty_class_path
92
- full_class_path.join(':')
93
- end
94
-
95
- def class_path_urls
96
- full_class_path.map do |e|
97
- full_path = File.expand_path(e)
98
- full_path += '/' if File.directory?(full_path) && full_path[-1] != '/'
99
-
100
- URL.new('file', 'localhost', full_path)
101
- end
102
- end
103
-
104
- def class_loader
105
- @class_loader ||= URLClassLoader.new(class_path_urls.to_java(URL), ClassLoader.system_class_loader)
106
- end
107
-
108
- def class_instances
109
- @class_names.map { |class_name| load_class(class_name) }.to_java(java.lang.Class)
110
- end
111
-
112
- def load_class(class_name)
113
- class_loader.load_class(class_name)
114
- rescue ClassNotFoundException => e
115
- raise LoadError, "Class not found: #{class_name} (looking in #{pretty_class_path})"
116
- end
117
-
118
- end
119
-
120
- end