warbler 2.1.0 → 2.1.2

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.
@@ -7,14 +7,7 @@
7
7
  module Warbler
8
8
  module BundlerHelper
9
9
  def to_spec(spec)
10
- # JRuby <= 1.7.20 does not handle respond_to? with method_missing right
11
- # thus a `spec.respond_to?(:to_spec) ? spec.to_spec : spec` won't do :
12
- if ::Bundler.const_defined?(:StubSpecification) # since Bundler 1.10.1
13
- spec = spec.to_spec if spec.is_a?(::Bundler::StubSpecification)
14
- else
15
- spec = spec.to_spec if spec.respond_to?(:to_spec)
16
- end
17
- spec
10
+ spec.respond_to?(:to_spec) ? spec.to_spec : spec
18
11
  end
19
12
  module_function :to_spec
20
13
  end
@@ -15,8 +15,8 @@ module Warbler
15
15
  include RakeHelper
16
16
 
17
17
  TOP_DIRS = %w(app db config lib log script vendor)
18
- FILE = "config/warble.rb"
19
- BUILD_GEMS = %w(warbler rake rcov)
18
+ CONFIG_DIR = "config"
19
+ FILE = "#{CONFIG_DIR}/warble.rb"
20
20
 
21
21
  include Traits
22
22
 
@@ -29,11 +29,8 @@ module Warbler
29
29
 
30
30
  # Traits: an array of trait classes corresponding to
31
31
  # characteristics of the project that are either auto-detected or
32
- # configured.
33
- attr_accessor :traits
34
-
35
- # Deprecated: No longer has any effect.
36
- attr_accessor :staging_dir
32
+ # forced enabled during `Config.new(forced_traits: [...]) do |config|`
33
+ attr_reader :traits
37
34
 
38
35
  # Directory where the war file will be written. Can be used to direct
39
36
  # Warbler to place your war file directly in your application server's
@@ -63,8 +60,10 @@ module Warbler
63
60
  # Whether to include dependent gems (default true)
64
61
  attr_accessor :gem_dependencies
65
62
 
66
- # Array of regular expressions matching relative paths in gems to
67
- # be excluded from the war. Default contains no exclusions.
63
+ # Array of regular expressions matching paths *inside* packed gems to be
64
+ # excluded from the archive. Paths are matched relative to each gem's root
65
+ # (for git-sourced gems: the repository checkout root). Default contains no
66
+ # exclusions.
68
67
  attr_accessor :gem_excludes
69
68
 
70
69
  # Whether to exclude **/*.log files (default is true)
@@ -185,8 +184,9 @@ module Warbler
185
184
  attr_reader :warbler_templates
186
185
  attr_reader :warbler_scripts
187
186
 
188
- def initialize(warbler_home = WARBLER_HOME)
189
- super()
187
+ # @param forced_traits [Array<Class>, nil] optional array of Warbler::Trait types to force rather than auto-detecting them
188
+ def initialize(warbler_home = WARBLER_HOME, forced_traits: nil)
189
+ super(forced_traits)
190
190
 
191
191
  @warbler_home = warbler_home
192
192
  @warbler_templates = "#{WARBLER_HOME}/lib/warbler/templates"
data/lib/warbler/gems.rb CHANGED
@@ -51,9 +51,8 @@ module Warbler
51
51
 
52
52
  # Add a single gem to WEB-INF/gems
53
53
  def find_single_gem_files(gem_dependencies, gem_pattern, version = nil)
54
- gem_spec_class = Gem::Specification
55
54
  case gem_pattern
56
- when gem_spec_class
55
+ when Gem::Specification
57
56
  return BundlerHelper.to_spec(gem_pattern)
58
57
  when Gem::Dependency
59
58
  gem = gem_pattern
@@ -61,12 +60,9 @@ module Warbler
61
60
  gem = Gem::Dependency.new(gem_pattern, Gem::Requirement.create(version))
62
61
  end
63
62
  # skip development dependencies
64
- return nil if gem.respond_to?(:type) and gem.type != :runtime
63
+ return nil if gem.type != :runtime
65
64
 
