warbler_updated 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/History.txt +411 -0
  4. data/LICENSE.txt +27 -0
  5. data/Mavenfile +32 -0
  6. data/README.rdoc +280 -0
  7. data/Rakefile +63 -0
  8. data/bin/warble +11 -0
  9. data/ext/JarMain.java +334 -0
  10. data/ext/WarMain.java +375 -0
  11. data/ext/WarblerJar.java +199 -0
  12. data/ext/WarblerJarService.java +18 -0
  13. data/lib/warbler/application.rb +104 -0
  14. data/lib/warbler/bundler_helper.rb +22 -0
  15. data/lib/warbler/config.rb +265 -0
  16. data/lib/warbler/executable_helper.rb +25 -0
  17. data/lib/warbler/gems.rb +77 -0
  18. data/lib/warbler/jar.rb +348 -0
  19. data/lib/warbler/pathmap_helper.rb +20 -0
  20. data/lib/warbler/platform_helper.rb +26 -0
  21. data/lib/warbler/rake_helper.rb +30 -0
  22. data/lib/warbler/scripts/rails.rb +5 -0
  23. data/lib/warbler/task.rb +185 -0
  24. data/lib/warbler/templates/bundler.erb +19 -0
  25. data/lib/warbler/templates/config.erb +1 -0
  26. data/lib/warbler/templates/jar.erb +11 -0
  27. data/lib/warbler/templates/jbundler.erb +2 -0
  28. data/lib/warbler/templates/rack.erb +5 -0
  29. data/lib/warbler/templates/rails.erb +1 -0
  30. data/lib/warbler/templates/war.erb +19 -0
  31. data/lib/warbler/traits/bundler.rb +157 -0
  32. data/lib/warbler/traits/gemspec.rb +79 -0
  33. data/lib/warbler/traits/jar.rb +58 -0
  34. data/lib/warbler/traits/jbundler.rb +48 -0
  35. data/lib/warbler/traits/nogemspec.rb +47 -0
  36. data/lib/warbler/traits/rack.rb +33 -0
  37. data/lib/warbler/traits/rails.rb +91 -0
  38. data/lib/warbler/traits/war.rb +260 -0
  39. data/lib/warbler/traits.rb +124 -0
  40. data/lib/warbler/version.rb +10 -0
  41. data/lib/warbler/war.rb +8 -0
  42. data/lib/warbler/web_server.rb +125 -0
  43. data/lib/warbler/zip_support.rb +13 -0
  44. data/lib/warbler.rb +40 -0
  45. data/lib/warbler_jar.jar +0 -0
  46. data/warble.rb +188 -0
  47. data/warbler.gemspec +37 -0
  48. data/web.xml.erb +57 -0
  49. metadata +188 -0
