warbler 1.2.1 → 1.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Gemfile +8 -5
  2. data/History.txt +5 -0
  3. data/Manifest.txt +43 -23
  4. data/README.txt +67 -26
  5. data/Rakefile +17 -6
  6. data/ext/JarMain.java +147 -0
  7. data/ext/{Main.java → WarMain.java} +4 -4
  8. data/ext/{WarblerWar.java → WarblerJar.java} +79 -13
  9. data/ext/{WarblerWarService.java → WarblerJarService.java} +2 -2
  10. data/lib/warbler/application.rb +9 -9
  11. data/lib/warbler/config.rb +58 -204
  12. data/lib/warbler/gems.rb +2 -2
  13. data/lib/warbler/jar.rb +247 -0
  14. data/lib/warbler/task.rb +28 -60
  15. data/lib/warbler/templates/config.erb +1 -1
  16. data/lib/warbler/templates/rack.erb +1 -1
  17. data/lib/warbler/templates/rails.erb +1 -1
  18. data/lib/warbler/traits/bundler.rb +58 -0
  19. data/lib/warbler/traits/gemspec.rb +64 -0
  20. data/lib/warbler/traits/jar.rb +53 -0
  21. data/lib/warbler/traits/merb.rb +34 -0
  22. data/lib/warbler/traits/nogemspec.rb +41 -0
  23. data/lib/warbler/traits/rack.rb +31 -0
  24. data/lib/warbler/traits/rails.rb +57 -0
  25. data/lib/warbler/traits/war.rb +191 -0
  26. data/lib/warbler/traits.rb +105 -0
  27. data/lib/warbler/version.rb +1 -1
  28. data/lib/warbler/war.rb +1 -247
  29. data/lib/warbler.rb +2 -5
  30. data/lib/warbler_jar.jar +0 -0
  31. data/spec/sample_jar/History.txt +6 -0
  32. data/spec/sample_jar/Manifest.txt +8 -0
  33. data/spec/sample_jar/README.txt +30 -0
  34. data/spec/sample_jar/lib/sample_jar.rb +6 -0
  35. data/spec/sample_jar/sample_jar.gemspec +41 -0
  36. data/spec/sample_jar/test/test_sample_jar.rb +8 -0
  37. data/spec/{sample → sample_war}/app/controllers/application.rb +0 -0
  38. data/spec/{sample → sample_war}/app/helpers/application_helper.rb +0 -0
  39. data/spec/{sample → sample_war}/config/boot.rb +0 -0
  40. data/spec/{sample → sample_war}/config/database.yml +0 -0
  41. data/spec/{sample → sample_war}/config/environment.rb +0 -0
  42. data/spec/{sample → sample_war}/config/environments/development.rb +0 -0
  43. data/spec/{sample → sample_war}/config/environments/production.rb +0 -0
  44. data/spec/{sample → sample_war}/config/environments/test.rb +0 -0
  45. data/spec/{sample → sample_war}/config/initializers/inflections.rb +0 -0
  46. data/spec/{sample → sample_war}/config/initializers/mime_types.rb +0 -0
  47. data/spec/{sample → sample_war}/config/initializers/new_rails_defaults.rb +0 -0
  48. data/spec/{sample → sample_war}/config/routes.rb +0 -0
  49. data/spec/{sample → sample_war}/lib/tasks/utils.rake +0 -0
  50. data/spec/{sample → sample_war}/public/404.html +0 -0
  51. data/spec/{sample → sample_war}/public/422.html +0 -0
  52. data/spec/{sample → sample_war}/public/500.html +0 -0
  53. data/spec/{sample → sample_war}/public/favicon.ico +0 -0
  54. data/spec/{sample → sample_war}/public/index.html +0 -0
  55. data/spec/{sample → sample_war}/public/robots.txt +0 -0
  56. data/spec/spec_helper.rb +40 -0
  57. data/spec/warbler/application_spec.rb +2 -9
  58. data/spec/warbler/config_spec.rb +101 -83
  59. data/spec/warbler/jar_spec.rb +763 -0
  60. data/spec/warbler/task_spec.rb +56 -41
  61. data/spec/warbler/traits_spec.rb +16 -0
  62. data/spec/warbler/war_spec.rb +2 -492
  63. data/warble.rb +36 -32
  64. metadata +57 -35
  65. data/lib/warbler_war.jar +0 -0
