buildr 1.4.4-x86-mswin32 → 1.4.5-x86-mswin32

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 (103) hide show
  1. data/CHANGELOG +46 -0
  2. data/Rakefile +0 -1
  3. data/addon/buildr/bnd.rb +147 -0
  4. data/addon/buildr/jaxb_xjc.rb +72 -0
  5. data/addon/buildr/protobuf.rb +14 -1
  6. data/buildr.gemspec +6 -2
  7. data/doc/artifacts.textile +6 -0
  8. data/doc/contributing.textile +3 -0
  9. data/doc/download.textile +60 -0
  10. data/doc/index.textile +9 -15
  11. data/doc/installing.textile +23 -6
  12. data/doc/mailing_lists.textile +4 -0
  13. data/doc/more_stuff.textile +333 -6
  14. data/doc/packaging.textile +187 -1
  15. data/lib/buildr.rb +8 -1
  16. data/lib/buildr/clojure.rb +34 -0
  17. data/lib/buildr/clojure/shell.rb +52 -0
  18. data/lib/buildr/core.rb +3 -0
  19. data/lib/buildr/core/#application.rb# +700 -0
  20. data/lib/buildr/core/application.rb +18 -8
  21. data/lib/buildr/core/build.rb +2 -2
  22. data/lib/buildr/core/cc.rb +57 -63
  23. data/lib/buildr/core/checks.rb +4 -5
  24. data/lib/buildr/core/doc.rb +3 -1
  25. data/lib/buildr/core/generate.rb +2 -0
  26. data/lib/buildr/core/jrebel.rb +42 -0
  27. data/lib/buildr/core/linux.rb +30 -0
  28. data/lib/buildr/core/project.rb +9 -8
  29. data/lib/buildr/core/run.rb +3 -3
  30. data/lib/buildr/core/shell.rb +29 -90
  31. data/lib/buildr/core/test.rb +3 -3
  32. data/lib/buildr/core/transports.rb +5 -5
  33. data/lib/buildr/core/util.rb +2 -2
  34. data/lib/buildr/groovy.rb +1 -0
  35. data/lib/buildr/groovy/compiler.rb +12 -1
  36. data/lib/buildr/groovy/doc.rb +76 -0
  37. data/lib/buildr/groovy/shell.rb +24 -15
  38. data/lib/buildr/ide.rb +1 -1
  39. data/lib/buildr/ide/idea.rb +527 -141
  40. data/lib/buildr/java/bdd.rb +18 -13
  41. data/lib/buildr/java/ecj.rb +1 -3
  42. data/lib/buildr/java/jtestr_result.rb +295 -0
  43. data/lib/buildr/java/jtestr_runner.rb.erb +4 -6
  44. data/lib/buildr/java/packaging.rb +14 -3
  45. data/lib/buildr/java/pom.rb +6 -2
  46. data/lib/buildr/java/test_result.rb +15 -243
  47. data/lib/buildr/java/tests.rb +1 -1
  48. data/lib/buildr/packaging.rb +2 -1
  49. data/lib/buildr/packaging/#package.rb.rej# +19 -0
  50. data/lib/buildr/packaging/archive.rb +13 -3
  51. data/lib/buildr/packaging/artifact.rb +11 -12
  52. data/lib/buildr/packaging/tar.rb +4 -1
  53. data/lib/buildr/packaging/zip.rb +106 -1
  54. data/lib/buildr/resources/completed.png +0 -0
  55. data/lib/buildr/resources/failed.png +0 -0
  56. data/lib/buildr/resources/icons-license.txt +17 -0
  57. data/lib/buildr/run.rb +7 -14
  58. data/lib/buildr/scala/#Untitled-2# +7 -0
  59. data/lib/buildr/scala/bdd.rb +1 -1
  60. data/lib/buildr/scala/compiler.rb +1 -1
  61. data/lib/buildr/scala/doc.rb +20 -2
  62. data/lib/buildr/scala/shell.rb +14 -22
  63. data/lib/buildr/scala/tests.rb +2 -2
  64. data/lib/buildr/shell.rb +113 -108
  65. data/lib/buildr/version.rb +1 -1
  66. data/rakelib/checks.rake +9 -7
  67. data/rakelib/doc.rake +10 -0
  68. data/rakelib/release.rake +9 -0
  69. data/rakelib/rspec.rake +27 -28
  70. data/rakelib/setup.rake +1 -1
  71. data/rakelib/stage.rake +2 -2
  72. data/spec/addon/bnd_spec.rb +330 -0
  73. data/spec/addon/jaxb_xjc_spec.rb +125 -0
  74. data/spec/core/application_spec.rb +1 -1
  75. data/spec/core/build_spec.rb +7 -7
  76. data/spec/core/cc_spec.rb +154 -104
  77. data/spec/core/compile_spec.rb +3 -3
  78. data/spec/core/project_spec.rb +10 -0
  79. data/spec/core/run_spec.rb +1 -0
  80. data/spec/core/shell_spec.rb +146 -0
  81. data/spec/groovy/doc_spec.rb +65 -0
  82. data/spec/ide/eclipse_spec.rb +1 -1
  83. data/spec/ide/idea_spec.rb +1145 -0
  84. data/spec/java/bdd_spec.rb +3 -3
  85. data/spec/java/emma_spec.rb +2 -0
  86. data/spec/java/packaging_spec.rb +40 -11
  87. data/spec/java/test_coverage_helper.rb +1 -1
  88. data/spec/packaging/archive_spec.rb +76 -21
  89. data/spec/packaging/artifact_namespace_spec.rb +1 -1
  90. data/spec/packaging/artifact_spec.rb +14 -7
  91. data/spec/sandbox.rb +11 -4
  92. data/spec/scala/bdd_spec.rb +2 -2
  93. data/spec/scala/compiler_spec.rb +2 -2
  94. data/spec/scala/doc_spec.rb +24 -4
  95. data/spec/scala/scala.rb +2 -2
  96. data/spec/scala/tests_spec.rb +2 -2
  97. data/spec/spec_helpers.rb +9 -8
  98. data/spec/xpath_matchers.rb +121 -0
  99. metadata +246 -166
  100. data/lib/buildr/ide/idea.ipr.template +0 -300
  101. data/lib/buildr/ide/idea7x.ipr.template +0 -290
  102. data/lib/buildr/ide/idea7x.rb +0 -231
  103. data/spec/ide/idea7x_spec.rb +0 -96
