vic-buildr 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
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