data/lib/warbler/task.rb CHANGED
@@ -7,8 +7,8 @@
7
7
 
8
8
  require 'rake'
9
9
  require 'rake/tasklib'
10
- require 'stringio'
11
- require 'zip/zip'
10
+ require 'warbler/config'
11
+ require 'warbler/jar'
12
12
 
13
13
  module Warbler
14
14
  # Warbler Rake task. Allows defining multiple configurations inside the same
@@ -18,11 +18,11 @@ module Warbler
18
18
  # code like the following in a Rakefile:
19
19
  #
20
20
  # Warbler::Task.new("war1", Warbler::Config.new do |config|
21
- # config.war_name = "war1"
21
+ # config.jar_name = "war1"
22
22
  # # ...
23
23
  # end
24
24
  # Warbler::Task.new("war2", Warbler::Config.new do |config|
25
- # config.war_name = "war2"
25
+ # config.jar_name = "war2"
26
26
  # # ...
27
27
  # end
28
28
  #
@@ -35,11 +35,10 @@ module Warbler
35
35
  # Warbler::Config
36
36
  attr_accessor :config
37
37
 
38
- # Warbler::War
39
- attr_accessor :war
38
+ # Warbler::Jar
39
+ attr_accessor :jar
40
40
 
41
- def initialize(name = :war, config = nil)
42
- @name = name
41
+ def initialize(name = nil, config = nil)
43
42
  @config = config
44
43
  if @config.nil? && File.exists?(Config::FILE)
45
44
  @config = eval(File.open(Config::FILE) {|f| f.read})
@@ -49,11 +48,15 @@ module Warbler
49
48
  warn "Warbler::Config not provided by override in initializer or #{Config::FILE}; using defaults"
50
49
  @config = Config.new
51
50
  end
52
- @war = Warbler::War.new
51
+ @name = name || @config.jar_extension
52
+ @jar = Warbler::Jar.new
53
53
  yield self if block_given?
54
54
  define_tasks
55
55
  end
56
56
 
57
+ # Deprecated: attr_accessor :war
58
+ alias war jar
59
+
57
60
  private
58
61
  def define_tasks
59
62
  define_main_task
@@ -72,7 +75,7 @@ module Warbler
72
75
  end
73
76
 
74
77
  def define_main_task
75
- desc "Create the project .war file"
78
+ desc "Create the project #{config.jar_extension} file"
76
79
  task @name do
77
80
  unless @config.features.empty?
78
81
  @config.features.each do |feature|
@@ -93,28 +96,31 @@ module Warbler
93
96
  end
94
97
 
95
98
  def define_clean_task
96
- desc "Remove the .war file"
99
+ desc "Remove the project #{config.jar_extension} file"
97
100
  task "clean" do
98
- rm_f "#{config.war_name}.war"
101
+ rm_f "#{config.jar_name}.#{config.jar_extension}"
99
102
  end
100
103
  task "clear" => "#{name}:clean"
101
104
  end
102
105
 
103
106
  def define_compiled_task
104
107
  task "compiled" do
105
- war.compile(config)
108
+ jar.compile(config)
109
+ task @name do
110
+ rm_f config.compiled_ruby_files.map {|f| f.sub(/\.rb$/, '.class') }
111
+ end
106
112
  end
107
113
  end
108
114
 
109
115
  def define_files_task
110
116
  task "files" do
111
- war.apply(config)
117
+ jar.apply(config)
112
118
  end
113
119
  end
114
120
 