@@ -19,14 +19,16 @@ require 'buildr/java/commands'
19
19
  require 'buildr/core/util'
20
20
 
21
21
  module Buildr
22
+
22
23
  module Shell
23
24
 
24
25
  class BeanShell < Base
25
-
26
- include JavaRebel
26
+ include Buildr::JRebel
27
27
 
28
28
  VERSION = '2.0b4'
29
29
 
30
+ specify :name => :bsh, :languages => [:java]
31
+
30
32
  class << self
31
33
  def version
32
34
  Buildr.settings.build['bsh'] || VERSION
@@ -35,22 +37,16 @@ module Buildr
35
37
  def artifact
36
38
  "org.beanshell:bsh:jar:#{version}"
37
39
  end
38
-
39
- def lang
40
- :java
41
- end
42
-
43
- def to_sym
44
- :bsh
45
- end
46
40
  end
47
41
 
48
- def launch
49
- cp = project.compile.dependencies + [project.path_to(:target, :classes), Buildr.artifact(BeanShell.artifact)]
42
+ def launch(task)
43
+ cp = ( project.compile.dependencies +
44
+ [project.path_to(:target, :classes), Buildr.artifact(BeanShell.artifact)] +
45
+ task.classpath )
50
46
  Java::Commands.java 'bsh.Console', {
51
- :properties => rebel_props(project),
47
+ :properties => jrebel_props(project).merge(task.properties),
52
48
  :classpath => cp,
53
- :java_args => rebel_args
49
+ :java_args => jrebel_args + task.java_args
54
50
  }
55
51
  end
56
52
 
@@ -58,26 +54,23 @@ module Buildr
58
54
 
59
55
 
60
56
  class JIRB < Base
61
- include JavaRebel
57
+ include JRebel
62
58
 
63
59
  JRUBY_VERSION = '1.4.0'
64
60
 
65
- class << self
66
- def lang
67
- :none
68
- end
69
- end
70
-
71
- def launch
61
+ def launch(task)
72
62
  if jruby_home # if JRuby is installed, use it
73
63
  cp = project.compile.dependencies +
74
64
  [project.path_to(:target, :classes)] +
75
- Dir.glob("#{jruby_home}#{File::SEPARATOR}lib#{File::SEPARATOR}*.jar")
65
+ Dir.glob("#{jruby_home}#{File::SEPARATOR}lib#{File::SEPARATOR}*.jar") +
66
+ task.classpath
76
67
 
77
68
  props = {
78
69
  'jruby.home' => jruby_home,
79
70
  'jruby.lib' => "#{jruby_home}#{File::SEPARATOR}lib"
80
71
  }
72
+ props.merge! jrebel_props(project)
73
+ props.merge! task.properties
81
74
 
82
75
  if not Util.win_os?
83
76
  uname = `uname -m`
@@ -104,26 +97,27 @@ module Buildr
104
97
 
105
98
  args = [
106
99
  "-Xbootclasspath/a:#{Dir.glob("#{jruby_home}#{File::SEPARATOR}lib#{File::SEPARATOR}jruby*.jar").join File::PATH_SEPARATOR}"
107
- ]
100
+ ] + jrebel_args + task.java_args
108
101
 
109
102
  Java::Commands.java 'org.jruby.Main', "#{jruby_home}#{File::SEPARATOR}bin#{File::SEPARATOR}jirb", {
110
- :properties => props.merge(rebel_props(project)),
103
+ :properties => props,
111
104
  :classpath => cp,
112
- :java_args => args + rebel_args
105
+ :java_args => args
113
106
  }
114
107
  else
115
- cp = project.compile.dependencies + [
116
- jruby_artifact,
117
- project.path_to(:target, :classes)
118
- ]
108
+ cp = project.compile.dependencies + [ jruby_artifact, project.path_to(:target, :classes) ] +
109
+ task.classpath
110
+ props = jrebel_props(project).merge(task.properties)
111
+ args = jrebel_args + task.java_args
119
112
 
120
113
  Java::Commands.java 'org.jruby.Main', '--command', 'irb', {
121
- :properties => rebel_props(project),
114
+ :properties => props,
122
115
  :classpath => cp,
123
- :java_args => rebel_args
116
+ :java_args => args
124
117
  }
125
118
  end
126
119
  end
120
+
127
121
  private
128
122
  def jruby_home
129
123
  @jruby_home ||= RUBY_PLATFORM =~ /java/ ? Config::CONFIG['prefix'] : ENV['JRUBY_HOME']
@@ -135,64 +129,9 @@ module Buildr
135
129
  end
136
130
 
137
131
  end
138
-
139
- class Clojure < Base
140
- include JavaRebel
141
-
142
- JLINE_VERSION = '0.9.94'
143
-
144
- class << self
145
- def lang
146
- :none
147
- end
148
-
149
- def to_sym
150
- :clj # more common than `clojure`
151
- end
152
- end
153
-
154
- # don't build if it's *only* Clojure sources
155
- def build?
156
- !has_source?(:clojure) or has_source?(:java) or has_source?(:scala) or has_source?(:groovy)
157
- end
158
-
159
- def launch
160
- fail 'Are we forgetting something? CLOJURE_HOME not set.' unless clojure_home
161
-
162
- cp = project.compile.dependencies +
163
- [
164
- if build?
165
- project.path_to(:target, :classes)
166
- else
167
- project.path_to(:src, :main, :clojure)
168
- end,
169
- File.expand_path('clojure.jar', clojure_home),
170
- 'jline:jline:jar:0.9.94'
171
- ]
172
-
173
- if build?
174
- Java::Commands.java 'jline.ConsoleRunner', 'clojure.lang.Repl', {
175
- :properties => rebel_props(project),
176
- :classpath => cp,
177
- :java_args => rebel_args
178
- }
179
- else
180
- Java::Commands.java 'jline.ConsoleRunner', 'clojure.lang.Repl', :classpath => cp
181
- end
182
- end
183
-
184
- private
185
- def clojure_home
186
- @home ||= ENV['CLOJURE_HOME']
187
- end
188
-
189
- def has_source?(lang)
190
- File.exists? project.path_to(:src, :main, lang)
191
- end
192
- end
193
132
  end