@@ -0,0 +1,157 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ module Warbler
9
+ module Traits
10
+ # The Bundler trait uses Bundler to determine gem dependencies to
11
+ # be added to the project.
12
+ class Bundler
13
+ include Trait
14
+ include PathmapHelper
15
+ include BundlerHelper
16
+
17
+ def self.detect?
18
+ File.exist?(ENV['BUNDLE_GEMFILE'] || 'Gemfile')
19
+ end
20
+
21
+ def self.requirements
22
+ [ Traits::War, Traits::Jar ]
23
+ end
24
+
25
+ def before_configure
26
+ config.bundler ||= true
27
+ config.bundle_without = ['development', 'test', 'assets']
28
+ end
29
+
30
+ def after_configure
31
+ add_bundler_gems if config.bundler
32
+ end
33
+
34
+ def add_bundler_gems; require 'bundler'
35
+ # config.gems.clear allow to add `config.gems` on top of those bundled
36
+ config.gem_dependencies = false # Bundler takes care of these
37
+ config.bundler = {} if config.bundler == true
38
+
39
+ bundler_specs.each do |spec|
40
+ spec = to_spec(spec)
41
+ # Bundler HAX -- fixup bad #loaded_from attribute in fake
42
+ # bundler gemspec from bundler/source.rb
43
+ if spec.name == 'bundler'
44
+ full_gem_path = Pathname.new(spec.full_gem_path)
45
+ while ! full_gem_path.join('bundler.gemspec').exist?
46
+ full_gem_path = full_gem_path.dirname
47
+ # if at top of the path, meaning we cannot find bundler.gemspec, abort.
48
+ if full_gem_path.to_s =~ /^[\.\/]$/
49
+ warn("Unable to detect bundler spec under '#{spec.full_gem_path}'' and its sub-dirs")
50
+ exit
51
+ end
52
+ end
53
+
54
+ spec.loaded_from = full_gem_path.join('bundler.gemspec').to_s
55
+ spec.full_gem_path = full_gem_path.to_s
56
+ end
57
+
58
+ case spec.source
59
+ when ::Bundler::Source::Git
60
+ config.bundler[:git_specs] ||= []
61
+ config.bundler[:git_specs] << spec
62
+ when ::Bundler::Source::Path
63
+ unless bundler_source_is_warbled_gem_itself?(spec.source)
64
+ if spec.source.path && spec.source.path.relative?
65
+ # include (assuming) relative *[APP_ROOT]/gem/path*
66
+ # NOTE: might be tuned to only add gemspec.files ...
67
+ config.includes += FileList[File.join(spec.source.path, '**/*')]
68
+ config.gems << spec # probably not really needed
69
+ else
70
+ warn("Bundler `path' components are not fully supported.\n" +
71
+ "The `#{spec.full_name}' component was not bundled.\n" +
72
+ "Your application may fail to boot!")
73
+ end
74
+ end
75
+ else
76
+ config.gems << spec
77
+ end
78
+ end
79
+ config.bundler[:gemfile] = ::Bundler.default_gemfile
80
+ config.bundler[:gemfile_path] = apply_pathmaps(config, relative_from_pwd(::Bundler.default_gemfile), :application)
81
+ config.bundler[:lockfile] = ::Bundler.default_lockfile
82
+ config.bundler[:frozen] = ::Bundler.settings[:frozen]
83
+ path = ::Bundler.settings[:path]
84
+ config.excludes += [path, "#{path}/**/*"] if path
85
+ config.init_contents << "#{config.warbler_templates}/bundler.erb"
86
+ end
87
+
88
+ def update_archive(jar)
89
+ add_bundler_files(jar) if config.bundler
90
+ end
91
+
92
+ # Add Bundler Gemfiles and git repositories to the archive.
93
+ def add_bundler_files(jar)
94
+ gemfile = relative_from_pwd(config.bundler[:gemfile])
95
+ lockfile = relative_from_pwd(config.bundler[:lockfile])
96
+ jar.files[apply_pathmaps(config, gemfile, :application)] = config.bundler[:gemfile].to_s
97
+ if File.exist?(lockfile)
98
+ jar.files[apply_pathmaps(config, lockfile, :application)] = config.bundler[:lockfile].to_s
99
+ end
100
+ if config.bundler[:git_specs]
101
+ pathmap = "#{config.relative_gem_path}/bundler/gems/%p"
102
+ pathmap.sub!(%r{^/+}, '')
103
+ config.pathmaps.git = [pathmap]
104
+ config.bundler[:git_specs].each do |spec|
105
+ full_gem_path = Pathname.new(spec.full_gem_path)
106
+
107
+ gem_relative_path = full_gem_path.relative_path_from(::Bundler.install_path)
108
+ filenames = []
109
+ gem_relative_path.each_filename { |f| filenames << f }
110
+
111
+ exclude_gems = true
112
+ unless filenames.empty?
113
+ full_gem_path = Pathname.new(::Bundler.install_path) + filenames.first
114
+ exclude_gems = false
115
+ end
116
+
117
+ if spec.groups.include?(:warbler_excluded)
118
+ pattern = "#{full_gem_path.to_s}/**/#{spec.name}.gemspec" # #42: gemspec only to avert Bundler error
119
+ else
120
+ pattern = "#{full_gem_path.to_s}/**/*"
121
+ end
122
+
123
+ FileList[pattern].each do |src|
124
+ f = Pathname.new(src).relative_path_from(full_gem_path).to_s
125
+ next if exclude_gems && config.gem_excludes && config.gem_excludes.any? {|rx| f =~ rx }
126
+ jar.files[apply_pathmaps(config, File.join(full_gem_path.basename, f), :git)] = src
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def relative_from_pwd(path)
133
+ if path.relative?
134
+ path
135
+ else
136
+ path.relative_path_from(Pathname.new(Dir.pwd)).to_s
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def bundler_specs
143
+ bundle_without = config.bundle_without.map { |s| s.to_sym }
144
+ definition = ::Bundler.definition
145
+ all = definition.specs.to_a
146
+ requested = definition.specs_for(definition.groups - bundle_without).to_a
147
+ excluded_git_specs = (all - requested).select { |spec| ::Bundler::Source::Git === spec.source }
148
+ excluded_git_specs.each { |spec| spec.groups << :warbler_excluded }
149
+ requested + excluded_git_specs
150
+ end
151
+
152
+ def bundler_source_is_warbled_gem_itself?(source)
153
+ source.path.to_s == '.'
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,79 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ module Warbler
9
+ module Traits
10
+ # The Gemspec trait reads a .gemspec file to determine the files,
11
+ # executables, require paths, and dependencies for a project.
12
+ class Gemspec
13
+ include Trait
14
+ include PathmapHelper
15
+ include ExecutableHelper
16
+
17
+ def self.detect?
18
+ !Dir['*.gemspec'].empty?
19
+ end
20
+
21
+ def before_configure; require 'yaml'
22
+ @spec_file = Dir['*.gemspec'].first
23
+ @spec = File.open(@spec_file) { |f| Gem::Specification.from_yaml(f) } rescue Gem::Specification.load(@spec_file)
24
+ @spec.runtime_dependencies.each { |g| config.gems << g }
25
+ config.dirs = []
26
+ config.compiled_ruby_files = @spec.files.select { |f| f =~ /\.rb$/ }
27
+ end
28
+
29
+ def after_configure
30
+ @spec.require_paths.each do |p|
31
+ add_init_load_path( config.pathmaps.application.inject(p) { |pm,x| pm.pathmap(x) } )
32
+ end
33
+ end
34
+
35
+ def update_archive(jar)
36
+ @spec.files.each do |f|
37
+ unless File.exist?(f)
38
+ warn "update your gemspec; skipping missing file #{f}"
39
+ next
40
+ end
41
+ file_key = jar.apply_pathmaps(config, f, :application)
42
+ next if jar.files[file_key]
43
+ jar.files[file_key] = f
44
+ end
45
+
46
+ config.compiled_ruby_files.each do |f|
47
+ f = f.sub(/\.rb$/, '.class')
48
+ next unless File.exist?(f)
49
+ jar.files[apply_pathmaps(config, f, :application)] = f
50
+ end
51
+
52
+ update_archive_add_executable(jar)
53
+ end
54
+
55
+ def default_executable
56
+ if ! @spec.executables.empty?
57
+ exe_script = @spec.executables.first
58
+ exe_path = File.join(@spec.bindir, exe_script) # bin/script
59
+ if File.exists?(exe_path)
60
+ exe_path
61
+ elsif File.exists?("bin/#{exe_script}") # compatibility
62
+ "bin/#{exe_script}" # ... should probably remove this
63
+ else
64
+ raise "no `#{exe_script}` executable script found"
65
+ end
66
+ elsif exe_path = Dir['bin/*'].sort.first
67
+ warn "no executables found in #{@spec_file}, using #{exe_path}"
68
+ exe_path
69
+ elsif exe_path = Dir['exe/*'].sort.first
70
+ warn "no executables found in #{@spec_file}, using #{exe_path}"
71
+ exe_path
72
+ else
73
+ raise "no executable script found"
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,58 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ require 'stringio'
9
+ require 'ostruct'
10
+
11
+ module Warbler
12
+ module Traits
13
+ # The Jar trait sets up the archive layout for an executable jar
14
+ # project, and adds the JRuby jar files and a JarMain class to the
15
+ # archive.
16
+ class Jar
17
+ include Trait
18
+
19
+ def self.detect?
20
+ !War.detect?
21
+ end
22
+
23
+ def before_configure
24
+ config.gem_path = '/'
25
+ config.pathmaps = default_pathmaps
26
+ config.java_libs = default_jar_files
27
+ config.manifest_file = 'MANIFEST.MF' if File.exist?('MANIFEST.MF')
28
+ config.init_contents << "#{config.warbler_templates}/jar.erb"
29
+ end
30
+
31
+ def after_configure
32
+ config.init_contents << StringIO.new("require 'rubygems' unless defined?(Gem)\n")
33
+ end
34
+
35
+ def update_archive(jar)
36
+ unless config.manifest_file
37
+ manifest = Warbler::Jar::DEFAULT_MANIFEST.chomp + "Main-Class: JarMain\n"
38
+ jar.files['META-INF/MANIFEST.MF'] = StringIO.new(manifest)
39
+ end
40
+ jar.files['JarMain.class'] = jar.entry_in_jar(WARBLER_JAR, "JarMain.class")
41
+ end
42
+
43
+ def default_pathmaps
44
+ p = OpenStruct.new
45
+ p.java_libs = ["META-INF/lib/%f"]
46
+ p.java_classes = ["%p"]
47
+ p.application = ["#{config.jar_name}/%p"]
48
+ p.gemspecs = ["specifications/%f"]
49
+ p.gems = ["gems/%p"]
50
+ p
51
+ end
52
+
53
+ def default_jar_files
54
+ jruby_jars
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,48 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ module Warbler
9
+ module Traits
10
+ # The JBundler trait uses JBundler to determine jar dependencies to
11
+ # be added to the project.
12
+ class JBundler
13
+ include Trait
14
+ include PathmapHelper
15
+
16
+ def self.detect?
17
+ File.exist?(ENV['JBUNDLE_JARFILE'] || "Jarfile")
18
+ end
19
+
20
+ def self.requirements
21
+ [ Traits::War, Traits::Jar ]
22
+ end
23
+
24
+ def before_configure
25
+ config.jbundler = true
26
+ end
27
+
28
+ def after_configure
29
+ add_jbundler_jars if config.jbundler
30
+ end
31
+
32
+ def add_jbundler_jars
33
+ require 'jbundler/config'
34
+ classpath = ::JBundler::Config.new.classpath_file
35
+ if File.exists?( classpath )
36
+ require File.expand_path( classpath )
37
+ else
38
+ raise 'jbundler support needs jruby to create a local config: jruby -S jbundle install'
39
+ end
40
+ # use only the jars from jbundler and jruby
41
+ config.java_libs += jruby_jars
42
+ config.java_libs += JBUNDLER_CLASSPATH
43
+ config.java_libs.uniq! {|lib| lib.split(File::SEPARATOR).last }
44
+ config.init_contents << "#{config.warbler_templates}/jbundler.erb"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,47 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ module Warbler
9
+ module Traits
10
+ # The NoGemspec trait is used when no gemspec file is found for a
11
+ # jar project. It assumes a standard layout including +bin+ and
12
+ # +lib+ directories.
13
+ class NoGemspec
14
+ include Trait
15
+ include PathmapHelper
16
+ include ExecutableHelper
17
+
18
+ def self.detect?
19
+ Jar.detect? && !Gemspec.detect?
20
+ end
21
+
22
+ def before_configure
23
+ config.dirs = ['.']
24
+ end
25
+
26
+ def after_configure
27
+ if File.directory?("lib")
28
+ add_init_load_path(config.pathmaps.application.inject("lib") {|pm,x| pm.pathmap(x)})
29
+ end
30
+ end
31
+
32
+ def update_archive(jar)
33
+ update_archive_add_executable(jar)
34
+ end
35
+
36
+ def default_executable
37
+ exes = Dir['bin/*'].sort
38
+ unless exe = exes.grep(/#{config.jar_name}/).first
39
+ exe = exes.first
40
+ warn "No executable matching config.jar_name found, using #{exe}" if exe
41
+ end
42
+ raise "No executable script found" unless exe
43
+ exe
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ module Warbler
9
+ module Traits
10
+ # The Rack trait adds config.ru to a Rack-based war project.
11
+ class Rack
12
+ include Trait
13
+
14
+ def self.detect?
15
+ !Rails.detect? && (File.exist?("config.ru") || !Dir['*/config.ru'].empty?)
16
+ end
17
+
18
+ def self.requirements
19
+ [ Traits::War ]
20
+ end
21
+
22
+ def before_configure
23
+ config.webxml.booter = :rack
24
+ config.webinf_files += [FileList['config.ru', '*/config.ru'].detect {|f| File.exist?(f)}]
25
+ config.webxml.rack.env = ENV['RACK_ENV'] || 'production'
26
+ end
27
+
28
+ def after_configure
29
+ config.init_contents << "#{config.warbler_templates}/rack.erb"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,91 @@
1
+ #--
2
+ # Copyright (c) 2010-2012 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ module Warbler
9
+ module Traits
10
+ # The Rails trait invokes the Rake environment task and sets up Rails for a war-based project.
11
+ class Rails
12
+ include Trait
13
+
14
+ def self.detect?
15
+ File.exist?('config/environment.rb')
16
+ end
17
+
18
+ def self.requirements
19
+ [ Traits::War ]
20
+ end
21
+
22
+ def before_configure
23
+ config.jar_name = default_app_name
24
+ config.webxml.rails.env = ENV['RAILS_ENV'] || 'production'
25
+ config.pathmaps.public_html << "%{packs/(manifest.*),WEB-INF/public/packs/\\1}p"
26
+
27
+ return unless Warbler.framework_detection
28
+ return false unless task = Warbler.project_application.lookup('environment')
29
+
30
+ task.invoke rescue nil
31
+ return false unless defined?(::Rails)
32
+
33
+ config.dirs << 'tmp' if File.directory?('tmp')
34
+ config.webxml.booter = :rails
35
+ unless (defined?(::Rails.vendor_rails?) && ::Rails.vendor_rails?) || File.directory?('vendor/rails')
36
+ config.gems['rails'] = ::Rails::VERSION::STRING unless Bundler.detect?
37
+ end
38
+ if defined?(::Rails.configuration.gems)
39
+ ::Rails.configuration.gems.each do |g|
40
+ config.gems << Gem::Dependency.new(g.name, g.requirement) if Dir["vendor/gems/#{g.name}*"].empty?
41
+ end
42
+ end
43
+ config.script_files << "#{config.warbler_scripts}/rails.rb"
44
+ end
45
+
46
+ def after_configure
47
+ config.init_contents << "#{config.warbler_templates}/rails.erb"
48
+
49
+ if config.webxml.jruby.min.runtimes.is_a?(OpenStruct) &&
50
+ config.webxml.jruby.max.runtimes.is_a?(OpenStruct) # not set
51
+ if rails_major_version(0) >= 4 || threadsafe_enabled?
52
+ config.webxml.jruby.min.runtimes = 1
53
+ config.webxml.jruby.max.runtimes = 1
54
+ end
55
+ end
56
+
57
+ config.includes += FileList["public/assets/.sprockets-manifest-*.json"].existing
58
+ config.includes += FileList["public/assets/manifest-*.json"].existing
59
+ config.includes += FileList["public/assets/manifest.yml"].existing
60
+ end
61
+
62
+ def default_app_name
63
+ File.basename(File.expand_path(defined?(::Rails.root) ? ::Rails.root : (defined?(RAILS_ROOT) ? RAILS_ROOT : Dir.getwd)))
64
+ end
65
+
66
+ def threadsafe_enabled?
67
+ rails_env = config.webxml.rails.env
68
+ begin
69
+ unless IO.readlines("config/environments/#{rails_env}.rb").grep(/^\s*config\.threadsafe!/).empty? &&
70
+ IO.readlines("config/environment.rb").grep(/^\s*config\.threadsafe!/).empty?
71
+ return true
72
+ end
73
+ rescue
74
+ end
75
+ end
76
+
77
+ def rails_major_version(default = 0)
78
+ begin
79
+ File.open("#{ENV['BUNDLE_GEMFILE'] || 'Gemfile'}.lock") do |file|
80
+ file.each_line do |line|
81
+ match = line.match( /^\s*rails\s\(\s*(\d)\.\d+\.\d+.*\)$/ )
82
+ return match[1].to_i if match
83
+ end
84
+ end
85
+ rescue
86
+ end
87
+ default
88
+ end
89
+ end
90
+ end
91
+ end