vic-buildr 1.3.3 → 1.3.4

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 (98) hide show
  1. data/CHANGELOG +42 -11
  2. data/Rakefile +5 -3
  3. data/_buildr +9 -31
  4. data/addon/buildr/cobertura.rb +5 -218
  5. data/addon/buildr/drb.rb +281 -0
  6. data/addon/buildr/emma.rb +5 -220
  7. data/addon/buildr/nailgun.rb +94 -686
  8. data/bin/buildr +0 -9
  9. data/buildr.gemspec +6 -6
  10. data/doc/images/favicon.png +0 -0
  11. data/doc/pages/contributing.textile +6 -4
  12. data/doc/pages/download.textile +11 -0
  13. data/doc/pages/extending.textile +2 -2
  14. data/doc/pages/getting_started.textile +4 -4
  15. data/doc/pages/index.textile +8 -11
  16. data/doc/pages/more_stuff.textile +50 -22
  17. data/doc/pages/packaging.textile +1 -1
  18. data/doc/pages/projects.textile +2 -2
  19. data/doc/pages/settings_profiles.textile +2 -2
  20. data/doc/pages/testing.textile +1 -1
  21. data/doc/pages/whats_new.textile +12 -0
  22. data/doc/site.haml +1 -0
  23. data/lib/buildr.rb +2 -4
  24. data/lib/buildr/core.rb +2 -0
  25. data/lib/buildr/core/application.rb +304 -149
  26. data/lib/buildr/core/checks.rb +3 -131
  27. data/lib/buildr/core/common.rb +0 -4
  28. data/lib/buildr/core/compile.rb +1 -7
  29. data/lib/buildr/core/environment.rb +0 -3
  30. data/lib/buildr/core/filter.rb +7 -3
  31. data/lib/buildr/core/generate.rb +50 -52
  32. data/lib/buildr/core/help.rb +2 -1
  33. data/lib/buildr/core/osx.rb +49 -0
  34. data/lib/buildr/core/progressbar.rb +1 -1
  35. data/lib/buildr/core/project.rb +7 -9
  36. data/lib/buildr/core/test.rb +4 -4
  37. data/lib/buildr/core/transports.rb +13 -30
  38. data/lib/buildr/core/util.rb +8 -3
  39. data/lib/buildr/groovy/bdd.rb +1 -0
  40. data/lib/buildr/groovy/compiler.rb +1 -1
  41. data/lib/buildr/ide/eclipse.rb +30 -20
  42. data/lib/buildr/ide/idea.rb +3 -2
  43. data/lib/buildr/ide/idea7x.rb +4 -2
  44. data/lib/buildr/java/ant.rb +1 -1
  45. data/lib/buildr/java/bdd.rb +9 -5
  46. data/lib/buildr/java/cobertura.rb +236 -0
  47. data/lib/buildr/java/commands.rb +2 -1
  48. data/lib/buildr/java/emma.rb +238 -0
  49. data/lib/buildr/java/jtestr_runner.rb.erb +2 -0
  50. data/lib/buildr/java/packaging.rb +6 -2
  51. data/lib/buildr/java/pom.rb +0 -4
  52. data/lib/buildr/java/test_result.rb +45 -15
  53. data/lib/buildr/java/tests.rb +14 -9
  54. data/lib/buildr/packaging.rb +5 -2
  55. data/lib/buildr/packaging/archive.rb +488 -0
  56. data/lib/buildr/packaging/artifact.rb +36 -7
  57. data/lib/buildr/packaging/artifact_namespace.rb +2 -2
  58. data/lib/buildr/packaging/gems.rb +3 -3
  59. data/lib/buildr/packaging/package.rb +1 -1
  60. data/lib/buildr/packaging/tar.rb +85 -3
  61. data/lib/buildr/packaging/version_requirement.rb +172 -0
  62. data/lib/buildr/packaging/zip.rb +24 -682
  63. data/lib/buildr/packaging/ziptask.rb +313 -0
  64. data/lib/buildr/scala/compiler.rb +1 -1
  65. data/lib/buildr/scala/tests.rb +2 -2
  66. data/rakelib/apache.rake +58 -8
  67. data/rakelib/package.rake +4 -1
  68. data/rakelib/rspec.rake +2 -2
  69. data/rakelib/rubyforge.rake +6 -3
  70. data/rakelib/scm.rake +1 -1
  71. data/rakelib/setup.rake +0 -5
  72. data/rakelib/stage.rake +4 -1
  73. data/spec/addon/drb_spec.rb +328 -0
  74. data/spec/core/application_spec.rb +29 -22
  75. data/spec/core/build_spec.rb +8 -0
  76. data/spec/core/checks_spec.rb +293 -311
  77. data/spec/core/common_spec.rb +8 -2
  78. data/spec/core/compile_spec.rb +17 -1
  79. data/spec/core/generate_spec.rb +33 -0
  80. data/spec/core/project_spec.rb +18 -10
  81. data/spec/core/test_spec.rb +24 -1
  82. data/spec/ide/eclipse_spec.rb +96 -28
  83. data/spec/java/ant.rb +5 -0
  84. data/spec/java/bdd_spec.rb +4 -4
  85. data/spec/{addon → java}/cobertura_spec.rb +3 -3
  86. data/spec/{addon → java}/emma_spec.rb +3 -3
  87. data/spec/java/java_spec.rb +9 -1
  88. data/spec/java/packaging_spec.rb +19 -2
  89. data/spec/{addon → java}/test_coverage_spec.rb +7 -1
  90. data/spec/java/tests_spec.rb +5 -0
  91. data/spec/packaging/archive_spec.rb +1 -1
  92. data/spec/{core → packaging}/artifact_namespace_spec.rb +2 -2
  93. data/spec/packaging/artifact_spec.rb +46 -5
  94. data/spec/packaging/packaging_spec.rb +1 -1
  95. data/spec/sandbox.rb +16 -14
  96. data/spec/spec_helpers.rb +26 -3
  97. metadata +20 -11
  98. data/lib/buildr/core/application_cli.rb +0 -139