194
133
  end
195
134
 
196
- Buildr::ShellProviders << Buildr::Shell::BeanShell
197
- Buildr::ShellProviders << Buildr::Shell::JIRB
198
- Buildr::ShellProviders << Buildr::Shell::Clojure
135
+ Buildr::Shell.providers << Buildr::Shell::BeanShell
136
+ Buildr::Shell.providers << Buildr::Shell::JIRB
137
+
@@ -193,8 +193,8 @@ module Buildr
193
193
 
194
194
  # Used by the test/integration to include specific tests
195
195
  def include(includes)
196
+ includes = wildcardify(Array(includes))
196
197
  Project.projects.each do |project|
197
- includes = wildcardify(includes)
198
198
  project.test.send :include, *includes if includes.size > 0
199
199
  project.test.send :forced_need=, true
200
200
  end
@@ -202,8 +202,8 @@ module Buildr
202
202
 
203
203
  # Used by the test/integration to exclude specific tests
204
204
  def exclude(excludes)
205
+ excludes = wildcardify(Array(excludes))
205
206
  Project.projects.each do |project|
206
- excludes = wildcardify(excludes)
207
207
  project.test.send :exclude, *excludes if excludes.size > 0
208
208
  project.test.send :forced_need=, true
209
209
  end
@@ -646,7 +646,7 @@ module Buildr
646
646
  excludes.map! { |t| t[1..-1] }
647
647
 
648
648
  TestTask.clear
649
- TestTask.include(includes.empty? ? '*' : includes)
649
+ TestTask.include(includes.empty? ? ['*'] : includes)
650
650
  TestTask.exclude excludes
651
651
  end
652
652
  task('test').invoke
@@ -214,14 +214,14 @@ module URI
214
214
  elsif source.respond_to?(:read)
215
215
  digests = (options[:digests] || [:md5, :sha1]).
216
216
  inject({}) { |hash, name| hash[name] = Digest.const_get(name.to_s.upcase).new ; hash }
217
- size = source.size rescue nil
217
+ size = source.stat.size rescue nil
218
218
  write (options).merge(:progress=>verbose && size, :size=>size) do |bytes|
219
219
  source.read(bytes).tap do |chunk|
220
220
  digests.values.each { |digest| digest << chunk } if chunk
221
221
  end
222
222
  end
223
223
  digests.each do |key, digest|
224
- self.merge("#{self.path}.#{key}").write "#{digest.hexdigest} #{File.basename(path)}",
224
+ self.merge("#{self.path}.#{key}").write digest.hexdigest,
225
225
  (options).merge(:progress=>false)
226
226
  end
227
227
  else
@@ -406,7 +406,7 @@ module URI
406
406
  SFTP.passwords[host] = ssh_options[:password]
407
407
  trace 'connected'
408
408
 
409
- with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress|
409
+ with_progress_bar options[:progress] && options[:size], path.split('/').last, options[:size] || 0 do |progress|
410
410
  trace "Downloading from #{path}"
411
411
  sftp.file.open(path, 'r') do |file|
412
412
  while chunk = file.read(RW_CHUNK_SIZE)
@@ -450,7 +450,7 @@ module URI
450
450
  "#{combined}/"
451
451
  end
452
452
 
453
- with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress|
453
+ with_progress_bar options[:progress] && options[:size], path.split('/').last, options[:size] || 0 do |progress|
454
454
  trace "Uploading to #{path}"
455
455
  sftp.file.open(path, 'w') do |file|
456
456
  while chunk = yield(RW_CHUNK_SIZE)
@@ -546,7 +546,7 @@ module URI
546
546
  raise ArgumentError, 'Either you\'re attempting to write a file to another host (which we don\'t support), or you used two slashes by mistake, where you should have file:///<path>.' if host
547
547
  temp = Tempfile.new(File.basename(path))
548
548
  temp.binmode
549
- with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress|
549
+ with_progress_bar options[:progress] && options[:size], path.split('/').last, options[:size] || 0 do |progress|
550
550
  while chunk = yield(RW_CHUNK_SIZE)
551
551
  temp.write chunk
552
552
  progress << chunk
@@ -484,8 +484,8 @@ if Buildr::Util.java_platform?
484
484
  arg_str = args.map { |a| "'#{a}'" }
485
485
  __native_system__(cd + cmd.first + ' ' + arg_str.join(' '))
486
486
  end
487
- $? = Buildr::ProcessStatus.new(0, res == 0, res) # KLUDGE
488
- block.call(res == 0, $?)
487
+ status = Buildr::ProcessStatus.new(0, res == 0, res) # KLUDGE
488
+ block.call(res == 0, status)
489
489
  end
490
490
  end
491
491
 
data/lib/buildr/groovy.rb CHANGED
@@ -16,4 +16,5 @@
16
16
 
17
17
  require 'buildr/groovy/compiler'
18
18
  require 'buildr/groovy/bdd'
19
+ require 'buildr/groovy/doc'
19
20
  require 'buildr/groovy/shell'
@@ -16,6 +16,17 @@
16
16
 
17
17
  module Buildr::Groovy
18
18
 
19
+ REQUIRES = ArtifactNamespace.for(self) do |ns|
20
+ ns.jansi! 'org.fusesource.jansi:jansi:jar:1.2.1'
21
+ ns.jline! 'jline:jline:jar:0.9.94'
22
+ end
23
+
24
+ class << self
25
+ def dependencies #:nodoc:
26
+ REQUIRES.artifacts + Groovyc.dependencies
27
+ end
28
+ end
29
+
19
30
  # Groovyc compiler:
20
31
  # compile.using(:groovyc)
21
32
  #
@@ -57,7 +68,7 @@ module Buildr::Groovy
57
68
  #
58
69
  # namespace before this file is required.
59
70
  REQUIRES = ArtifactNamespace.for(self) do |ns|
60
- ns.groovy! 'org.codehaus.groovy:groovy:jar:>=1.7.1'
71
+ ns.groovy! 'org.codehaus.groovy:groovy:jar:>=1.7.5'
61
72
  ns.commons_cli! 'commons-cli:commons-cli:jar:>=1.2'
