Skip to content

Commit 9c12ec3

Browse files
committed
Add forced_traits as an option to Config.new
1 parent 0231112 commit 9c12ec3

5 files changed

Lines changed: 92 additions & 8 deletions

File tree

lib/warbler/config.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Config
3131
# Traits: an array of trait classes corresponding to
3232
# characteristics of the project that are either auto-detected or
3333
# configured.
34-
attr_accessor :traits
34+
attr_reader :traits
3535

3636
# Directory where the war file will be written. Can be used to direct
3737
# Warbler to place your war file directly in your application server's
@@ -183,8 +183,8 @@ class Config
183183
attr_reader :warbler_templates
184184
attr_reader :warbler_scripts
185185

186-
def initialize(warbler_home = WARBLER_HOME)
187-
super()
186+
def initialize(warbler_home = WARBLER_HOME, forced_traits: [])
187+
super(forced_traits)
188188

189189
@warbler_home = warbler_home
190190
@warbler_templates = "#{WARBLER_HOME}/lib/warbler/templates"

lib/warbler/traits.rb

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,28 @@ module Warbler
1515
# the kind of project and how it should be packed into the jar or
1616
# war file.
1717
module Traits
18-
attr_accessor :traits
19-
20-
def initialize
18+
def initialize(forced_traits = [])
19+
@forced_traits = forced_traits
2120
@traits = auto_detect_traits
2221
end
2322

2423
def auto_detect_traits
25-
TraitsDependencyArray.new(Traits.constants.map {|t| Traits.const_get(t)}).tsort.select {|tc| tc.detect? }
24+
all_trait_classes = Traits.constants.map { |t| Traits.const_get(t) }
25+
sorted = TraitsDependencyArray.new(all_trait_classes).tsort
26+
27+
conflicts = @forced_traits.flat_map { |ft| ft.conflicts }.uniq
28+
29+
sorted.select do |tc|
30+
if @forced_traits.include?(tc)
31+
true
32+
elsif conflicts.include?(tc)
33+
false
34+
elsif tc.requirements.any? && tc.requirements.all? { |req| conflicts.include?(req) }
35+
false
36+
else
37+
tc.detect?
38+
end
39+
end
2640
end
2741

2842
def before_configure
@@ -53,6 +67,10 @@ module ClassMethods
5367
def requirements
5468
[]
5569
end
70+
71+
def conflicts
72+
[]
73+
end
5674
end
5775

5876
def self.included(base)

lib/warbler/traits/jar.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ def self.detect?
2020
!War.detect?
2121
end
2222

23+
def self.conflicts
24+
[War]
25+
end
26+
2327
def before_configure
2428
config.gem_path = '/'
2529
config.pathmaps = default_pathmaps

lib/warbler/traits/war.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class War
1818
DEFAULT_GEM_PATH = '/WEB-INF/gems'
1919

2020
def self.detect?
21-
Traits::Rails.detect? || Traits::Rack.detect?
21+
Rails.detect? || Rack.detect?
22+
end
23+
24+
def self.conflicts
25+
[Jar]
2226
end
2327

2428
def before_configure

spec/warbler/traits_spec.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,62 @@
1818
end
1919
end
2020
end
21+
22+
describe "conflicts" do
23+
it "Jar conflicts with War" do
24+
expect(Warbler::Traits::Jar.conflicts).to include(Warbler::Traits::War)
25+
end
26+
27+
it "War conflicts with Jar" do
28+
expect(Warbler::Traits::War.conflicts).to include(Warbler::Traits::Jar)
29+
end
30+
31+
it "traits with no declared conflicts return an empty array" do
32+
expect(Warbler::Traits::Bundler.conflicts).to eq([])
33+
end
34+
end
35+
36+
describe "forced_traits" do
37+
context "in a Rack project with Bundler" do
38+
run_in_directory 'spec/sample_bundler'
39+
40+
it "auto-detects War trait by default" do
41+
config = Warbler::Config.new
42+
expect(config.traits).to include(Warbler::Traits::War)
43+
expect(config.traits).to include(Warbler::Traits::Rack)
44+
expect(config.traits).to_not include(Warbler::Traits::Jar)
45+
end
46+
47+
it "forces Jar and excludes War when Jar is forced" do
48+
config = Warbler::Config.new(forced_traits: [Warbler::Traits::Jar])
49+
expect(config.traits).to include(Warbler::Traits::Jar)
50+
expect(config.traits).to_not include(Warbler::Traits::War)
51+
end
52+
53+
it "excludes traits that require an excluded trait" do
54+
config = Warbler::Config.new(forced_traits: [Warbler::Traits::Jar])
55+
expect(config.traits).to_not include(Warbler::Traits::Rack)
56+
end
57+
58+
it "preserves non-conflicting auto-detected traits" do
59+
config = Warbler::Config.new(forced_traits: [Warbler::Traits::Jar])
60+
expect(config.traits).to include(Warbler::Traits::Bundler)
61+
end
62+
63+
it "runs before_configure with forced traits" do
64+
config = Warbler::Config.new(forced_traits: [Warbler::Traits::Jar])
65+
expect(config.jar_extension).to eq('jar')
66+
end
67+
end
68+
69+
context "with no forced traits" do
70+
run_in_directory 'spec/sample_jar'
71+
72+
it "behaves identically to auto-detection" do
73+
default_config = Warbler::Config.new
74+
forced_config = Warbler::Config.new(forced_traits: [])
75+
expect(forced_config.traits).to eq(default_config.traits)
76+
end
77+
end
78+
end
2179
end

0 commit comments

Comments
 (0)