pangolin 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2009 Theo Hultberg
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,72 @@
1
+ = Pangolin
2
+
3
+ Ruby wrappers for javac and jar that don't just exec.
4
+
5
+ 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 with exec you have to wait for the JVM to start for each invocation. In combination with JRuby this gem lets you run +javac+ and +jar+ in your Rake scripts without exec'ing, by using the programmatic interface to Javac and Java's ZIP file creation capabilities.
6
+
7
+ == Example
8
+
9
+ require 'pangolin'
10
+
11
+
12
+ task :compile do
13
+ javac FileList['src/**/*.java'], :destination => 'build, :class_path => FileList['lib/*.jar']
14
+ end
15
+
16
+ task :dist => :compile do
17
+ jar 'dist/my-awsome-app.jar', FileList['build/**/*.class'], :base_dir => 'build'
18
+ end
19
+
20
+ task :test => :compile do
21
+ test_classes = FileList['build/**/Test*.class'].pathmap('%{build/,}X').gsub('/', '.')
22
+
23
+ junit test_classes, :class_path => FileList['build', 'lib/*.jar']
24
+ end
25
+
26
+ There are more examples in the +examples+ directory.
27
+
28
+ == Installation
29
+
30
+ The new way, from Gemcutter:
31
+
32
+ sudo jruby -S gem install pangolin
33
+
34
+ To add Gemcutter as a gem source, run these commands:
35
+
36
+ jruby -S gem install gemcutter
37
+ jruby -S gem tumble
38
+
39
+ To add GitHub as a gem source, run this command:
40
+
41
+ jruby -S gem sources -a http://gems.github.com
42
+
43
+ == Command style
44
+
45
+ Many Rake add-ons look like this:
46
+
47
+ Spec::Rake::SpecTask.new(:spec) do |spec|
48
+ spec.spec_opts << '--options' << 'spec/spec.opts'
49
+ # ...
50
+ end
51
+
52
+ I think it ruins the DSL illusion, and I prefer to write tasks that contain commands, more like how +cp+, +rm+ and +sh+ work in Rake.
53
+
54
+ == Nailgun
55
+
56
+ Don't forget that since JRuby 1.3 you can minimize the startup by using the built-in Nailgun support. Run
57
+
58
+ jruby --ng-server &
59
+
60
+ to start a Nailgun server and then run Rake with this command
61
+
62
+ jruby --ng -S rake
63
+
64
+ you'll notice that the startup time decreases significantly the second time you run it. To avoid having to write all that every time you want to build create an alias, I call mine +jrk+.
65
+
66
+ == Upcomming
67
+
68
+ Even though the whole rationale behind Pangolin is to avoid exec it wouldn't be much effort to support non-JRuby runtimes since at least the +javac+ command needs to build the command string anyway.
69
+
70
+ == Pangolin?
71
+
72
+ Pangolins eats ants for breakfast.
@@ -0,0 +1,40 @@
1
+ require 'rake/clean'
2
+
3
+
4
+ task :default => :prepare
5
+
6
+ task :prepare do
7
+ require 'open-uri'
8
+
9
+ junit_url = "http://downloads.sourceforge.net/project/junit/junit/4.7/junit-4.7.jar"
10
+ ext_dir = 'lib/pangolin/ext'
11
+ local_path = "#{ext_dir}/junit.jar"
12
+
13
+ unless File.exists?(local_path)
14
+ mkdir_p ext_dir
15
+
16
+ $stderr.print 'Downloading JUnit 4.7... '
17
+
18
+ File.open(local_path, 'w') do |f|
19
+ f.write(open(junit_url).read)
20
+ end
21
+
22
+ $stderr.puts 'done'
23
+ end
24
+ end
25
+
26
+ # This is a workaround for a silly bug in RubyGems on JRuby:
27
+ # when running a rakefile as part of an install the 2>&1 redirect ends
28
+ # ends up as an argument to Rake, and Rake complains, which makes the
29
+ # build fail. The workaround is to declare a task with this name.
30
+ task '2>&1' => :default
31
+
32
+
33
+ # Import all .rake-files in the tasks directory
34
+ Dir['tasks/*.rake'].each do |tasks_file|
35
+ begin
36
+ load tasks_file
37
+ rescue Exception => e
38
+ $stderr.puts e.message
39
+ end
40
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../lib/pangolin')
2
+
3
+ require 'rake/clean'
4
+
5
+
6
+ CLOBBER.include('build')
7
+
8
+
9
+ task :default => :compile
10
+
11
+ desc "Compile all classes"
12
+ task :compile => 'build' do
13
+ javac FileList['src/**/*.java'], :destination => 'build', :verbose => true
14
+ end
15
+
16
+ directory 'build'
@@ -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,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../lib/java_tools')
2
+
3
+ require 'rake/clean'
4
+
5
+
6
+ CLOBBER.include('build')
7
+ CLOBBER.include('dist')
8
+
9
+
10
+ task :default => :package
11
+
12
+ task :package => [:compile, 'dist'] do
13
+ jar 'dist/package.jar', FileList['build/**/*.class'], :base_dir => 'build',
14
+ :main_class => 'com.example.HelloWorld',
15
+ :manifest => {'X-Test', 'foo'},
16
+ :verbose => true
17
+ end
18
+
19
+ task :compile => 'build' do
20
+ javac FileList['src/**/*.java'], :destination => 'build', :verbose => true
21
+ end
22
+
23
+ directory 'build'
24
+ directory 'dist'
@@ -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,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../lib/java_tools')
2
+
3
+ require 'rake/clean'
4
+
5
+
6
+ CLOBBER.include('build')
7
+
8
+
9
+ task :default => :test
10
+
11
+ task :compile => 'build' do
12
+ javac FileList['{src,test}/**/*.java'], :destination => 'build',
13
+ :class_path => FileList['lib/*.jar'],
14
+ :verbose => true
15
+ end
16
+
17
+ task :test => :compile do
18
+ junit FileList['build/**/Test*.class'].pathmap('%{build/,}X').gsub('/', '.'), :class_path => ['build/'], :colorize => true
19
+ end
20
+
21
+ directory 'build'
@@ -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,31 @@
1
+ package com.example;
2
+
3
+
4
+ import org.junit.Before;
5
+ import org.junit.Test;
6
+
7
+ import static org.junit.Assert.assertNotNull;
8
+ import static org.junit.Assert.assertEquals;
9
+
10
+
11
+ public class TestHelloWorld {
12
+
13
+ private HelloWorld helloWorld;
14
+
15
+
16
+ @Before
17
+ public void setUp( ) {
18
+ helloWorld = new HelloWorld();
19
+ }
20
+
21
+ @Test
22
+ public void testTheObvious( ) {
23
+ assertNotNull(helloWorld);
24
+ }
25
+
26
+ @Test
27
+ public void testThatFails( ) {
28
+ assertEquals(1, 2);
29
+ }
30
+
31
+ }
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{java_tools}
8
+ s.version = "0.2.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Theo Hultberg"]
12
+ s.date = %q{2009-10-08}
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
+ s.email = %q{theo@iconara.net}
15
+ s.extensions = ["Rakefile"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "examples/compile/Rakefile",
26
+ "examples/compile/src/com/example/HelloWorld.java",
27
+ "examples/package/Rakefile",
28
+ "examples/package/src/com/example/HelloWorld.java",
29
+ "examples/test/Rakefile",
30
+ "examples/test/src/com/example/HelloWorld.java",
31
+ "examples/test/test/com/example/TestHelloWorld.java",
32
+ "java_tools.gemspec",
33
+ "lib/java_tools.rb",
34
+ "lib/java_tools/jar.rb",
35
+ "lib/java_tools/javac.rb",
36
+ "lib/java_tools/junit.rb",
37
+ "lib/java_tools/output/formatting.rb",
38
+ "spec/jar_cmd_spec.rb",
39
+ "spec/jar_spec.rb",
40
+ "spec/javac_cmd_spec.rb",
41
+ "spec/javac_spec.rb",
42
+ "spec/junit_cmd_spec.rb",
43
+ "spec/junit_spec.rb",
44
+ "spec/spec.opts",
45
+ "spec/spec_helper.rb",
46
+ "tasks/gem.rake",
47
+ "tasks/rdoc.rake",
48
+ "tasks/spec.rake"
49
+ ]
50
+ s.homepage = %q{http://github.com/iconara/java_tools}
51
+ s.rdoc_options = ["--charset=UTF-8"]
52
+ s.require_paths = ["lib"]
53
+ s.rubygems_version = %q{1.3.3}
54
+ s.summary = %q{Ruby wrappers for javac and jar that don't just exec}
55
+ s.test_files = [
56
+ "spec/jar_cmd_spec.rb",
57
+ "spec/jar_spec.rb",
58
+ "spec/javac_cmd_spec.rb",
59
+ "spec/javac_spec.rb",
60
+ "spec/junit_cmd_spec.rb",
61
+ "spec/junit_spec.rb",
62
+ "spec/spec_helper.rb"
63
+ ]
64
+
65
+ if s.respond_to? :specification_version then
66
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
67
+ s.specification_version = 3
68
+
69
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
70
+ else
71
+ end
72
+ else
73
+ end
74
+ end
@@ -0,0 +1,143 @@
1
+ raise "Pangolin requires JRuby" unless RUBY_PLATFORM =~ /\bjava\b/
2
+
3
+
4
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/output/formatting'
5
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/javac'
6
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/jar'
7
+ require File.expand_path(File.dirname(__FILE__)) + '/pangolin/junit'
8
+
9
+
10
+
11
+ module Pangolin # :nodoc:
12
+
13
+ def self.version # :nodoc:
14
+ version_file = File.join(File.dirname(__FILE__), '..', 'VERSION')
15
+
16
+ File.open(version_file) do |f|
17
+ f.readline.strip
18
+ end
19
+ end
20
+
21
+ def self.exec_command( obj, options, block )
22
+ if block
23
+ block.call(obj)
24
+ elsif options
25
+ configure_command(obj, options)
26
+ end
27
+
28
+ obj.execute or fail("Execution failed, see above")
29
+ end
30
+
31
+ def self.configure_command( command, options ) # :nodoc:
32
+ options.each do |option, value|
33
+ setter_name = "#{option}="
34
+
35
+ if command.respond_to? setter_name
36
+ command.send(setter_name, value)
37
+ else
38
+ raise ArgumentError, "Invalid option: #{option}"
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ class Exception # :nodoc:
46
+ alias exception_backtrace backtrace
47
+
48
+ # Elide JRuby backtraces to remove all the internal stuff
49
+ def backtrace
50
+ exception_backtrace.reject do |line|
51
+ line =~ /^(org\/jruby|com\/mysql|sun\/|java\/)/
52
+ end
53
+ end
54
+ end
55
+
56
+ # Javac can be run in either command or yield mode: command mode
57
+ # looks roughly like this:
58
+ #
59
+ # javac [file1, file2], :destination => 'build'
60
+ #
61
+ # and yield mode like this:
62
+ #
63
+ # javac(file1, file2) do |conf|
64
+ # conf.destination = 'build'
65
+ # end
66
+ #
67
+ # In command mode you pass a hash with the configuration directives
68
+ # (listed below) and in yield mode an object is passed to the block,
69
+ # and the configuration directives should be set on that.
70
+ #
71
+ # The possible configuration directives are:
72
+ # * +source_path+
73
+ # * +destination+
74
+ # * +class_path+
75
+ # * +deprecation_warnings+
76
+ # * +warnings+
77
+ # * +encoding+
78
+ # * +verbose+
79
+ #
80
+ # The directives are the same as the properties of Pangolin::Javac.
81
+ #
82
+ def javac( source_files, options = nil, &block )
83
+ Pangolin::exec_command(Pangolin::Javac.new(*source_files), options, block)
84
+ end
85
+
86
+ # Jar can be run in either command or yield mode: command mode
87
+ # looks roughly like this:
88
+ #
89
+ # jar 'output.jar', [file1, file2], :base_dir => 'build'
90
+ #
91
+ # and yield mode like this:
92
+ #
93
+ # jar('output.jar', [file1, file2]) do |conf|
94
+ # conf.base_dir = 'build'
95
+ # end
96
+ #
97
+ # In command mode you pass a hash with the configuration directives
98
+ # (listed below) and in yield mode an object is passed to the block,
99
+ # and the configuration directives should be set on that.
100
+ #
101
+ # The possible configuration directives are:
102
+ # * +base_dir+
103
+ # * +compression+
104
+ # * +verbose+
105
+ #
106
+ # The directives are the same as the properties of Pangolin::Jar.
107
+ #
108
+ def jar( output, files = nil, options = nil, &block )
109
+ base_dir = nil
110
+
111
+ if options && options[:base_dir]
112
+ base_dir = options[:base_dir]
113
+ end
114
+
115
+ Pangolin::exec_command(Pangolin::Jar.new(output, files, base_dir), options, block)
116
+ end
117
+
118
+ # Junit can be run in either command or yield mode: command mode
119
+ # looks roughly like this:
120
+ #
121
+ # junit ['TestFoo', 'TestBar'], :class_path => ['build']
122
+ #
123
+ # (where +TestFoo+ and +TestBar+ are classes available from the class path).
124
+ #
125
+ # Yield mode looks like this:
126
+ #
127
+ # junit ['TestFoo', 'TestBar'] do |conf|
128
+ # conf.class_path = ['build']
129
+ # end
130
+ #
131
+ # In command mode you pass a hash with the configuration directives
132
+ # (listed below) and in yield mode an object is passed to the block,
133
+ # and the configuration directives should be set on that.
134
+ #
135
+ # The possible configuration directives are:
136
+ # * +class_path+
137
+ # * +colorize+
138
+ #
139
+ # The directives are the same as the properties of Pangolin::Junit.
140
+ #
141
+ def junit( classes, options = nil, &block )
142
+ Pangolin::exec_command(Pangolin::Junit.new(*classes), options, block)
143
+ end