62
73
  ns.asm! 'asm:asm:jar:>=3.2'
63
74
  ns.antlr! 'antlr:antlr:jar:>=2.7.7'
@@ -0,0 +1,76 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ require 'buildr/core/doc'
17
+ require 'buildr/groovy/compiler' # ensure Groovy dependencies are ready
18
+
19
+ module Buildr
20
+ module Doc
21
+
22
+ module GroovydocDefaults
23
+ include Extension
24
+
25
+ # Default groovydoc -doc-title to project's comment or name
26
+ after_define(:groovydoc => :doc) do |project|
27
+ if project.doc.engine? Groovydoc
28
+ options = project.doc.options
29
+ options[:windowtitle] = (project.comment || project.name) unless options[:windowtitle]
30
+ end
31
+ end
32
+ end
33
+
34
+ class Groovydoc < Base
35
+ specify :language => :groovy, :source_ext => ['java', 'groovy']
36
+
37
+ def generate(sources, target, options = {})
38
+ mkdir_p target
39
+ cmd_args = [ '-d', target, trace?(:groovydoc) ? '-verbose' : nil ].compact
40
+ options.reject { |key, value| [:sourcepath, :classpath].include?(key) }.
41
+ each { |key, value| value.invoke if value.respond_to?(:invoke) }.
42
+ each do |key, value|
43
+ case value
44
+ when true, nil
45
+ cmd_args << "-#{key}"
46
+ when false
47
+ cmd_args << "-no#{key}"
48
+ when Hash
49
+ value.each { |k,v| cmd_args << "-#{key}" << k.to_s << v.to_s }
50
+ else
51
+ cmd_args += Array(value).map { |item| ["-#{key}", item.to_s] }.flatten
52
+ end
53
+ end
54
+ [:sourcepath, :classpath].each do |option|
55
+ Array(options[option]).flatten.tap do |paths|
56
+ cmd_args << "-#{option}" << paths.flatten.map(&:to_s).join(File::PATH_SEPARATOR) unless paths.empty?
57
+ end
58
+ end
59
+ cmd_args += sources.flatten.uniq
60
+ unless Buildr.application.options.dryrun
61
+ info "Generating Groovydoc for #{project.name}"
62
+ trace (['groovydoc'] + cmd_args).join(' ')
63
+ result = Java::Commands.java('org.codehaus.groovy.tools.groovydoc.Main', cmd_args,
64
+ :classpath => Buildr::Groovy.dependencies)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ class Project
71
+ include GroovydocDefaults
72
+ end
73
+ end
74
+
75
+ Buildr::Doc.engines << Buildr::Doc::Groovydoc
76
+
@@ -18,25 +18,34 @@ require 'buildr/shell'
18
18
  module Buildr
19
19
  module Groovy
20
20
  class GroovySH < Buildr::Shell::Base
21
+ include JRebel
22
+
21
23
  SUFFIX = if Util.win_os? then '.bat' else '' end
22
24
 
23
- class << self
24
- def lang
25
- :groovy
25
+ specify :name => :groovy, :languages => [:groovy]
26
+
27
+ def launch(task)
28
+ cp = Groovy.dependencies +
29
+ project.compile.dependencies +
30
+ [ project.path_to(:target, :classes) ] +
31
+ task.classpath
32
+ props = jrebel_props(project).merge(task.properties)
33
+ java_args = jrebel_args + task.java_args
34
+
35
+ groovy_home = nil
36
+ if groovy_home
37
+ cmd_args = " -classpath '#{cp.join(File::SEPARATOR)}'"
38
+ trace "groovysh #{cmd_args}"
39
+ system(File.expand_path("bin#{File::SEPARATOR}groovysh#{SUFFIX}", groovy_home) + cmd_args)
40
+ else
41
+ Java::Commands.java 'org.codehaus.groovy.tools.shell.Main', {
42
+ :properties => props,
43
+ :classpath => cp,
44
+ :java_args => java_args
45
+ }
26
46
  end
27
47
  end
28
48
 
29
- def launch
30
- fail 'Are we forgetting something? GROOVY_HOME not set.' unless groovy_home
31
-
32
- cp = project.compile.dependencies.join(File::PATH_SEPARATOR) +
33
- File::PATH_SEPARATOR + project.path_to(:target, :classes)
34
-
35
- cmd_args = " -classpath '#{cp}'"
36
- trace "groovysh #{cmd_args}"
37
- system(File.expand_path("bin#{File::SEPARATOR}groovysh#{SUFFIX}", groovy_home) + cmd_args)
38
- end
39
-
40
49
  private
41
50
  def groovy_home
42
51
  @home ||= ENV['GROOVY_HOME']
@@ -45,4 +54,4 @@ module Buildr
45
54
  end
46
55
  end
47
56
 
48
- Buildr::ShellProviders << Buildr::Groovy::GroovySH
57
+ Buildr::Shell.providers << Buildr::Groovy::GroovySH
data/lib/buildr/ide.rb CHANGED
@@ -16,4 +16,4 @@
16
16
 
17
17
  require 'buildr/ide/eclipse'
18
18
  require 'buildr/ide/idea'
19
- require 'buildr/ide/idea7x'
19
+
@@ -20,171 +20,557 @@ require 'stringio'
20
20
 
21
21
 
22
22
  module Buildr
23
- module Idea #:nodoc:
23
+ module IntellijIdea
24
+ # Abstract base class for IdeaModule and IdeaProject
25
+ class IdeaFile
26
+ DEFAULT_SUFFIX = ""
27
+
28
+ attr_reader :buildr_project
29
+ attr_writer :suffix
30
+ attr_writer :id
31
+ attr_accessor :template
32
+
33
+ def suffix
34
+ @suffix ||= DEFAULT_SUFFIX
35
+ end
24
36
 
25
- include Extension
37
+ def filename
38
+ buildr_project.path_to("#{name}.#{extension}")
39
+ end
26
40
 
27
- first_time do
28
- # Global task "idea" generates artifacts for all projects.
29
- desc "Generate Idea artifacts for all projects"
30
- Project.local_task "idea"=>"artifacts"
31
- end
41
+ def id
42
+ @id ||= buildr_project.name.split(':').last
43
+ end
44
+
45
+ def add_component(name, attrs = {}, &xml)
46
+ self.components << create_component(name, attrs, &xml)
47
+ end
48
+
49
+ def write(f)
50
+ document.write f
51
+ end
52
+
53
+ protected
54
+
55
+ def name
56
+ "#{self.id}#{suffix}"
57
+ end
32
58
 