115
121
  def define_jar_task
116
122
  task "jar" do
117
- war.create(config)
123
+ jar.create(config)
118
124
  end
119
125
  end
120
126
 
@@ -122,36 +128,22 @@ module Warbler
122
128
  desc "Dump diagnostic information"
123
129
  task "debug" => "files" do
124
130
  require 'yaml'
125
- puts YAML::dump(config)
126
- war.files.each {|k,v| puts "#{k} -> #{String === v ? v : '<blob>'}"}
131
+ puts config.dump
132
+ jar.files.each {|k,v| puts "#{k} -> #{String === v ? v : '<blob>'}"}
127
133
  end
128
134
  task "debug:includes" => "files" do
129
135
  puts "", "included files:"
130
- puts *war.webinf_filelist.include
136
+ puts *war.app_filelist.include
131
137
  end
132
138
  task "debug:excludes" => "files" do
133
139
  puts "", "excluded files:"
134
- puts *war.webinf_filelist.exclude
140
+ puts *war.app_filelist.exclude
135
141
  end
136
142
  end
137
143
 
138
144
  def define_gemjar_task
139
145
  task "gemjar" do
140
- task "#@name:jar" => "#@name:make_gemjar"
141
- end
142
-
143
- gem_jar = Warbler::War.new
144
- task "make_gemjar" => "files" do
145
- gem_path = Regexp::quote(config.relative_gem_path)
146
- gems = war.files.select{|k,v| k =~ %r{#{gem_path}/} }
147
- gems.each do |k,v|
148
- gem_jar.files[k.sub(%r{#{gem_path}/}, '')] = v
149
- end
150
- war.files["WEB-INF/lib/gems.jar"] = "tmp/gems.jar"
151
- war.files.reject!{|k,v| k =~ /#{gem_path}/ }
152
- mkdir_p "tmp"
153
- gem_jar.add_manifest
154
- gem_jar.create("tmp/gems.jar")
146
+ @config.features << "gemjar"
155
147
  end
156
148
  end
157
149
 
@@ -186,32 +178,8 @@ module Warbler
186
178
  end
187
179
 
188
180
  def define_executable_task
189
- winstone_type = ENV["WINSTONE"] || "winstone-lite"
190
- winstone_version = ENV["WINSTONE_VERSION"] || "0.9.10"
191
- winstone_path = "net/sourceforge/winstone/#{winstone_type}/#{winstone_version}/#{winstone_type}-#{winstone_version}.jar"
192
- winstone_jar = File.expand_path("~/.m2/repository/#{winstone_path}")
193
- file winstone_jar do |t|
194
- # Not always covered in tests as these lines may not get
195
- # executed every time if the jar is cached.
196
- puts "Downloading #{winstone_type}.jar" #:nocov:
197
- mkdir_p File.dirname(t.name) #:nocov:
198
- require 'open-uri' #:nocov:
199
- maven_repo = ENV["MAVEN_REPO"] || "http://repo2.maven.org/maven2" #:nocov:
200
- open("#{maven_repo}/#{winstone_path}") do |stream| #:nocov:
201
- File.open(t.name, "wb") do |f| #:nocov:
202
- while buf = stream.read(4096) #:nocov:
203
- f << buf #:nocov:
204
- end #:nocov:
205
- end #:nocov:
206
- end #:nocov:
207
- end
208
-
209
- task "executable" => winstone_jar do
210
- war.files['META-INF/MANIFEST.MF'] = StringIO.new(War::DEFAULT_MANIFEST.chomp + "Main-Class: Main\n")
211
- war.files['Main.class'] = Zip::ZipFile.open("#{WARBLER_HOME}/lib/warbler_war.jar") do |zf|
212
- zf.get_input_stream('Main.class') {|io| StringIO.new(io.read) }
213
- end
214
- war.files['WEB-INF/winstone.jar'] = winstone_jar
181
+ task "executable" do
182
+ @config.features << "executable"
215
183
  end
216
184
  end
217
185
 
@@ -1 +1 @@
1
- WARBLER_CONFIG = <%= webxml.context_params(false) .inspect %>
1
+ WARBLER_CONFIG = <%= config.webxml ? config.webxml.context_params(false).inspect : '{}' %>
@@ -1 +1 @@
1
- ENV['RACK_ENV'] = '<%= (params = webxml.context_params; params['rack.env'] || params['rails.env']) %>'
1
+ ENV['RACK_ENV'] = '<%= (params = config.webxml.context_params; params['rack.env'] || params['rails.env']) %>'
@@ -1 +1 @@
1
- ENV['RAILS_ENV'] = '<%= webxml.rails.env %>'
1
+ ENV['RAILS_ENV'] = '<%= config.webxml.rails.env %>'
@@ -0,0 +1,58 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ module Warbler
8
+ module Traits
9
+ # The Bundler trait uses Bundler to determine gem dependencies to
10
+ # be added to the project.
11
+ class Bundler
12
+ include Trait
13
+
14
+ def self.detect?
15
+ File.exist?("Gemfile")
16
+ end
17
+
18
+ def self.requires?(trait)
19
+ trait == Traits::War || trait == Traits::Jar
20
+ end
21
+
22
+ def before_configure
23
+ config.bundler = true
24
+ config.bundle_without = ["development", "test"]
25
+ end
26
+
27
+ def after_configure
28
+ add_bundler_gems if config.bundler
29
+ end
30
+
31
+ def add_bundler_gems
32
+ config.gems.clear
33
+ config.gem_dependencies = false # Bundler takes care of these
34
+
35
+ require 'bundler'
36
+ gemfile = Pathname.new("Gemfile").expand_path
37
+ root = gemfile.dirname
38
+ lockfile = root.join('Gemfile.lock')
39
+ definition = ::Bundler::Definition.build(gemfile, lockfile, nil)
40
+ groups = definition.groups - config.bundle_without.map {|g| g.to_sym}
41
+ definition.specs_for(groups).each {|spec| config.gems << spec }
42
+ config.init_contents << StringIO.new("ENV['BUNDLE_WITHOUT'] = '#{config.bundle_without.join(':')}'\n")
43
+ end
44
+
45
+ def update_archive(jar)
46
+ add_bundler_files(jar) if config.bundler
47
+ end
48
+
49
+ # Add Bundler Gemfiles to the archive.
50
+ def add_bundler_files(jar)
51
+ jar.files[jar.apply_pathmaps(config, 'Gemfile', :application)] = 'Gemfile'
52
+ if File.exist?('Gemfile.lock')
53
+ jar.files[jar.apply_pathmaps(config, 'Gemfile.lock', :application)] = 'Gemfile.lock'
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,64 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ module Warbler
8
+ module Traits
9
+ # The Gemspec trait reads a .gemspec file to determine the files,
10
+ # executables, require paths, and dependencies for a project.
11
+ class Gemspec
12
+ include Trait
13
+
14
+ def self.detect?
15
+ !Dir['*.gemspec'].empty?
16
+ end
17
+
18
+ def before_configure
19
+ @spec_file = Dir['*.gemspec'].first
20
+ require 'yaml'
21
+ @spec = File.open(@spec_file) {|f| Gem::Specification.from_yaml(f) } rescue Gem::Specification.load(@spec_file)
22
+ @spec.runtime_dependencies.each {|g| config.gems << g }
23
+ config.dirs = []
24
+ config.compiled_ruby_files = @spec.files.select {|f| f =~ /\.rb$/}
25
+ end
26
+
27
+ def after_configure
28
+ @spec.require_paths.each do |p|
29
+ add_init_load_path(config.pathmaps.application.inject(p) {|pm,x| pm.pathmap(x)})
30
+ end
31
+ end
32
+
33
+ def update_archive(jar)
34
+ @spec.files.each do |f|
35
+ unless File.exist?(f)
36
+ warn "update your gemspec; skipping missing file #{f}"
37
+ next
38
+ end
39
+ file_key = jar.apply_pathmaps(config, f, :application)
40
+ next if jar.files[file_key]
41
+ jar.files[file_key] = f
42
+ end
43
+ config.compiled_ruby_files.each do |f|
44
+ f = f.sub(/\.rb$/, '.class')
45
+ next unless File.exist?(f)
46
+ jar.files[jar.apply_pathmaps(config, f, :application)] = f
47
+ end
48
+ bin_path = jar.apply_pathmaps(config, default_executable, :application)
49
+ add_main_rb(jar, bin_path)
50
+ end
51
+
52
+ def default_executable
53
+ if @spec.default_executable
54
+ "bin/#{@spec.default_executable}"
55
+ else
56
+ exe = Dir['bin/*'].first
57
+ raise "No executable script found" unless exe
58
+ warn "No default executable found in #{@spec_file}, using #{exe}"
59
+ exe
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,53 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ require 'stringio'
8
+ require 'ostruct'
9
+
10
+ module Warbler
11
+ module Traits
12
+ # The Jar trait sets up the archive layout for an executable jar
13
+ # project, and adds the JRuby jar files and a JarMain class to the
14
+ # archive.
15
+ class Jar
16
+ include Trait
17
+
18
+ def self.detect?
19
+ !War.detect?
20
+ end
21
+
22
+ def before_configure
23
+ config.pathmaps = default_pathmaps
24
+ config.java_libs = default_jar_files
25
+ config.manifest_file = 'MANIFEST.MF' if File.exist?('MANIFEST.MF')
26
+ end
27
+
28
+ def after_configure
29
+ config.init_contents << StringIO.new("require 'rubygems'\n")
30
+ end
31
+
32
+ def update_archive(jar)
33
+ jar.files['META-INF/MANIFEST.MF'] = StringIO.new(Warbler::Jar::DEFAULT_MANIFEST.chomp + "Main-Class: JarMain\n") unless config.manifest_file
34
+ jar.files['JarMain.class'] = jar.entry_in_jar("#{WARBLER_HOME}/lib/warbler_jar.jar", "JarMain.class")
35
+ end
36
+
37
+ def default_pathmaps
38
+ p = OpenStruct.new
39
+ p.java_libs = ["META-INF/lib/%f"]
40
+ p.java_classes = ["%p"]
41
+ p.application = ["#{config.jar_name}/%p"]
42
+ p.gemspecs = ["specifications/%f"]
43
+ p.gems = ["gems/%p"]
44
+ p
45
+ end
46
+
47
+ def default_jar_files
48
+ require 'jruby-jars'
49
+ FileList[JRubyJars.core_jar_path, JRubyJars.stdlib_jar_path]
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,34 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ module Warbler
8
+ module Traits
9
+ # The Merb trait adds Merb::BootLoader gem dependencies to the project.
10
+ class Merb
11
+ include Trait
12
+
13
+ def self.detect?
14
+ File.exist?("config/init.rb")
15
+ end
16
+
17
+ def self.requires?(trait)
18
+ trait == Traits::War
19
+ end
20
+
21
+ def before_configure
22
+ return false unless task = Warbler.project_application.lookup("merb_env")
23
+ task.invoke rescue nil
24
+ return false unless defined?(::Merb)
25
+ config.webxml.booter = :merb
26
+ if defined?(::Merb::BootLoader::Dependencies.dependencies)
27
+ ::Merb::BootLoader::Dependencies.dependencies.each {|g| config.gems << g }
28
+ else
29
+ warn "unable to auto-detect Merb dependencies; upgrade to Merb 1.0 or greater"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ module Warbler
8
+ module Traits
9
+ # The NoGemspec trait is used when no gemspec file is found for a
10
+ # jar project. It assumes a standard layout including +bin+ and
11
+ # +lib+ directories.
12
+ class NoGemspec
13
+ include Trait
14
+
15
+ def self.detect?
16
+ Jar.detect? && !Gemspec.detect?
17
+ end
18
+
19
+ def before_configure
20
+ config.dirs = ['.']
21
+ end
22
+
23
+ def after_configure
24
+ if File.directory?("lib")
25
+ add_init_load_path(config.pathmaps.application.inject("lib") {|pm,x| pm.pathmap(x)})
26
+ end
27
+ end
28
+
29
+ def update_archive(jar)
30
+ add_main_rb(jar, jar.apply_pathmaps(config, default_executable, :application))
31
+ end
32
+
33
+ def default_executable
34
+ exes = Dir['bin/*']
35
+ exe = exes.grep(/#{config.jar_name}/).first || exes.first
36
+ raise "No executable script found" unless exe
37
+ exe
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ module Warbler
8
+ module Traits
9
+ # The Rack trait adds config.ru to a Rack-based war project.
10
+ class Rack
11
+ include Trait
12
+
13
+ def self.detect?
14
+ !Rails.detect? && (File.exist?("config.ru") || !Dir['*/config.ru'].empty?)
15
+ end
16
+
17
+ def self.requires?(trait)
18
+ trait == Traits::War
19
+ end
20
+
21
+ def before_configure
22
+ config.webxml.booter = :rack
23
+ config.webinf_files += [FileList['config.ru', '*/config.ru'].detect {|f| File.exist?(f)}]
24
+ end
25
+
26
+ def after_configure
27
+ config.init_contents << "#{config.warbler_templates}/rack.erb"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ module Warbler
8
+ module Traits
9
+ # The Rails trait invokes the Rake environment task and sets up Rails for a war-based project.
10
+ class Rails
11
+ include Trait
12
+
13
+ def self.detect?
14
+ File.exist?("config/environment.rb")
15
+ end
16
+
17
+ def self.requires?(trait)
18
+ trait == Traits::War
19
+ end
20
+
21
+ def before_configure
22
+ config.jar_name = default_app_name
23
+
24
+ return unless Warbler.framework_detection
25
+ return false unless task = Warbler.project_application.lookup("environment")
26
+ task.invoke rescue nil
27
+ return false unless defined?(::Rails)
28
+ config.dirs << "tmp" if File.directory?("tmp")
29
+ config.webxml.booter = :rails
30
+ unless (defined?(::Rails.vendor_rails?) && ::Rails.vendor_rails?) || File.directory?("vendor/rails")
31
+ config.gems["rails"] = ::Rails::VERSION::STRING
32
+ end
33
+ if defined?(::Rails.configuration.gems)
34
+ ::Rails.configuration.gems.each do |g|
35
+ config.gems << Gem::Dependency.new(g.name, g.requirement) if Dir["vendor/gems/#{g.name}*"].empty?
36
+ end
37
+ end
38
+ if defined?(::Rails.configuration.threadsafe!) &&
39
+ (defined?(::Rails.configuration.allow_concurrency) && # Rails 3
40
+ ::Rails.configuration.allow_concurrency && ::Rails.configuration.preload_frameworks) ||
41
+ (defined?(::Rails.configuration.action_controller.allow_concurrency) && # Rails 2
42
+ ::Rails.configuration.action_controller.allow_concurrency && ::Rails.configuration.action_controller.preload_frameworks)
43
+ config.webxml.jruby.max.runtimes = 1
44
+ end
45
+ end
46
+
47
+ def after_configure
48
+ config.init_contents << "#{config.warbler_templates}/rails.erb"
49
+ end
50
+
51
+
52
+ def default_app_name
53
+ File.basename(File.expand_path(defined?(::Rails.root) ? ::Rails.root : (defined?(RAILS_ROOT) ? RAILS_ROOT : Dir.getwd)))
54
+ end
55
+ end
56
+ end
57
+ end