66
- # Deal with deprecated Gem.source_index and #search
67
- matched = gem.respond_to?(:to_spec) ? [ gem.to_spec ] : Gem.source_index.search(gem)
68
- fail "gem '#{gem}' not installed" if matched.empty?
69
- spec = matched.last
65
+ spec = gem.to_spec
70
66
  return spec unless gem_dependencies
71
67
  [spec] + spec.dependencies.map { |dependent_gem| find_single_gem_files(gem_dependencies, dependent_gem) }
72
68
  end
data/lib/warbler/jar.rb CHANGED
@@ -70,8 +70,6 @@ module Warbler
70
70
  end
71
71
  @compiled = true
72
72
  end
73
- # @deprecated only due compatibility
74
- alias_method :run_javac, :run_jrubyc
75
73
 
76
74
  def sh_jrubyc(cmd)
77
75
  sh(cmd) do |ok, res|
@@ -178,6 +176,7 @@ module Warbler
178
176
 
179
177
  # Invoke a hook to allow the project traits to add or modify the archive contents.
180
178
  def apply_traits(config)
179
+ puts "Applying traits #{config.traits}" unless silent?
181
180
  config.update_archive(self)
182
181
  end
183
182
 
@@ -220,7 +219,7 @@ module Warbler
220
219
  # OK if the gem does not exists as its un-packed on the "shared" path
221
220
  # ... at least gem spec.spec_file should exists although not crucial
222
221
  if JRUBY_VERSION != JRubyJars::VERSION
223
- warn "skipping #{spec.name} default gem (assuming its part of jruby-jars #{JRubyJars::VERSION})" unless silent?
222
+ warn "skipping #{spec.name} default gem (assuming its part of jruby-jars #{JRubyJars::VERSION})"
224
223
  end
225
224
  else
226
225
  warn "skipping #{spec.name} gem (#{full_gem_path.to_s} does not exist)"
@@ -335,14 +334,6 @@ module Warbler
335
334
 
336
335
  # Java-boosted jar creation for JRuby; replaces #create_jar and
337
336
  # #entry_in_jar with Java version
338
- require 'warbler_jar' if defined?(JRUBY_VERSION) && JRUBY_VERSION >= "1.5"
339
- end
340
-
341
- # Warbler::War is Deprecated. Please use Warbler::Jar.
342
- class War < Jar
343
- def initialize(*)
344
- super
345
- warn "Warbler::War is deprecated. Please replace all occurrences with Warbler::Jar."
346
- end
337
+ require 'warbler_jar' if defined?(JRUBY_VERSION)
347
338
  end
348
339
  end
data/lib/warbler/task.rb CHANGED
@@ -151,12 +151,15 @@ module Warbler
151
151
  if File.exist?(Warbler::Config::FILE) && ENV["FORCE"].nil?
152
152
  puts "There's another bird sitting on my favorite branch"
153
153
  puts "(file '#{Warbler::Config::FILE}' already exists. Pass argument FORCE=1 to override)"
154
- elsif !File.directory?("config")
155
- puts "I'm confused; my favorite branch is missing"
156
- puts "(directory 'config' is missing)"
157
- else
158
- cp "#{Warbler::WARBLER_HOME}/warble.rb", Warbler::Config::FILE
154
+ next
155
+ end
156
+
157
+ if !File.directory?(Warbler::Config::CONFIG_DIR)
158
+ puts "config dir is missing, creating it"
159
+ mkdir_p Warbler::Config::CONFIG_DIR
159
160
  end
161
+
162
+ cp "#{Warbler::WARBLER_HOME}/warble.rb", Warbler::Config::FILE
160
163
  end
161
164
  end
162
165
 
@@ -1,4 +1 @@
1
1
  ENV['BUNDLE_WITHOUT'] = '<%= config.bundle_without.join(':') %>'