33
- before_define(:idea) do |project|
34
- project.recursive_task("idea")
59
+ def create_component(name, attrs = {})
60
+ target = StringIO.new
61
+ Builder::XmlMarkup.new(:target => target, :indent => 2).component(attrs.merge({:name => name})) do |xml|
62
+ yield xml if block_given?
63
+ end
64
+ REXML::Document.new(target.string).root
65
+ end
66
+
67
+ def components
68
+ @components ||= self.default_components.compact
69
+ end
70
+
71
+ def load_document(filename)
72
+ REXML::Document.new(File.read(filename))
73
+ end
74
+
75
+ def document
76
+ if File.exist?(self.filename)
77
+ doc = load_document(self.filename)
78
+ else
79
+ doc = base_document
80
+ inject_components(doc, self.initial_components)
81
+ end
82
+ if self.template
83
+ template_doc = load_document(self.template)
84
+ REXML::XPath.each(template_doc, "//component") do |element|
85
+ inject_component(doc, element)
86
+ end
87
+ end
88
+ inject_components(doc, self.components)
89
+ doc
90
+ end
91
+
92
+ def inject_components(doc, components)
93
+ components.each do |component|
94
+ # execute deferred components
95
+ component = component.call if Proc === component
96
+ inject_component(doc, component) if component
97
+ end
98
+ end
99
+
100
+ # replace overridden component (if any) with specified component
101
+ def inject_component(doc, component)
102
+ doc.root.delete_element("//component[@name='#{component.attributes['name']}']")
103
+ doc.root.add_element component
104
+ end
35
105
  end
36
106
 