@@ -191,7 +191,7 @@ module Buildr
191
191
  @forced_need = false
192
192
  parent_task = Project.parent_task(name)
193
193
  if parent_task.respond_to?(:options)
194
- @options = OpenObject.new { |hash, key| parent_task.options[key].clone rescue parent_task.options[key] }
194
+ @options = OpenObject.new { |hash, key| hash[key] = parent_task.options[key].clone rescue hash[key] = parent_task.options[key] }
195
195
  else
196
196
  @options = OpenObject.new(default_options)
197
197
  end
@@ -629,9 +629,9 @@ module Buildr
629
629
  # Use this method to return the integration tests task, or enhance it with a block to execute.
630
630
  #
631
631
  # There is one integration tests task you can execute directly, or as a result of running the package
632
- # task (or tasks that depend on it, like install and deploy). It contains all the tests marked with
632
+ # task (or tasks that depend on it, like install and upload). It contains all the tests marked with
633
633
  # :integration=>true, all other tests are considered unit tests and run by the test task before packaging.
634
- # So essentially: build=>test=>packaging=>integration=>install/deploy.
634
+ # So essentially: build=>test=>packaging=>integration=>install/upload.
635
635
  #
636
636
  # You add new tests from projects that define integration tests using the regular test task,
637
637
  # but with the following addition:
@@ -658,7 +658,7 @@ module Buildr
658
658
  class Options
659
659
 
660
660
  # Runs tests after the build when true (default). This forces tests to execute
661
- # after the build, including when running build related tasks like install, deploy and release.
661
+ # after the build, including when running build related tasks like install, upload and release.
662
662
  #
663
663
  # Set to false to not run any tests. Set to :all to run all tests, ignoring failures.