2
- <% if config.bundler[:frozen] -%>
3
- ENV['BUNDLE_FROZEN'] = '1'
4
- <% end -%>
@@ -4,10 +4,12 @@ ENV['GEM_HOME'] <%= config.override_gem_home ? '=' : '||=' %> File.expand_path(F
4
4
  ENV['GEM_HOME'] <%= config.override_gem_home ? '=' : '||=' %> File.expand_path(File.join('..', '..', '<%= config.relative_gem_path %>'), __FILE__)
5
5
  <% end -%>
6
6
  <% if config.override_gem_home -%>
7
- ENV['GEM_PATH'] = nil # RGs sets Gem.paths.path = Gem.default_path + [ GEM_HOME ]
7
+ <%# GEM_HOME (the packed gems) is always on Gem.path; adding only the runtime's own default %>
8
+ <%# gem dir (Ruby's "bundled gems") excludes host gem paths (e.g. Gem.user_dir aka ~/.gem) %>
9
+ ENV['GEM_PATH'] = Gem.default_dir
8
10
  <% end -%>
9
11
  <% if config.bundler && config.bundler[:gemfile_path] -%>
10
12
  ENV['BUNDLE_GEMFILE'] = File.expand_path(File.join('..', '..', '<%= config.bundler[:gemfile_path] %>'), __FILE__)
11
13
  <% end -%>
12
14
  <%# Ensure any cached paths are cleared; otherwise behaviour can be indeterminate if the paths have already been read %>
13
- # Gem.clear_paths
15
+ Gem.clear_paths
@@ -6,7 +6,9 @@ if $servlet_context.nil?
6
6
  else
7
7
  ENV['GEM_HOME'] <%= config.override_gem_home ? '=' : '||=' %> $servlet_context.getRealPath('<%= config.gem_path %>')
8
8
  <% if config.override_gem_home -%>
9
- ENV['GEM_PATH'] = nil
9
+ <%# GEM_HOME (the packed gems) is always on Gem.path; adding only the runtime's own default %>
10
+ <%# gem dir (Ruby's "bundled gems") excludes host gem paths (e.g. Gem.user_dir aka ~/.gem) %>
11
+ ENV['GEM_PATH'] = Gem.default_dir
10
12
  <% end -%>
11
13
  <% if config.bundler && config.bundler[:gemfile_path] -%>
12
14
  ENV['BUNDLE_GEMFILE'] ||= $servlet_context.getRealPath('/<%= config.bundler[:gemfile_path] %>')
@@ -14,6 +14,23 @@ module Warbler
14
14
  include PathmapHelper
15
15
  include BundlerHelper
16
16
 
17
+ # Bundler settings enforced in the packed application via a generated
18
+ # *.bundle/config*, the highest-precedence documented configuration level:
19
+ BUNDLE_CONFIG_DEFAULTS = {
20
+ # BUNDLE_VERSION: disable bundler's "auto-switch" to Gemfile.lock's BUNDLED WITH bundler version
21
+ # (bundler restarts the process to do so, which cannot work inside a servlet container or self-contained executable jar)
22
+ 'BUNDLE_VERSION' => 'system',
23
+ # BUNDLE_FROZEN: fail fast with a descriptive error on Gemfile vs Gemfile.lock drift instead of attempting
24
+ # a runtime re-resolution
25
+ 'BUNDLE_FROZEN' => 'true',
26
+ # BUNDLE_PATH__SYSTEM (path.system): pin bundler to the "system" gems - which are the packed gems, via
27
+ # GEM_HOME/GEM_PATH from *init.rb* - immune to a BUNDLE_PATH/BUNDLE_DEPLOYMENT leaking in from the host's
28
+ # environment or ~/.bundle/config
29
+ 'BUNDLE_PATH__SYSTEM' => 'true',
30
+ # BUNDLE_AUTO_INSTALL: never install gems at boot time, even if the host's environment or global config enables it
31
+ 'BUNDLE_AUTO_INSTALL' => 'false'
32
+ }.freeze
33
+
17
34
  def self.detect?
18
35
  File.exist?(ENV['BUNDLE_GEMFILE'] || 'Gemfile')
19
36
  end
@@ -36,6 +53,8 @@ module Warbler
36
53
  config.gem_dependencies = false # Bundler takes care of these
37
54
  config.bundler = {} if config.bundler == true
38
55
 
56
+ warn_on_bundler_version_mismatch
57
+
39
58
  bundler_specs.each do |spec|
40
59
  spec = to_spec(spec)
41
60
 
@@ -45,11 +64,12 @@ module Warbler
45
64
  config.bundler[:git_specs] << spec
46
65
  when ::Bundler::Source::Path
47
66
  unless bundler_source_is_warbled_gem_itself?(spec.source)
48
- if spec.source.path && spec.source.path.relative?
49
- # include (assuming) relative *[APP_ROOT]/gem/path*
50
- # NOTE: might be tuned to only add gemspec.files ...
67
+ if spec.source.path&.relative?
68
+ # pack the gem at its relative *[APP_ROOT]/gem/path* location - at runtime bundler resolves the path
69
+ # source relative to the packed Gemfile.
70
+ # Deliberately NOT also added to config.gems: bundler never materializes path gems from the gem
71
+ # repository; doing so would cause duplication.
51
72
  config.includes += FileList[File.join(spec.source.path, '**/*')]
52
- config.gems << spec # probably not really needed
53
73
  else
54
74
  warn("Bundler `path' components are not fully supported.\n" +
55
75
  "The `#{spec.full_name}' component was not bundled.\n" +
@@ -57,13 +77,12 @@ module Warbler
57
77
  end
58
78
  end
59
79
  else
60
- config.gems << spec
80
+ config.gems << spec unless spec.respond_to?(:default_gem?) && spec.default_gem?
61
81
  end
62
82
  end
63
83
  config.bundler[:gemfile] = ::Bundler.default_gemfile
64
84
  config.bundler[:gemfile_path] = apply_pathmaps(config, relative_from_pwd(::Bundler.default_gemfile), :application)
65
85
  config.bundler[:lockfile] = ::Bundler.default_lockfile
66
- config.bundler[:frozen] = ::Bundler.settings[:frozen]
67
86
  path = ::Bundler.settings[:path]
68
87
  config.excludes += [path, "#{path}/**/*"] if path
69
88
  config.init_contents << "#{config.warbler_templates}/bundler.erb"
@@ -73,42 +92,41 @@ module Warbler
73
92
  add_bundler_files(jar) if config.bundler
74
93
  end
75
94
 
76
- # Add Bundler Gemfiles and git repositories to the archive.
95
+ # Add Bundler Gemfiles, .bundle/config and git repositories to the archive.
77
96
  def add_bundler_files(jar)
78
97
  gemfile = relative_from_pwd(config.bundler[:gemfile])
79
98
  lockfile = relative_from_pwd(config.bundler[:lockfile])
99
+ bundle_config = File.join('.bundle', 'config')
100
+
80
101
  jar.files[apply_pathmaps(config, gemfile, :application)] = config.bundler[:gemfile].to_s
81
- if File.exist?(lockfile)
82
- jar.files[apply_pathmaps(config, lockfile, :application)] = config.bundler[:lockfile].to_s
83
- end
84
- if config.bundler[:git_specs]
85
- pathmap = "#{config.relative_gem_path}/bundler/gems/%p"
86
- pathmap.sub!(%r{^/+}, '')
87
- config.pathmaps.git = [pathmap]
88
- config.bundler[:git_specs].each do |spec|
89
- full_gem_path = Pathname.new(spec.full_gem_path)
90
-
91
- gem_relative_path = full_gem_path.relative_path_from(::Bundler.install_path)
92
- filenames = []
93
- gem_relative_path.each_filename { |f| filenames << f }
94
-
95
- exclude_gems = true
96
- unless filenames.empty?
97
- full_gem_path = Pathname.new(::Bundler.install_path) + filenames.first
98
- exclude_gems = false
99
- end
102
+ jar.files[apply_pathmaps(config, lockfile, :application)] = config.bundler[:lockfile].to_s if File.exist?(lockfile)
103
+ # NOTE: in-memory content must be an IO - jar creation treats plain Strings as source file paths
104
+ jar.files[apply_pathmaps(config, bundle_config, :application)] = StringIO.new(bundle_config_contents)
100
105
 
101
- if spec.groups.include?(:warbler_excluded)
102
- pattern = "#{full_gem_path.to_s}/**/#{spec.name}.gemspec" # #42: gemspec only to avert Bundler error
103
- else
104
- pattern = "#{full_gem_path.to_s}/**/*"
105
- end
106
+ add_bundler_git_specs(config.bundler[:git_specs], jar) if config.bundler[:git_specs]
107
+ end
106
108
 
107
- FileList[pattern].each do |src|
108
- f = Pathname.new(src).relative_path_from(full_gem_path).to_s
109
- next if exclude_gems && config.gem_excludes && config.gem_excludes.any? {|rx| f =~ rx }
110
- jar.files[apply_pathmaps(config, File.join(full_gem_path.basename, f), :git)] = src
111
- end
109
+ private
110
+
111
+ def add_bundler_git_specs(git_specs, jar)
112
+ config.pathmaps.git = ["#{config.relative_gem_path}/bundler/gems/%p".sub(%r{^/+}, '')]
113
+
114
+ # a git source checkout may contain multiple gems (spec.full_gem_path being a sub-directory) - bundler expects
115
+ # the complete repository checkout under bundler/gems/<repo>-<ref>, so pack from its root (once per repository,
116
+ # even when several specs share the checkout)
117
+ checkout_paths = git_specs.map do |spec|
118
+ full_gem_path = Pathname.new(spec.full_gem_path)
119
+ filenames = full_gem_path.relative_path_from(::Bundler.install_path).each_filename.to_a
120
+ filenames.empty? ? full_gem_path : Pathname.new(::Bundler.install_path) + filenames.first
121
+ end.uniq
122
+
123
+ checkout_paths.each do |checkout_path|
124
+ FileList["#{checkout_path.to_s}/**/*"].each do |src|
125
+ f = Pathname.new(src).relative_path_from(checkout_path).to_s
126
+ # NOTE: for git sources the excludes match relative to the packed repository checkout root (the gem root,
127
+ # except multi-gem repos)
128
+ next if config.gem_excludes && config.gem_excludes.any? { |rx| f =~ rx }
129
+ jar.files[apply_pathmaps(config, File.join(checkout_path.basename, f), :git)] = src
112
130
  end
113
131
  end
114
132
  end
@@ -121,17 +139,32 @@ module Warbler
121
139
  end
122
140
  end
123
141
 
124
- private
142
+ def warn_on_bundler_version_mismatch
143
+ lockfile = ::Bundler.default_lockfile
144
+ return unless lockfile && File.exist?(lockfile)
145
+ locked = ::Bundler::LockfileParser.new(File.read(lockfile)).bundler_version rescue nil
146
+ if locked && locked.to_s != ::Bundler::VERSION
147
+ warn("Gemfile.lock BUNDLED WITH (#{locked}) does not match the bundler running warbler (#{::Bundler::VERSION}).\n" +
148
+ "The packed application will boot with the default bundler of the packed JRuby (jruby-jars),\n" +
149
+ "consider re-generating Gemfile.lock with a matching bundler version.")
150
+ end
151
+ end
152
+
153
+ # Contents for the packed *.bundle/config*: only warbler's deployment settings, deliberately independent of the
154
+ # application's build-time bundler configuration.
155
+ def bundle_config_contents
156
+ require 'yaml'
157
+ settings = BUNDLE_CONFIG_DEFAULTS.dup
158
+ # frozen mode errors without a lockfile - do not force it upon applications packed without a Gemfile.lock
159
+ settings.delete('BUNDLE_FROZEN') if config.bundler[:frozen] == false || !File.exist?(config.bundler[:lockfile].to_s)
160
+ settings.to_yaml
161
+ end
125
162
 
126
163
  def bundler_specs
127
164
  bundle_without = config.bundle_without.map { |s| s.to_sym }
128
165
  definition = ::Bundler.definition
129
- all = definition.specs.to_a
130
166
  requested_groups = definition.groups - bundle_without
131
- requested = requested_groups.empty? ? [] : definition.specs_for(requested_groups).to_a
132
- excluded_git_specs = (all - requested).select { |spec| ::Bundler::Source::Git === spec.source }
133
- excluded_git_specs.each { |spec| spec.groups << :warbler_excluded }
134
- requested + excluded_git_specs
167
+ requested_groups.empty? ? [] : definition.specs_for(requested_groups).to_a
135
168
  end
136
169
 
137
170
  def bundler_source_is_warbled_gem_itself?(source)
@@ -18,6 +18,10 @@ module Warbler
18
18
  !Dir['*.gemspec'].empty?
19
19
  end
20
20
 
21
+ def self.conflicts
22
+ [ Traits::NoGemspec ]
23
+ end
24
+
21
25
  def before_configure; require 'yaml'
22
26
  @spec_file = Dir['*.gemspec'].first
23
27
  @spec = File.open(@spec_file) { |f| Gem::Specification.from_yaml(f) } rescue Gem::Specification.load(@spec_file)
@@ -17,7 +17,11 @@ module Warbler
17
17
  include Trait
18
18
 
19
19
  def self.detect?
20
- !War.detect?
20
+ !detect_any_conflicts?
21
+ end
22
+
23
+ def self.conflicts
24
+ [ Traits::War ]
21
25
  end
22
26
 
23
27
  def before_configure
@@ -28,10 +32,6 @@ module Warbler
28
32
  config.init_contents << "#{config.warbler_templates}/jar.erb"
29
33
  end
30
34
 
31
- def after_configure
32
- config.init_contents << StringIO.new("require 'rubygems' unless defined?(Gem)\n")
33
- end
34
-
35
35
  def update_archive(jar)
36
36
  unless config.manifest_file
37
37
  manifest = Warbler::Jar::DEFAULT_MANIFEST.chomp + "Main-Class: JarMain\n"
@@ -23,6 +23,7 @@ module Warbler
23
23
 
24
24
  def before_configure
25
25
  config.jbundler = true
26
+ warn "JBundler support is deprecated due to the EOL of JBundler. See https://github.com/jruby/warbler/issues/481 for discussion on replacement with jar-dependencies."
26
27
  end
27
28
 
28
29
  def after_configure
@@ -35,7 +36,7 @@ module Warbler
35
36
  if File.exist?( classpath )
36
37
  require File.expand_path( classpath )
37
38
  else
38
- raise 'jbundler support needs jruby to create a local config: jruby -S jbundle install'
39
+ raise 'JBundler support needs JRuby to create a local config: jruby -S jbundle install'
39
40
  end
40
41
  # use only the jars from jbundler and jruby
41
42
  config.java_libs += jruby_jars
@@ -16,7 +16,11 @@ module Warbler
16
16
  include ExecutableHelper
17
17
 
18
18
  def self.detect?
19
- Jar.detect? && !Gemspec.detect?
19
+ Jar.detect? && !detect_any_conflicts?
20
+ end
21
+
22
+ def self.conflicts
23
+ [ Traits::Gemspec ]
20
24
  end
21
25
 
22
26
  def before_configure
@@ -12,7 +12,11 @@ module Warbler
12
12
  include Trait
13
13
 
14
14
  def self.detect?
15
- !Rails.detect? && (File.exist?("config.ru") || !Dir['*/config.ru'].empty?)
15
+ (File.exist?("config.ru") || !Dir['*/config.ru'].empty?) && !detect_any_conflicts?
16
+ end
17
+
18
+ def self.conflicts
19
+ [ Traits::Rails ]
16
20
  end
17
21
 
18
22
  def self.requirements
@@ -15,6 +15,10 @@ module Warbler
15
15
  File.exist?('config/environment.rb')
16
16
  end
17
17
 
18
+ def self.conflicts
19
+ [ Traits::Rack ]
20
+ end
21
+
18
22
  def self.requirements
19
23
  [ Traits::War ]
20
24
  end
@@ -21,6 +21,10 @@ module Warbler
21
21
  Traits::Rails.detect? || Traits::Rack.detect?
22
22
  end
23
23
 
24
+ def self.conflicts
25
+ [ Traits::Jar ]
26
+ end
27
+
24
28
  def before_configure
25
29
  config.gem_path = DEFAULT_GEM_PATH
26
30
  config.pathmaps = default_pathmaps
@@ -5,6 +5,7 @@
5
5
  # See the file LICENSE.txt for details.
6
6
  #++
7
7
 
8
+ require 'set'
8
9
  require 'stringio'
9
10
  require 'tsort'
10
11
 
@@ -15,10 +16,13 @@ module Warbler
15
16
  # the kind of project and how it should be packed into the jar or
16
17
  # war file.
17
18
  module Traits
18
- attr_accessor :traits
19
-
20
- def initialize
21
- @traits = auto_detect_traits
19
+ # @param forced_traits [Array<Class>, nil] array of Warbler::Trait types to force rather than auto-detecting them
20
+ def initialize(forced_traits)
21
+ @traits = if forced_traits.nil? || forced_traits.empty?
22
+ auto_detect_traits
23
+ else
24
+ validate_traits(forced_traits)
25
+ end
22
26
  end
23
27
 
24
28
  def auto_detect_traits
@@ -45,6 +49,18 @@ module Warbler
45
49
  @trait_objects = nil
46
50
  @traits.collect! {|t| t.name }
47
51
  end
52
+
53
+ private
54
+ def validate_traits(requested_traits)
55
+ conflicts = Set.new
56
+ requested_traits.each do |trait|
57
+ trait.conflicts.each do |conflict|
58
+ conflicts += [trait, conflict] if requested_traits.include?(conflict)
59
+ end
60
+ end
61
+ raise "Some forced traits declare conflicts with each other: #{conflicts.to_a}" unless conflicts.empty?
62
+ TraitsDependencyArray.new(requested_traits).tsort
63
+ end
48
64
  end
49
65
 
50
66
  # Each trait class includes this module to receive shared functionality.
@@ -53,6 +69,14 @@ module Warbler
53
69
  def requirements
54
70
  []
55
71
  end
72
+
73
+ def conflicts
74
+ []
75
+ end
76
+
77
+ def detect_any_conflicts?
78
+ conflicts.any? { |c| c.detect? }
79
+ end
56
80
  end
57
81
 
58
82
  def self.included(base)
@@ -108,7 +132,7 @@ module Warbler
108
132
 
109
133
  alias tsort_each_node each
110
134
  def tsort_each_child(node, &block)
111
- node.requirements.each(&block)
135
+ node.requirements.select { |r| include?(r) }.each(&block)
112
136
  end
113
137
  end
114
138
 
@@ -6,5 +6,5 @@
6
6
  #++
7
7
 
8
8
  module Warbler
9
- VERSION = "2.1.0"
9
+ VERSION = "2.1.2"
10
10
  end
@@ -106,7 +106,6 @@ CONFIG
106
106
  jar.files["WEB-INF/webserver.properties"] ||= StringIO.new(<<-PROPS)
107
107
  mainclass = org.eclipse.jetty.runner.Runner
108
108
  args = args0,args1,args2,args3,args4,args5,args6
109
- props = jetty.home
110
109
  args0 = --host
111
110
  args1 = {{host}}
112
111
  args2 = --port
@@ -114,7 +113,10 @@ args3 = {{port}}
114
113
  args4 = --config
115
114
  args5 = {{config}}
116
115
  args6 = {{warfile}}
116
+ props = jetty.home,org.eclipse.jetty.util.log.class,org.eclipse.jetty.util.log.stderr.ESCAPE
117
117
  jetty.home = {{webroot}}
118
+ org.eclipse.jetty.util.log.class = org.eclipse.jetty.util.log.StdErrLog
119
+ org.eclipse.jetty.util.log.stderr.ESCAPE = false
118
120
  PROPS
119
121
  end
120
122
  end
data/lib/warbler_jar.jar CHANGED
Binary file
data/warble.rb CHANGED
@@ -1,10 +1,27 @@
1
- # Disable Rake-environment-task framework detection by uncommenting/setting to false
1
+ # Warbler is designed to auto-detect "traits" of your application based on the presence of various files.
2
+ # In some cases this is ambiguous, or there is a desire to disable certain traits from being detected
3
+ # and a list of traits can be supplied to override this.
4
+ #
5
+ # This is an advanced option, and must be a complete list of traits. Using this capability disables
6
+ # some of Warbler's validation and conflict detection that causes traits to be automatically enabled and
7
+ # disabled as required.
8
+ # - `Warbler::Traits::Jar` - package as a normal executable java archive (jar) application
9
+ # - `Warbler::Traits::War` - package as an executable web archive (war) application
10
+ # - `Warbler::Traits::Bundler` - package with the gems implied by a bundle Gemfile/Gemfile.lock
11
+ # - `Warbler::Traits::Gemspec` - package with the gems implied by a gemspec
12
+ # - `Warbler::Traits::NoGemspec` - package only with the gems implied by that in a local `lib` folder
13
+ # - `Warbler::Traits::JBundler` - (deprecated, experimental) package with the jars implied by a `Jarfile`
14
+ # - `Warbler::Traits::Rails` - package with the necessary startup logic to boot a Rails application
15
+ # - `Warbler::Traits::Rack` - package with the necessary startup logic to boot a standalone Rack (non-Rails) application
16
+ # forced_traits = [Warbler::Traits::Jar]
17
+
18
+ # Disable Rake-environment-task framework detection for Rails applications by uncommenting/setting to false
2
19
  # Warbler.framework_detection = false
3
20
 
4
- # Warbler web application assembly configuration file
5
- Warbler::Config.new do |config|
21
+ # Configure a new Warbler application assembly
22
+ Warbler::Config.new(forced_traits: defined?(forced_traits) ? forced_traits : nil) do |config|
6
23
  # Features: additional options controlling how the jar is built.
7
- # Currently the following features are supported:
24
+ # Currently, the following features are supported:
8
25
  # - *gemjar*: package the gem repository in a jar file in WEB-INF/lib
9
26
  # - *executable*: embed a web server and make the war executable
10
27
  # - *runnable*: allows to run bin scripts e.g. `java -jar my.war -S rake -T`
@@ -84,7 +101,7 @@ Warbler::Config.new do |config|
84
101
  # File extension for the archive. Defaults to either 'jar' or 'war'.
85
102
  # config.jar_extension = "jar"
86
103
 
87
- # Destionation for the created archive. Defaults to project's root directory.
104
+ # Destination for the created archive. Defaults to project's root directory.
88
105
  # config.autodeploy_dir = "dist/"
89
106
 
90
107
  # Name of the MANIFEST.MF template for the war file. Defaults to a simple
@@ -101,11 +118,11 @@ Warbler::Config.new do |config|
101
118
  # config.compile_gems = false
102
119
 
103
120
  # When set it specify the bytecode version for compiled class files
104
- # config.bytecode_version = "1.6"
121
+ # config.bytecode_version = "1.8"
105
122
 
106
- # When set to true, Warbler will override the value of ENV['GEM_HOME'] even it
107
- # has already been set. When set to false it will use any existing value of
108
- # GEM_HOME if it is set.
123
+ # When set to true, Warbler will override the value of ENV['GEM_HOME'] even it has already been set.
124
+ # When set to false it will use any existing value of GEM_HOME if it is set. It's usually a bad idea to disable this;
125
+ # your built application will not be self-contained/isolated from the wider RubyGems environment of the machine.
109
126
  # config.override_gem_home = true
110
127
 
111
128
  # Specify executable
@@ -171,7 +188,7 @@ Warbler::Config.new do |config|
171
188
  # is simply embedded in web.xml.
172
189
  # The script is evaluated in a Rack::Builder to load the application.
173
190
  # Examples:
174
- # config.webxml.rackup.path = 'WEB-INF/hello.ru'
191
+ # config.webxml.rackup.path = '/WEB-INF/hello.ru'
175
192
  # config.webxml.rackup = %{require './lib/demo'; run Rack::Adapter::Camping.new(Demo)}
176
193
  # config.webxml.rackup = require 'cgi' && CGI::escapeHTML(File.read("config.ru"))
177
194