37
- after_define(:idea => :package) do |project|
38
- idea = project.task("idea")
39
- # We need paths relative to the top project's base directory.
40
- root_path = lambda { |p| f = lambda { |p| p.parent ? f[p.parent] : p.base_dir }; f[p] }[project]
41
-
42
- # Find a path relative to the project's root directory.
43
- relative = lambda { |path| Util.relative_path(path.to_s, project.path_to) }
44
-
45
- m2repo = Buildr::Repositories.instance.local
46
- excludes = [ '**/.svn/', '**/CVS/' ].join('|')
47
-
48
- # Only for projects that are packageable.
49
- task_name = project.path_to("#{project.name.gsub(':', '-')}.iml")
50
- idea.enhance [ file(task_name) ]
51
-
52
- # The only thing we need to look for is a change in the Buildfile.
53
- file(task_name=>Buildr.application.buildfile) do |task|
54
- info "Writing #{task.name}"
55
-
56
- # Idea handles modules slightly differently if they're WARs
57
- idea_types = Hash.new("JAVA_MODULE")
58
- idea_types["war"] = "J2EE_WEB_MODULE"
59
-
60
- # Note: Use the test classpath since Eclipse compiles both "main" and "test" classes using the same classpath
61
- deps = project.test.compile.dependencies.map(&:to_s) - [ project.compile.target.to_s ]
62
-
63
- # Convert classpath elements into applicable Project objects
64
- deps.collect! { |path| Buildr.projects.detect { |prj| prj.packages.detect { |pkg| pkg.to_s == path } } || path }
65
-
66
- # project_libs: artifacts created by other projects
67
- project_libs, others = deps.partition { |path| path.is_a?(Project) }
68
-
69
- # Separate artifacts from Maven2 repository
70
- m2_libs, others = others.partition { |path| path.to_s.index(m2repo) == 0 }
71
-
72
- # Generated: classpath elements in the project are assumed to be generated
73
- generated, libs = others.partition { |path| path.to_s.index(project.path_to.to_s) == 0 }
74
-
75
- # Project type is going to be the first package type
76
- if package = project.packages.first
77
- File.open(task.name, "w") do |file|
78
- xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
79
-
80
- xml.module(:version=>"4", :relativePaths=>"false", :type=>idea_types[package.type.to_s]) do
81
- xml.component :name=>"ModuleRootManager"
82
- xml.component "name"=>"NewModuleRootManager", "inherit-compiler-output"=>"false" do
83
- has_compile_sources = project.compile.target.to_s.size > 0
84
- xml.output :url=>"file://$MODULE_DIR$/#{relative[project.compile.target.to_s]}" if has_compile_sources
85
- xml.tag! "exclude-output"
86
-
87
- # TODO project.test.target isn't recognized, what's the proper way to get the test compile path?
88
- xml.tag! "output-test", :url=>"file://$MODULE_DIR$/target/test-classes"
89
-
90
- xml.content(:url=>"file://$MODULE_DIR$") do
91
- if has_compile_sources
92
- srcs = project.compile.sources.map { |src| relative[src.to_s] } + generated.map { |src| relative[src.to_s] }
93
- srcs.sort.uniq.each do |path|
94
- xml.sourceFolder :url=>"file://$MODULE_DIR$/#{path}", :isTestSource=>"false"
95
- end
96
-
97
- test_sources = project.test.compile.sources.map { |src| relative[src.to_s] }
98
- test_sources.each do |paths|
99
- paths.sort.uniq.each do |path|
100
- xml.sourceFolder :url=>"file://$MODULE_DIR$/#{path}", :isTestSource=>"true"
101
- end
102
- end
103
- end
104
- [project.resources=>false, project.test.resources=>true].each do |resources, test|
105
- resources.each do |path|
106
- path[0].sources.each do |srcpath|
107
- xml.sourceFolder :url=>"file://#{srcpath}", :isTestSource=>path[1].to_s
108
- end
109
- end
110
- end
111
- xml.excludeFolder :url=>"file://$MODULE_DIR$/#{relative[project.compile.target.to_s]}" if has_compile_sources
112
- end
113
-
114
- xml.orderEntry :type=>"sourceFolder", :forTests=>"false"
115
- xml.orderEntry :type=>"inheritedJdk"
116
-
117
- # Classpath elements from other projects
118
- project_libs.map(&:id).sort.uniq.each do |project_id|
119
- xml.orderEntry :type=>'module', "module-name"=>project_id
120
- end
121
-
122
- # Libraries
123
- ext_libs = libs.map {|path| "$MODULE_DIR$/#{path.to_s}" } +
124
- m2_libs.map { |path| path.to_s.sub(m2repo, "$M2_REPO$") }
125
- ext_libs.each do |path|
126
- xml.orderEntry :type=>"module-library" do
127
- xml.library do
128
- xml.CLASSES do
129
- xml.root :url=>"jar://#{path}!/"
130
- end
131
- xml.JAVADOC
132
- xml.SOURCES do
133
- xml.root :url=>"jar://#{path.sub(/\.jar$/, "-sources.jar")}!/"
134
- end
135
- end
136
- end
137
- end
138
-
139
- xml.orderEntryProperties
107
+ # IdeaModule represents an .iml file
108
+ class IdeaModule < IdeaFile
109
+ DEFAULT_TYPE = "JAVA_MODULE"
110
+ DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE = "MAVEN_REPOSITORY"
111
+
112
+ attr_accessor :type
113
+ attr_accessor :local_repository_env_override
114
+ attr_accessor :group
115
+ attr_reader :facets
116
+
117
+ def initialize
118
+ @type = DEFAULT_TYPE
119
+ @local_repository_env_override = DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE
120
+ end
121
+
122
+ def buildr_project=(buildr_project)
123
+ @id = nil
124
+ @facets = []
125
+ @skip_content = false
126
+ @buildr_project = buildr_project
127
+ end
128
+
129
+ def extension
130
+ "iml"
131
+ end
132
+
133
+ def main_source_directories
134
+ @main_source_directories ||= [
135
+ buildr_project.compile.sources,
136
+ buildr_project.resources.sources
137
+ ].flatten.compact
138
+ end
139
+
140
+ def test_source_directories
141
+ @test_source_directories ||= [
142
+ buildr_project.test.compile.sources,
143
+ buildr_project.test.resources.sources
144
+ ].flatten.compact
145
+ end
146
+
147
+ def excluded_directories
148
+ @excluded_directories ||= [
149
+ buildr_project.resources.target,
150
+ buildr_project.test.resources.target,
151
+ buildr_project.path_to(:target, :main),
152
+ buildr_project.path_to(:target, :test),
153
+ buildr_project.path_to(:reports)
154
+ ].flatten.compact
155
+ end
156
+
157
+ attr_writer :main_output_dir
158
+
159
+ def main_output_dir
160
+ @main_output_dir ||= buildr_project._(:target, :main, :java)
161
+ end
162
+
163
+ attr_writer :test_output_dir
164
+
165
+ def test_output_dir
166
+ @test_output_dir ||= buildr_project._(:target, :test, :java)
167
+ end
168
+
169
+ def main_dependencies
170
+ @main_dependencies ||= buildr_project.compile.dependencies
171
+ end
172
+
173
+ def test_dependencies
174
+ @test_dependencies ||= buildr_project.test.compile.dependencies
175
+ end
176
+
177
+ def add_facet(name, type)
178
+ target = StringIO.new
179
+ Builder::XmlMarkup.new(:target => target, :indent => 2).facet(:name => name, :type => type) do |xml|
180
+ yield xml if block_given?
181
+ end
182
+ self.facets << REXML::Document.new(target.string).root
183
+ end
184
+
185
+ def skip_content?
186
+ !!@skip_content
187
+ end
188
+
189
+ def skip_content!
190
+ @skip_content = true
191
+ end
192
+
193
+ protected
194
+
195
+ def test_dependency_details
196
+ main_dependencies_paths = main_dependencies.map(&:to_s)
197
+ target_dir = buildr_project.compile.target.to_s
198
+ test_dependencies.select { |d| d.to_s != target_dir }.collect do |d|
199
+ dependency_path = d.to_s
200
+ export = main_dependencies_paths.include?(dependency_path)
201
+ source_path = nil
202
+ if d.respond_to?(:to_spec_hash)
203
+ source_spec = d.to_spec_hash.merge(:classifier => 'sources')
204
+ source_path = Buildr.artifact(source_spec).to_s
205
+ source_path = nil unless File.exist?(source_path)
206
+ end
207
+ [dependency_path, export, source_path]
208
+ end
209
+
210
+ end
211
+
212
+ def base_directory
213
+ buildr_project.path_to
214
+ end
215
+
216
+ def base_document
217
+ target = StringIO.new
218
+ Builder::XmlMarkup.new(:target => target).module(:version => "4", :relativePaths => "true", :type => self.type)
219
+ REXML::Document.new(target.string)
220
+ end
221
+
222
+ def initial_components
223
+ []
224
+ end
225
+
226
+ def default_components
227
+ [
228
+ lambda { module_root_component },
229
+ lambda { facet_component }
230
+ ]
231
+ end
232
+
233
+ def facet_component
234
+ return nil if self.facets.empty?
235
+ fm = self.create_component("FacetManager")
236
+ self.facets.each do |facet|
237
+ fm.add_element facet
238
+ end
239
+ fm
240
+ end
241
+
242
+ def module_root_component
243
+ create_component("NewModuleRootManager", "inherit-compiler-output" => "false") do |xml|
244
+ generate_compile_output(xml)
245
+ generate_content(xml) unless skip_content?
246
+ generate_initial_order_entries(xml)
247
+ project_dependencies = []
248
+
249
+ # Note: Use the test classpath since IDEA compiles both "main" and "test" classes using the same classpath
250
+ self.test_dependency_details.each do |dependency_path, export, source_path|
251
+ project_for_dependency = Buildr.projects.detect do |project|
252
+ [project.packages, project.compile.target, project.test.compile.target].flatten.
253
+ detect { |proj_art| proj_art.to_s == dependency_path }
254
+ end
255
+ if project_for_dependency
256
+ if project_for_dependency.iml? && !project_dependencies.include?(project_for_dependency)
257
+ generate_project_dependency(xml, project_for_dependency.iml.name, export)
140
258
  end