664
664
  #
@@ -14,37 +14,20 @@
14
14
  # the License.
15
15
 
16
16
 
17
- require 'cgi'
17
+ require 'uri'
18
18
  require 'net/http'
19
- require 'net/https'
19
+ Net.autoload :HTTPS, 'net/https'
20
20
  # PATCH: On Windows, Net::SSH 2.0.2 attempts to load the Pageant DLLs which break on JRuby.
21
- $LOADED_FEATURES.unshift 'net/ssh/authentication/pageant' if RUBY_PLATFORM =~ /java/
22
- require 'net/ssh'
23
- require 'net/sftp'
24
- require 'uri'
25
- require 'digest/md5'
26
- require 'digest/sha1'
27
- require 'stringio'
28
- require 'tempfile'
29
- require 'buildr/core/progressbar'
30
-
31
-
32
- # Monkeypatching: SFTP never defines the mkdir method on its session or the underlying
33
- # driver, it just redirect calls through method_missing. Rake, on the other hand, decides
34
- # to define mkdir on Object, and so routes our calls to FileUtils.
35
- module Net #:nodoc:all
36
- class Session
37
- def mkdir(path, attrs = {})
38
- method_missing :mkdir, path, attrs
39
- end
40
- end
41
-
42
- class SFTP::Protocol::Driver
43
- def mkdir(first, path, attrs = {})
44
- method_missing :mkdir, first, path, attrs
45
- end
46
- end
21
+ $LOADED_FEATURES << 'net/ssh/authentication/pageant.rb' if RUBY_PLATFORM =~ /java/
22
+ gem 'net-ssh' ; Net.autoload :SSH, 'net/ssh'
23
+ gem 'net-sftp' ; Net.autoload :SFTP, 'net/sftp'
24
+ autoload :CGI, 'cgi'
25
+ module Digest
26
+ autoload :MD5, 'digest/md5'
27
+ autoload :SHA1, 'digest/sha1'
47
28
  end
29
+ require 'stringio'
30
+ autoload :ProgressBar, 'buildr/core/progressbar'
48
31
 
49
32
 
50
33
  # Not quite open-uri, but similar. Provides read and write methods for the resource represented by the URI.
@@ -173,7 +156,7 @@ module URI
173
156
  read({:progress=>verbose}.merge(options || {}).merge(:modified=>modified)) { |chunk| temp.write chunk }
174
157
  end
175
158
  mkpath File.dirname(target)
176
- File.move temp.path, target
159
+ FileUtils.mv temp.path, target
177
160
  when File
178
161
  read({:progress=>verbose}.merge(options || {}).merge(:modified=>target.mtime)) { |chunk| target.write chunk }
179
162
  target.flush
@@ -566,7 +549,7 @@ module URI
566
549
  end
567
550
  real_path.tap do |path|
568
551
  mkpath File.dirname(path)
569
- File.move temp.path, path
552
+ FileUtils.mv temp.path, path
570
553
  end
571
554
  end
572
555
 
@@ -16,7 +16,12 @@
16
16
 
17
17
  require 'rbconfig'
18
18
  require 'pathname'
19
- require 'builder' # A different kind of buildr, one we use to create XML.
19
+ autoload :Tempfile, 'tempfile'
20
+ autoload :YAML, 'yaml'
21
+ autoload :REXML, 'rexml/document'
22
+ gem 'xml-simple' ; autoload :XmlSimple, 'xmlsimple'
23
+ gem 'builder' ; autoload :Builder, 'builder' # A different kind of buildr, one we use to create XML.
24
+ require 'highline/import'
20
25
 
21
26
 
22
27
  module Buildr
@@ -31,7 +36,7 @@ module Buildr
31
36
  # In order to determine if we are running on a windows OS,
32
37
  # prefer this function instead of using Gem.win_platform?.
33
38
  #