259
+ project_dependencies << project_for_dependency
260
+ next
261
+ else
262
+ generate_module_lib(xml, url_for_path(dependency_path), export, (source_path ? url_for_path(source_path) : nil))
263
+ end
264
+ end
265
+
266
+ xml.orderEntryProperties
267
+ end
268
+ end
269
+
270
+ def jar_path(path)
271
+ "jar://#{resolve_path(path)}!/"
272
+ end
273
+
274
+ def file_path(path)
275
+ "file://#{resolve_path(path)}"
276
+ end
277
+
278
+ def url_for_path(path)
279
+ if path =~ /jar$/i
280
+ jar_path(path)
281
+ else
282
+ file_path(path)
283
+ end
284
+ end
285
+
286
+ def resolve_path(path)
287
+ m2repo = Buildr::Repositories.instance.local
288
+ if path.to_s.index(m2repo) == 0 && !self.local_repository_env_override.nil?
289
+ return path.sub(m2repo, "$#{self.local_repository_env_override}$")
290
+ else
291
+ begin
292
+ return "$MODULE_DIR$/#{relative(path)}"
293
+ rescue ArgumentError
294
+ # ArgumentError happens on windows when self.base_directory and path are on different drives
295
+ return path
296
+ end
297
+ end
298
+ end
299
+
300
+ def relative(path)
301
+ ::Buildr::Util.relative_path(File.expand_path(path.to_s), self.base_directory)
302
+ end
303
+
304
+ def generate_compile_output(xml)
305
+ xml.output(:url => file_path(self.main_output_dir.to_s))
306
+ xml.tag!("output-test", :url => file_path(self.test_output_dir.to_s))
307
+ xml.tag!("exclude-output")
308
+ end
309
+
310
+ def generate_content(xml)
311
+ xml.content(:url => "file://$MODULE_DIR$") do
312
+ # Source folders
313
+ {
314
+ :main => self.main_source_directories,
315
+ :test => self.test_source_directories
316
+ }.each do |kind, directories|
317
+ directories.map { |dir| dir.to_s }.compact.sort.uniq.each do |dir|
318
+ xml.sourceFolder :url => file_path(dir), :isTestSource => (kind == :test ? 'true' : 'false')
141
319
  end
142
320
  end
321
+
322
+ # Exclude target directories
323
+ self.net_excluded_directories.
324
+ collect { |dir| file_path(dir) }.
325
+ select { |dir| relative_dir_inside_dir?(dir) }.
326
+ sort.each do |dir|
327
+ xml.excludeFolder :url => dir
328
+ end
143
329
  end
144
330
  end
145
331
 
146
- # Root project aggregates all the subprojects.
147
- if project.parent == nil
148
- task_name = project.path_to("#{project.name.gsub(':', '-')}.ipr")
149
- idea.enhance [ file(task_name) ]
332
+ def relative_dir_inside_dir?(dir)
333
+ !dir.include?("../")
334
+ end
335
+
336
+ def generate_initial_order_entries(xml)
337
+ xml.orderEntry :type => "sourceFolder", :forTests => "false"
338
+ xml.orderEntry :type => "inheritedJdk"
339
+ end
150
340
 
151
- file(task_name=>Buildr.application.buildfile) do |task|
152
- info "Writing #{task.name}"
341
+ def generate_project_dependency(xml, other_project, export = true)
342
+ attribs = {:type => 'module', "module-name" => other_project}
343
+ attribs[:exported] = '' if export
344
+ xml.orderEntry attribs
345
+ end
153
346
 
154
- # Generating just the little stanza that chanages from one project to another
155
- partial = StringIO.new
156
- xml = Builder::XmlMarkup.new(:target=>partial, :indent=>2)
157
- xml.component(:name=>"ProjectModuleManager") do
158
- xml.modules do
159
- project.projects.each do |subp|
160
- module_name = subp.name.gsub(":", "-")
161
- module_path = subp.name.split(":"); module_path.shift
162
- module_path = module_path.join("/")
163
- path = "#{module_path}/#{module_name}.iml"
164
- xml.module :fileurl=>"file://$PROJECT_DIR$/#{path}", :filepath=>"$PROJECT_DIR$/#{path}"
347
+ def generate_module_lib(xml, path, export, source_path)
348
+ attribs = {:type => 'module-library'}
349
+ attribs[:exported] = '' if export
350
+ xml.orderEntry attribs do
351
+ xml.library do
352
+ xml.CLASSES do
353
+ xml.root :url => path
354
+ end
355
+ xml.JAVADOC
356
+ xml.SOURCES do
357
+ if source_path
358
+ xml.root :url => source_path
165
359
  end
166
- if package = project.packages.first
167
- xml.module :fileurl=>"file://$PROJECT_DIR$/#{project.name}.iml", :filepath=>"$PROJECT_DIR$/#{project.name}.iml"
360
+ end
361
+ end
362
+ end
363
+ end
364
+
365
+ # Don't exclude things that are subdirectories of other excluded things
366
+ def net_excluded_directories
367
+ net = []
368
+ all = self.excluded_directories.map { |dir| buildr_project._(dir.to_s) }.sort_by { |d| d.size }
369
+ all.each_with_index do |dir, i|
370
+ unless all[0 ... i].find { |other| dir =~ /^#{other}/ }
371
+ net << dir
372
+ end
373
+ end
374
+ net
375
+ end
376
+ end
377
+
378
+ # IdeaModule represents an .ipr file
379
+ class IdeaProject < IdeaFile
380
+ attr_accessor :vcs
381
+ attr_accessor :extra_modules
382
+ attr_writer :jdk_version
383
+
384
+ def initialize(buildr_project)
385
+ @buildr_project = buildr_project
386
+ @vcs = detect_vcs
387
+ @extra_modules = []
388
+ end
389
+
390
+ def jdk_version
391
+ @jdk_version ||= buildr_project.compile.options.source || "1.6"
392
+ end
393
+
394
+ protected
395
+
396
+ def extension
397
+ "ipr"
398
+ end
399
+
400
+ def detect_vcs
401
+ if File.directory?(buildr_project._('.svn'))
402
+ "svn"
403
+ elsif File.directory?(buildr_project._('.git'))
404
+ "Git"
405
+ end
406
+ end
407
+
408
+ def base_document
409
+ target = StringIO.new
410
+ Builder::XmlMarkup.new(:target => target).project(:version => "4", :relativePaths => "false")
411
+ REXML::Document.new(target.string)
412
+ end
413
+
414
+ def default_components
415
+ [
416
+ lambda { modules_component },
417
+ vcs_component
418
+ ]
419
+ end
420
+
421
+ def initial_components
422
+ [
423
+ lambda { project_root_manager_component },
424
+ lambda { project_details_component }
425
+ ]
426
+ end
427
+
428
+ def project_root_manager_component
429
+ attribs = {"version" => "2",
430
+ "assert-keyword" => "true",
431
+ "jdk-15" => "true",
432
+ "project-jdk-name" => self.jdk_version,
433
+ "project-jdk-type" => "JavaSDK",
434
+ "languageLevel" => "JDK_#{self.jdk_version.gsub('.', '_')}"}
435
+ create_component("ProjectRootManager", attribs) do |xml|
436
+ xml.output("url" => "file://$PROJECT_DIR$/out")
437
+ end
438
+ end
439
+
440
+ def project_details_component
441
+ create_component("ProjectDetails") do |xml|
442
+ xml.option("name" => "projectName", "value" => self.name)
443
+ end
444
+ end
445
+
446
+ def modules_component
447
+ create_component("ProjectModuleManager") do |xml|
448
+ xml.modules do
449
+ buildr_project.projects.select { |subp| subp.iml? }.each do |subproject|
450
+ module_path = subproject.base_dir.gsub(/^#{buildr_project.base_dir}\//, '')
451
+ path = "#{module_path}/#{subproject.iml.name}.iml"
452
+ attribs = {:fileurl => "file://$PROJECT_DIR$/#{path}", :filepath => "$PROJECT_DIR$/#{path}"}
453
+ if subproject.iml.group == true
454
+ attribs[:group] = subproject.parent.name.gsub(':', '/')
455
+ elsif !subproject.iml.group.nil?
456
+ attribs[:group] = subproject.group.to_s
168
457
  end
458
+ xml.module attribs
459
+ end
460
+ self.extra_modules.each do |iml_file|
461
+ xml.module :fileurl => "file://$PROJECT_DIR$/#{iml_file}",
462
+ :filepath => "$PROJECT_DIR$/#{iml_file}"
463
+ end
464
+ if buildr_project.iml?
465
+ xml.module :fileurl => "file://$PROJECT_DIR$/#{buildr_project.iml.name}.iml",
466
+ :filepath => "$PROJECT_DIR$/#{buildr_project.iml.name}.iml"
467
+ end
468
+ end
469
+ end
470
+ end
471
+
472
+ def vcs_component
473
+ if vcs
474
+ create_component("VcsDirectoryMappings") do |xml|
475
+ xml.mapping :directory => "", :vcs => vcs
476
+ end
477
+ end
478
+ end
479
+ end
480
+
481
+ module ProjectExtension
482
+ include Extension
483
+
484
+ first_time do
485
+ desc "Generate Intellij IDEA artifacts for all projects"
486
+ Project.local_task "idea:generate" => "artifacts"
487
+
488
+ desc "Delete the generated Intellij IDEA artifacts"
489
+ Project.local_task "idea:clean"
490
+ end
491
+
492
+ before_define do |project|
493
+ project.recursive_task("idea:generate")
494
+ project.recursive_task("idea:clean")
495
+ end
496
+
497
+ after_define do |project|
498
+ idea = project.task("idea:generate")
499
+
500
+ files = [
501
+ (project.iml if project.iml?),
502
+ (project.ipr if project.ipr?)
503
+ ].compact
504
+
505
+ files.each do |ideafile|
506
+ module_dir = File.dirname(ideafile.filename)
507
+ # Need to clear the actions else the extension included as part of buildr will run
508
+ file(ideafile.filename).clear_actions
509
+ idea.enhance [file(ideafile.filename)]
510
+ file(ideafile.filename => [Buildr.application.buildfile]) do |task|
511
+ mkdir_p module_dir
512
+ info "Writing #{task.name}"
513
+ t = Tempfile.open("buildr-idea")
514
+ temp_filename = t.path
515
+ t.close!
516
+ File.open(temp_filename, "w") do |f|
517
+ ideafile.write f
169
518
  end
519
+ mv temp_filename, ideafile.filename
170
520
  end
521
+ end
171
522
 
172
- # Loading the whole fairly constant crap
173
- template_xml = REXML::Document.new(File.open(File.dirname(__FILE__)+"/idea.ipr.template"))
174
- include_xml = REXML::Document.new(partial.string)
175
- template_xml.root.add_element(include_xml.root)
176
- File.open task.name, 'w' do |file|
177
- template_xml.write file
523
+ project.task("idea:clean") do
524
+ files.each do |f|
525
+ info "Removing #{f.filename}" if File.exist?(f.filename)
526
+ rm_rf f.filename
178
527
  end
179
528
  end
180
529
  end
181
530
 
182
- end #after define
531
+ def ipr
532
+ if ipr?
533
+ @ipr ||= IdeaProject.new(self)
534
+ else
535
+ raise "Only the root project has an IPR"
536
+ end
537
+ end
183
538
 
184
- end #module Idea
185
- end # module Buildr
539
+ def ipr?
540
+ !@no_ipr && self.parent.nil?
541
+ end
186
542
 
543
+ def iml
544
+ if iml?
545
+ unless @iml
546
+ inheritable_iml_source = self.parent
547
+ while inheritable_iml_source && !inheritable_iml_source.iml?
548
+ inheritable_iml_source = inheritable_iml_source.parent;
549
+ end
550
+ @iml = inheritable_iml_source ? inheritable_iml_source.iml.clone : IdeaModule.new
551
+ @iml.buildr_project = self
552
+ end
553
+ return @iml
554
+ else
555
+ raise "IML generation is disabled for #{self.name}"
556
+ end
557
+ end
558
+
559
+ def no_ipr
560
+ @no_ipr = true
561
+ end
562
+
563
+ def no_iml
564
+ @has_iml = false
565
+ end
566
+
567
+ def iml?
568
+ @has_iml = @has_iml.nil? ? true : @has_iml
569
+ end
570
+ end
571
+ end
572
+ end
187
573
 
188
574
  class Buildr::Project
189
- include Buildr::Idea
575
+ include Buildr::IntellijIdea::ProjectExtension
190
576
  end