34
- # Gem.win_platform? only checks the RUBY_PLATFORM global,
39
+ # Gem.win_platform? only checks these RUBY_PLATFORM global,
35
40
  # that in some cases like when running on JRuby is not
36
41
  # succifient for our purpose:
37
42
  #
@@ -286,4 +291,4 @@ class Hash
286
291
  }.join("\n")
287
292
  end
288
293
 
289
- end
294
+ end
@@ -13,6 +13,7 @@
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
15
 
16
+
16
17
  module Buildr::Groovy
17
18
 
18
19
  # EasyB is a Groovy based BDD framework.
@@ -19,7 +19,7 @@ module Buildr::Groovy
19
19
  # Groovyc compiler:
20
20
  # compile.using(:groovyc)
21
21
  #
22
- # You need to require 'buildr/java/groovyc' if you need to use this compiler.
22
+ # You need to require 'buildr/groovy/compiler' if you need to use this compiler.
23
23
  #
24
24
  # Used by default if .groovy files are found in the src/main/groovy directory (or src/test/groovy)
25
25
  # and sets the target directory to target/classes (or target/test/classes).
@@ -25,16 +25,16 @@ module Buildr
25
25
 
26
26
  first_time do
27
27
  # Global task "eclipse" generates artifacts for all projects.
28
- desc "Generate Eclipse artifacts for all projects"
29
- Project.local_task "eclipse"=>"artifacts"
28
+ desc 'Generate Eclipse artifacts for all projects'
29
+ Project.local_task 'eclipse'=>'artifacts'
30
30
  end
31
31
 
32
32
  before_define do |project|
33
- project.recursive_task("eclipse")
33
+ project.recursive_task('eclipse')
34
34
  end
35
35
 
36
36
  after_define do |project|
37
- eclipse = project.task("eclipse")
37
+ eclipse = project.task('eclipse')
38
38
 
39
39
  # Check if project has scala facet
40
40
  scala = project.compile.language == :scala
@@ -42,17 +42,18 @@ module Buildr
42
42
  # Only for projects that we support
43
43
  supported_languages = [:java, :scala]
44
44
  supported_packaging = %w(jar war rar mar aar)
45
- if (supported_languages.include? project.compile.language ||
45
+ if (supported_languages.include?(project.compile.language) ||
46
+ supported_languages.include?(project.test.compile.language) ||
46
47
  project.packages.detect { |pkg| supported_packaging.include?(pkg.type.to_s) })
47
- eclipse.enhance [ file(project.path_to(".classpath")), file(project.path_to(".project")) ]
48
+ eclipse.enhance [ file(project.path_to('.classpath')), file(project.path_to('.project')) ]
48
49
 
49
50
  # The only thing we need to look for is a change in the Buildfile.
50
- file(project.path_to(".classpath")=>Buildr.application.buildfile) do |task|
51
+ file(project.path_to('.classpath')=>Buildr.application.buildfile) do |task|
51
52
  info "Writing #{task.name}"
52
53
 
53
54
  m2repo = Buildr::Repositories.instance.local
54
55
 
55
- File.open(task.name, "w") do |file|
56
+ File.open(task.name, 'w') do |file|
56
57
  classpathentry = ClasspathEntryWriter.new project, file
57
58
  classpathentry.write do
58
59
  # Note: Use the test classpath since Eclipse compiles both "main" and "test" classes using the same classpath
@@ -82,7 +83,7 @@ module Buildr
82
83
  # Classpath elements from other projects
83
84
  classpathentry.src_projects project_libs
84
85
 
85
- classpathentry.output project.compile.target
86
+ classpathentry.output project.compile.target if project.compile.target
86
87
  classpathentry.lib libs
87
88
  classpathentry.var m2_libs, 'M2_REPO', m2repo
88
89
 
@@ -93,9 +94,9 @@ module Buildr
93
94
  end
94
95
 
95
96
  # The only thing we need to look for is a change in the Buildfile.
96
- file(project.path_to(".project")=>Buildr.application.buildfile) do |task|
97
+ file(project.path_to('.project')=>Buildr.application.buildfile) do |task|
97
98
  info "Writing #{task.name}"
98
- File.open(task.name, "w") do |file|
99
+ File.open(task.name, 'w') do |file|
99
100
  xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
100
101
  xml.projectDescription do
101
102
  xml.name project.id
@@ -103,17 +104,17 @@ module Buildr
103
104
  xml.buildSpec do
104
105
  if scala
105
106
  xml.buildCommand do
106
- xml.name "ch.epfl.lamp.sdt.core.scalabuilder"
107
+ xml.name 'ch.epfl.lamp.sdt.core.scalabuilder'
107
108
  end
108
109
  else
109
110
  xml.buildCommand do
110
- xml.name "org.eclipse.jdt.core.javabuilder"
111
+ xml.name 'org.eclipse.jdt.core.javabuilder'
111
112
  end
112
113
  end
113
114
  end
114
115
  xml.natures do
115
- xml.nature "ch.epfl.lamp.sdt.core.scalanature" if scala
116
- xml.nature "org.eclipse.jdt.core.javanature"
116
+ xml.nature 'ch.epfl.lamp.sdt.core.scalanature' if scala
117
+ xml.nature 'org.eclipse.jdt.core.javanature'
117
118
  end
118
119
  end
119
120
  end
@@ -149,7 +150,7 @@ module Buildr
149
150
  end
150
151
 
151
152
  # Write a classpathentry of kind 'src'.
152
- # Accepts an array of absolute paths or a task.
153
+ # Accept an array of absolute paths or a task.
153
154
  def src arg
154
155
  if [:sources, :target].all? { |message| arg.respond_to?(message) }
155
156
  src_from_task arg
@@ -159,10 +160,10 @@ module Buildr
159
160
  end
160
161
 
161
162
  # Write a classpathentry of kind 'src' for dependent projects.
162
- # Accepts an array of projects.
163
+ # Accept an array of projects.
163
164
  def src_projects project_libs
164
165
  project_libs.map(&:id).sort.uniq.each do |project_id|
165
- @xml.classpathentry :kind=>'src', :combineaccessrules=>"false", :path=>"/#{project_id}"
166
+ @xml.classpathentry :kind=>'src', :combineaccessrules=>'false', :path=>"/#{project_id}"
166
167
  end
167
168
  end
168
169
 
@@ -170,9 +171,18 @@ module Buildr
170
171
  @xml.classpathentry :kind=>'output', :path=>relative(target)
171
172
  end
172
173
 
174
+ # Write a classpathentry of kind 'var' (variable) for a library in a local repo.
175
+ # * +libs+ is an array of library paths.
176
+ # * +var_name+ is a variable name as defined in Eclipse (e.g., 'M2_REPO').
177
+ # * +var_value+ is the value of this variable (e.g., '/home/me/.m2').
178
+ # E.g., <tt>var([lib1, lib2], 'M2_REPO', '/home/me/.m2/repo')</tt>
173
179
  def var libs, var_name, var_value
174
- libs.map { |lib| lib.to_s.sub(var_value, var_name) }.sort.uniq.each do |path|
175
- @xml.classpathentry :kind=>'var', :path=>path
180
+ libs.each do |lib_path|
181
+ lib_artifact = file(lib_path)
182
+ source_path = lib_artifact.sources_artifact.to_s
183
+ relative_lib_path = lib_path.sub(var_value, var_name)
184
+ relative_source_path = source_path.sub(var_value, var_name)
185
+ @xml.classpathentry :kind=>'var', :path=>relative_lib_path, :sourcepath=>relative_source_path
176
186
  end
177
187
  end
178
188
 
@@ -17,7 +17,6 @@
17
17
  require 'buildr/core/project'
18
18
  require 'buildr/packaging'
19
19
  require 'stringio'
20
- require 'rexml/document'
21
20
 
22
21
 
23
22
  module Buildr
@@ -130,7 +129,9 @@ module Buildr
130
129
  xml.root :url=>"jar://#{path}!/"
131
130
  end
132
131
  xml.JAVADOC
133
- xml.SOURCES
132
+ xml.SOURCES do
133
+ xml.root :url=>"jar://#{path.sub(/\.jar$/, "-sources.jar")}!/"
134
+ end
134
135
  end
135
136
  end
136
137
  end
@@ -17,7 +17,7 @@
17
17
  require 'buildr/core/project'
18
18
  require 'buildr/packaging'
19
19
  require 'stringio'
20
- require 'rexml/document'
20
+
21
21
 
22
22
  module Buildr
23
23
  module Idea7x #:nodoc:
@@ -160,7 +160,9 @@ module Buildr
160
160
  xml.root :url=> path
161
161
  end
162
162
  xml.JAVADOC
163
- xml.SOURCES
163
+ xml.SOURCES do
164
+ xml.root :url=>"jar://#{path.sub(/\.jar$/, "-sources.jar")}!/"
165
+ end
164
166
  end
165
167
  end
166
168
  end
@@ -14,7 +14,7 @@
14
14
  # the License.
15
15
 
16
16
 
17
- require 'antwrap'
17
+ gem 'Antwrap' ; autoload :Antwrap, 'antwrap'
18
18
  require 'buildr/core/project'
19
19
  require 'buildr/core/help'
20
20
 
@@ -13,9 +13,11 @@
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
15
 
16
+
16
17
  require 'buildr/java/tests'
17
18
  require 'buildr/java/test_result'
18
19
 
20
+
19
21
  module Buildr
20
22
 
21
23
  # Mixin for test frameworks using src/spec/{lang}
@@ -46,7 +48,7 @@ module Buildr
46
48
  module TestFramework::JRubyBased
47
49
  extend self
48
50
 
49
- VERSION = '1.1.4'
51
+ VERSION = '1.1.3'
50
52
 
51
53
  class << self
52
54
  def version
@@ -269,8 +271,9 @@ module Buildr
269
271
  Buildr::TestFramework::TestResult::Error.guard('<%= runner.file %>') do
270
272
  ::Spec::Runner::CommandLine.run($rspec_options)
271
273
  end
274
+ exit 0 # let buildr figure the result from the yaml file
272
275
  }
273
- Filter::Mapper.new(:erb, binding).result(runner_erb)
276
+ Filter::Mapper.new(:erb, binding).transform(runner_erb)
274
277
  end
275
278
 
276
279
  end
@@ -365,14 +368,15 @@ module Buildr
365
368
 
366
369
  def runner_config
367
370
  runner = super
368
- runner.gems.update 'rspec' => '>0'
369
- runner.requires.unshift 'spec', 'jtestr'
371
+ # JtestR 0.3.1 comes with rspec 1.1.4 (and any other jtestr dependency) included,
372
+ # so the rspec version used depends on the jtestr jar.
373
+ runner.requires.unshift 'jtestr'
370
374
  runner
371
375
  end
372
376
 
373
377
  def runner_content(binding)
374
378
  runner_erb = File.join(File.dirname(__FILE__), 'jtestr_runner.rb.erb')
375
- Filter::Mapper.new(:erb, binding).result(File.read(runner_erb), runner_erb)
379
+ Filter::Mapper.new(:erb, binding).transform(File.read(runner_erb), runner_erb)
376
380
  end
377
381
 
378
382
  end
@@ -0,0 +1,236 @@
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
+
17
+ require 'buildr/java'
18
+
19
+
20
+ module Buildr
21
+
22
+ # Provides the <code>cobertura:html</code> and <code>cobertura:xml</code> tasks.
23
+ # Require explicitly using <code>require "buildr/cobertura"</code>.
24
+ #
25
+ # You can generate cobertura reports for a single project
26
+ # using the project name as prefix:
27
+ #
28
+ # project_name:cobertura:html
29
+ #
30
+ # You can also specify which classes to include/exclude from instrumentation by
31
+ # passing a class name regexp to the <code>cobertura.include</code> or
32
+ # <code>cobertura.exclude</code> methods.
33
+ #
34
+ # define 'someModule' do
35
+ # cobertura.include 'some.package.*'
36
+ # cobertura.include /some.(foo|bar).*/
37
+ # cobertura.exclude 'some.foo.util.SimpleUtil'
38
+ # cobertura.exclude /*.Const(ants)?/i
39
+ # end
40
+ module Cobertura
41
+
42
+ class << self
43
+
44
+ REQUIRES = ["net.sourceforge.cobertura:cobertura:jar:1.9", "log4j:log4j:jar:1.2.9",
45
+ "asm:asm:jar:2.2.1", "asm:asm-tree:jar:2.2.1", "oro:oro:jar:2.0.8"] unless const_defined?('REQUIRES')
46
+
47
+ def requires()
48
+ @requires ||= Buildr.artifacts(REQUIRES).each(&:invoke).map(&:to_s)
49
+ end
50
+
51
+ def report_to(file = nil)
52
+ File.expand_path(File.join(*["reports/cobertura", file.to_s].compact))
53
+ end
54
+
55
+ def data_file()
56
+ File.expand_path("reports/cobertura.ser")
57
+ end
58
+
59
+ end
60
+
61
+ class CoberturaConfig # :nodoc:
62
+
63
+ def initialize(project)
64
+ @project = project
65
+ end
66
+
67
+ attr_reader :project
68
+ private :project
69
+
70
+ attr_writer :data_file, :instrumented_dir, :report_dir
71
+
72
+ def data_file
73
+ @data_file ||= project.path_to(:reports, 'cobertura.ser')
74
+ end
75
+
76
+ def instrumented_dir
77
+ @instrumented_dir ||= project.path_to(:target, :instrumented, :classes)
78
+ end
79
+
80
+ def report_dir
81
+ @report_dir ||= project.path_to(:reports, :cobertura)
82
+ end
83
+
84
+ def report_to(file = nil)
85
+ File.expand_path(File.join(*[report_dir, file.to_s].compact))
86
+ end
87
+
88
+ # :call-seq:
89
+ # project.cobertura.include(*classPatterns)
90
+ #
91
+ def include(*classPatterns)
92
+ includes.push(*classPatterns.map { |p| String === p ? Regexp.new(p) : p })
93
+ self
94
+ end
95
+
96
+ def includes
97
+ @includeClasses ||= []
98
+ end
99
+
100
+ # :call-seq:
101
+ # project.cobertura.exclude(*classPatterns)
102
+ #
103
+ def exclude(*classPatterns)
104
+ excludes.push(*classPatterns.map { |p| String === p ? Regexp.new(p) : p })
105
+ self
106
+ end
107
+
108
+ def excludes
109
+ @excludeClasses ||= []
110
+ end
111
+
112
+ def sources
113
+ project.compile.sources
114
+ end
115
+ end
116
+
117
+ module CoberturaExtension # :nodoc:
118
+ include Buildr::Extension
119
+
120
+ def cobertura
121
+ @cobertura_config ||= CoberturaConfig.new(self)
122
+ end
123
+
124
+ after_define do |project|
125
+ cobertura = project.cobertura
126
+
127
+ namespace 'cobertura' do
128
+ unless project.compile.target.nil?
129
+ # Instrumented bytecode goes in a different directory. This task creates before running the test
130
+ # cases and monitors for changes in the generate bytecode.
131
+ instrumented = project.file(cobertura.instrumented_dir => project.compile.target) do |task|
132
+ mkdir_p task.to_s, :verbose => false
133
+ unless project.compile.sources.empty?
134
+ info "Instrumenting classes with cobertura data file #{cobertura.data_file}"
135
+ Buildr.ant "cobertura" do |ant|
136
+ ant.taskdef :classpath=>Cobertura.requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
137
+ ant.send "cobertura-instrument", :todir=>task.to_s, :datafile=>cobertura.data_file do
138
+ includes, excludes = cobertura.includes, cobertura.excludes
139
+
140
+ classes_dir = project.compile.target.to_s
141
+ if includes.empty? && excludes.empty?
142
+ ant.fileset :dir => classes_dir do
143
+ ant.include :name => "**/*.class"
144
+ end
145
+ else
146
+ includes = [//] if includes.empty?
147
+ Dir.glob(File.join(classes_dir, "**/*.class")) do |cls|
148
+ cls_name = cls.gsub(/#{classes_dir}\/?|\.class$/, '').gsub('/', '.')
149
+ if includes.any? { |p| p === cls_name } && !excludes.any? { |p| p === cls_name }
150
+ ant.fileset :file => cls
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ touch task.to_s, :verbose=>false
158
+ end
159
+
160
+ task 'instrument' => instrumented
161
+
162
+ # We now have two target directories with bytecode. It would make sense to remove compile.target
163
+ # and add instrumented instead, but apparently Cobertura only creates some of the classes, so
164
+ # we need both directories and instrumented must come first.
165
+ project.test.dependencies.unshift cobertura.instrumented_dir
166
+ project.test.with Cobertura.requires
167
+ project.test.options[:properties]["net.sourceforge.cobertura.datafile"] = cobertura.data_file
168
+
169
+ [:xml, :html].each do |format|
170
+ task format => ['instrument', 'test'] do
171
+ info "Creating test coverage reports in #{cobertura.report_to(format)}"
172
+ Buildr.ant "cobertura" do |ant|
173
+ ant.taskdef :classpath=>Cobertura.requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
174
+ ant.send "cobertura-report", :format=>format,
175
+ :destdir=>cobertura.report_to(format), :datafile=>cobertura.data_file do
176
+ cobertura.sources.flatten.each do |src|
177
+ ant.fileset(:dir=>src.to_s) if File.exist?(src.to_s)
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ end
186
+
187
+ project.clean do
188
+ rm_rf [cobertura.report_to, cobertura.data_file, cobertura.instrumented_dir], :verbose=>false
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+
195
+ class Buildr::Project
196
+ include CoberturaExtension
197
+ end
198
+
199
+ namespace "cobertura" do
200
+
201
+ task "instrument" do
202
+ Buildr.projects.each do |project|
203
+ project.cobertura.data_file = data_file
204
+ project.test.options[:properties]["net.sourceforge.cobertura.datafile"] = data_file
205
+ instrument_task ="#{project.name}:cobertura:instrument"
206
+ task(instrument_task).invoke if Rake::Task.task_defined?(instrument_task)
207
+ end
208
+ end
209
+
210
+ [:xml, :html].each do |format|
211
+ report_target = report_to(format)
212
+ desc "Run the test cases and produce code coverage reports in #{report_target}"
213
+ task format => ["instrument", "test"] do
214
+ info "Creating test coverage reports in #{report_target}"
215
+ Buildr.ant "cobertura" do |ant|
216
+ ant.taskdef :classpath=>requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
217
+ ant.send "cobertura-report", :destdir=>report_target, :format=>format, :datafile=>data_file do
218
+ Buildr.projects.map(&:cobertura).map(&:sources).flatten.each do |src|
219
+ ant.fileset :dir=>src.to_s if File.exist?(src.to_s)
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+
226
+ task "clean" do
227
+ rm_rf [report_to, data_file], :verbose=>false
228
+ end
229
+ end
230
+
231
+ task "clean" do
232
+ task("cobertura:clean").invoke if Dir.pwd == Rake.application.original_dir
233
+ end
234
+
235
+ end
236
+ end