buildr 1.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/CHANGELOG +780 -0
  2. data/DISCLAIMER +7 -0
  3. data/KEYS +151 -0
  4. data/LICENSE +176 -0
  5. data/NOTICE +31 -0
  6. data/README +173 -0
  7. data/Rakefile +63 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +232 -0
  10. data/addon/buildr/hibernate.rb +142 -0
  11. data/addon/buildr/javacc.rb +85 -0
  12. data/addon/buildr/jdepend.rb +60 -0
  13. data/addon/buildr/jetty.rb +248 -0
  14. data/addon/buildr/nailgun.rb +892 -0
  15. data/addon/buildr/openjpa.rb +90 -0
  16. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  17. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  18. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  19. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  20. data/addon/buildr/xmlbeans.rb +93 -0
  21. data/bin/buildr +21 -0
  22. data/buildr.gemspec +50 -0
  23. data/doc/css/default.css +225 -0
  24. data/doc/css/print.css +95 -0
  25. data/doc/css/syntax.css +43 -0
  26. data/doc/images/apache-incubator-logo.png +0 -0
  27. data/doc/images/buildr-hires.png +0 -0
  28. data/doc/images/buildr.png +0 -0
  29. data/doc/images/note.png +0 -0
  30. data/doc/images/tip.png +0 -0
  31. data/doc/images/zbuildr.tif +0 -0
  32. data/doc/pages/artifacts.textile +317 -0
  33. data/doc/pages/building.textile +501 -0
  34. data/doc/pages/contributing.textile +178 -0
  35. data/doc/pages/download.textile +25 -0
  36. data/doc/pages/extending.textile +229 -0
  37. data/doc/pages/getting_started.textile +337 -0
  38. data/doc/pages/index.textile +63 -0
  39. data/doc/pages/mailing_lists.textile +17 -0
  40. data/doc/pages/more_stuff.textile +367 -0
  41. data/doc/pages/packaging.textile +592 -0
  42. data/doc/pages/projects.textile +449 -0
  43. data/doc/pages/recipes.textile +127 -0
  44. data/doc/pages/settings_profiles.textile +339 -0
  45. data/doc/pages/testing.textile +475 -0
  46. data/doc/pages/troubleshooting.textile +121 -0
  47. data/doc/pages/whats_new.textile +389 -0
  48. data/doc/print.haml +52 -0
  49. data/doc/print.toc.yaml +28 -0
  50. data/doc/scripts/buildr-git.rb +411 -0
  51. data/doc/scripts/install-jruby.sh +44 -0
  52. data/doc/scripts/install-linux.sh +64 -0
  53. data/doc/scripts/install-osx.sh +52 -0
  54. data/doc/site.haml +55 -0
  55. data/doc/site.toc.yaml +44 -0
  56. data/lib/buildr.rb +47 -0
  57. data/lib/buildr/core.rb +27 -0
  58. data/lib/buildr/core/application.rb +373 -0
  59. data/lib/buildr/core/application_cli.rb +134 -0
  60. data/lib/buildr/core/build.rb +262 -0
  61. data/lib/buildr/core/checks.rb +382 -0
  62. data/lib/buildr/core/common.rb +155 -0
  63. data/lib/buildr/core/compile.rb +594 -0
  64. data/lib/buildr/core/environment.rb +120 -0
  65. data/lib/buildr/core/filter.rb +258 -0
  66. data/lib/buildr/core/generate.rb +195 -0
  67. data/lib/buildr/core/help.rb +118 -0
  68. data/lib/buildr/core/progressbar.rb +156 -0
  69. data/lib/buildr/core/project.rb +890 -0
  70. data/lib/buildr/core/test.rb +690 -0
  71. data/lib/buildr/core/transports.rb +486 -0
  72. data/lib/buildr/core/util.rb +235 -0
  73. data/lib/buildr/ide.rb +19 -0
  74. data/lib/buildr/ide/eclipse.rb +181 -0
  75. data/lib/buildr/ide/idea.ipr.template +300 -0
  76. data/lib/buildr/ide/idea.rb +194 -0
  77. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  78. data/lib/buildr/ide/idea7x.rb +210 -0
  79. data/lib/buildr/java.rb +26 -0
  80. data/lib/buildr/java/ant.rb +71 -0
  81. data/lib/buildr/java/bdd_frameworks.rb +267 -0
  82. data/lib/buildr/java/commands.rb +210 -0
  83. data/lib/buildr/java/compilers.rb +432 -0
  84. data/lib/buildr/java/deprecated.rb +141 -0
  85. data/lib/buildr/java/groovyc.rb +137 -0
  86. data/lib/buildr/java/jruby.rb +99 -0
  87. data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
  88. data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
  89. data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
  90. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  91. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
  92. data/lib/buildr/java/packaging.rb +706 -0
  93. data/lib/buildr/java/pom.rb +178 -0
  94. data/lib/buildr/java/rjb.rb +142 -0
  95. data/lib/buildr/java/test_frameworks.rb +290 -0
  96. data/lib/buildr/java/version_requirement.rb +172 -0
  97. data/lib/buildr/packaging.rb +21 -0
  98. data/lib/buildr/packaging/artifact.rb +729 -0
  99. data/lib/buildr/packaging/artifact_namespace.rb +957 -0
  100. data/lib/buildr/packaging/artifact_search.rb +140 -0
  101. data/lib/buildr/packaging/gems.rb +102 -0
  102. data/lib/buildr/packaging/package.rb +233 -0
  103. data/lib/buildr/packaging/tar.rb +104 -0
  104. data/lib/buildr/packaging/zip.rb +719 -0
  105. data/rakelib/apache.rake +126 -0
  106. data/rakelib/changelog.rake +56 -0
  107. data/rakelib/doc.rake +103 -0
  108. data/rakelib/package.rake +44 -0
  109. data/rakelib/release.rake +53 -0
  110. data/rakelib/rspec.rake +81 -0
  111. data/rakelib/rubyforge.rake +45 -0
  112. data/rakelib/scm.rake +49 -0
  113. data/rakelib/setup.rake +59 -0
  114. data/rakelib/stage.rake +45 -0
  115. data/spec/application_spec.rb +316 -0
  116. data/spec/archive_spec.rb +494 -0
  117. data/spec/artifact_namespace_spec.rb +635 -0
  118. data/spec/artifact_spec.rb +738 -0
  119. data/spec/build_spec.rb +193 -0
  120. data/spec/checks_spec.rb +537 -0
  121. data/spec/common_spec.rb +579 -0
  122. data/spec/compile_spec.rb +561 -0
  123. data/spec/groovy_compilers_spec.rb +239 -0
  124. data/spec/java_bdd_frameworks_spec.rb +238 -0
  125. data/spec/java_compilers_spec.rb +446 -0
  126. data/spec/java_packaging_spec.rb +1042 -0
  127. data/spec/java_test_frameworks_spec.rb +414 -0
  128. data/spec/packaging_helper.rb +63 -0
  129. data/spec/packaging_spec.rb +589 -0
  130. data/spec/project_spec.rb +739 -0
  131. data/spec/sandbox.rb +116 -0
  132. data/spec/scala_compilers_spec.rb +239 -0
  133. data/spec/spec.opts +6 -0
  134. data/spec/spec_helpers.rb +283 -0
  135. data/spec/test_spec.rb +871 -0
  136. data/spec/transport_spec.rb +300 -0
  137. data/spec/version_requirement_spec.rb +115 -0
  138. metadata +324 -0
@@ -0,0 +1,178 @@
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 'xmlsimple'
18
+ require 'buildr/packaging'
19
+
20
+
21
+ module Buildr
22
+ class POM
23
+
24
+ POM_TO_SPEC_MAP = { :group=>"groupId", :id=>"artifactId", :type=>"type",
25
+ :version=>"version", :classifier=>"classifier", :scope=>"scope" }
26
+ SCOPES_TRANSITIVE = [nil, "compile", "runtime"]
27
+ SCOPES_WE_USE = SCOPES_TRANSITIVE + ["provided"]
28
+
29
+ # POM project as Hash (using XmlSimple).
30
+ attr_reader :project
31
+ # Parent POM if referenced by this POM.
32
+ attr_reader :parent
33
+
34
+ class << self
35
+
36
+ # :call-seq:
37
+ # POM.load(arg)
38
+ #
39
+ # Load new POM object form various kind of sources such as artifact, hash representing spec, filename, XML.
40
+ def load(source)
41
+ case source
42
+ when Hash
43
+ load(Buildr.artifact(source).pom)
44
+ when Artifact
45
+ pom = source.pom
46
+ pom.invoke
47
+ load(pom.to_s)
48
+ when Rake::FileTask
49
+ source.invoke
50
+ load(source.to_s)
51
+ when String
52
+ filename = File.expand_path(source)
53
+ unless pom = cache[filename]
54
+ puts "Loading m2 pom file from #{filename}" if Buildr.application.options.trace
55
+ pom = POM.new(IO.read(filename))
56
+ cache[filename] = pom
57
+ end
58
+ pom
59
+ else
60
+ raise ArgumentError, "Expecting Hash spec, Artifact, file name or file task"
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def cache()
67
+ @cache ||= {}
68
+ end
69
+
70
+ end
71
+
72
+ def initialize(xml) #:nodoc:
73
+ @project = XmlSimple.xml_in(xml)
74
+ @parent = POM.load(pom_to_hash(project["parent"].first)) if project["parent"]
75
+ end
76
+
77
+ # :call-seq:
78
+ # dependencies(scopes?) => artifacts
79
+ #
80
+ # Returns list of required dependencies as specified by the POM. You can specify which scopes
81
+ # to use (e.g. "compile", "runtime"); use +nil+ for dependencies with unspecified scope.
82
+ # The default scopes are +nil+, "compile" and "runtime" (aka SCOPES_WE_USE).
83
+ def dependencies(scopes = SCOPES_WE_USE)
84
+ #try to cache dependencies also
85
+ @depends_for_scopes ||= {}
86
+ unless depends = @depends_for_scopes[scopes]
87
+ declared = project["dependencies"].first["dependency"] rescue nil
88
+ depends = (declared || []).reject { |dep| value_of(dep["optional"]) =~ /true/ }.
89
+ map { |dep|
90
+ spec = pom_to_hash(dep, properties)
91
+ apply = managed(spec)
92
+ spec = apply.merge(spec) if apply
93
+
94
+ #calculate transitive dependencies
95
+ if scopes.include?(spec[:scope])
96
+ spec.delete(:scope)
97
+
98
+ exclusions = dep["exclusions"]["exclusion"] rescue nil
99
+ transitive_deps = POM.load(spec).dependencies(SCOPES_TRANSITIVE)
100
+ transitive_deps = transitive_deps.reject{|dep|
101
+ exclusions.find {|ex| dep.index("#{dep['groupdId'].first}:#{dep['artifactId'].first}:") == 0}
102
+ } if exclusions
103
+
104
+ [Artifact.to_spec(spec)] + transitive_deps
105
+ end
106
+ }.flatten.compact #.uniq_by{|spec| art = spec.split(':'); "#{art[0]}:#{art[1]}"}
107
+
108
+ @depends_for_scopes[scopes] = depends
109
+ end
110
+ depends
111
+ end
112
+
113
+ # :call-seq:
114
+ # properties() => hash
115
+ #
116
+ # Returns properties available to this POM as hash. Includes explicit properties and pom.xxx/project.xxx
117
+ # properties for groupId, artifactId, version and packaging.
118
+ def properties()
119
+ @properties ||= begin
120
+ pom = ["groupId", "artifactId", "version", "packaging"].inject({}) { |hash, key|
121
+ value = project[key] || (parent ? parent.project[key] : nil)
122
+ hash["pom.#{key}"] = hash["project.#{key}"] = value_of(value) if value
123
+ hash
124
+ }
125
+ props = project["properties"].first rescue {}
126
+ props = props.inject({}) { |mapped, pair| mapped[pair.first] = value_of(pair.last, pom) ; mapped }
127
+ (parent ? parent.properties.merge(props) : props).merge(pom)
128
+ end
129
+ end
130
+
131
+ # :call-seq:
132
+ # managed() => hash
133
+ # managed(hash) => hash
134
+ #
135
+ # The first form returns all the managed dependencies specified by this POM in dependencyManagement.
136
+ # The second form uses a single spec hash and expands it from the current/parent POM. Used to determine
137
+ # the version number if specified in dependencyManagement instead of dependencies.
138
+ def managed(spec = nil)
139
+ if spec
140
+ managed.detect { |dep| [:group, :id, :type, :classifier].all? { |key| spec[key] == dep[key] } } ||
141
+ (parent ? parent.managed(spec) : nil)
142
+ else
143
+ @managed ||= begin
144
+ managed = project["dependencyManagement"].first["dependencies"].first["dependency"] rescue nil
145
+ managed ? managed.map { |dep| pom_to_hash(dep, properties) } : []
146
+ end
147
+ end
148
+ end
149
+
150
+ private
151
+
152
+ # :call-seq:
153
+ # value_of(element) => string
154
+ # value_of(element, true) => string
155
+ #
156
+ # Returns the normalized text value of an element from its XmlSimple value. The second form performs
157
+ # property substitution.
158
+ def value_of(element, substitute = nil)
159
+ value = element.to_a.join.strip
160
+ substitute ? value.gsub(/\$\{([^}]+)\}/) { |key| substitute[$1] } : value
161
+ end
162
+
163
+ # :call-seq:
164
+ # pom_to_hash(element) => hash
165
+ # pom_to_hash(element, true) => hash
166
+ #
167
+ # Return the spec hash from an XmlSimple POM referencing element (e.g. project, parent, dependency).
168
+ # The second form performs property substitution.
169
+ def pom_to_hash(element, substitute = nil)
170
+ hash = POM_TO_SPEC_MAP.inject({}) { |spec, pair|
171
+ spec[pair.first] = value_of(element[pair.last], substitute) if element[pair.last]
172
+ spec
173
+ }
174
+ { :type=>"jar" }.merge(hash)
175
+ end
176
+
177
+ end
178
+ end
@@ -0,0 +1,142 @@
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 'rjb'
18
+
19
+
20
+ # Equivalent to Java system properties. For example:
21
+ # ENV_JAVA['java.version']
22
+ # ENV_JAVA['java.class.version']
23
+ ENV_JAVA = {}
24
+
25
+
26
+ # Buildr runs along side a JVM, using either RJB or JRuby. The Java module allows
27
+ # you to access Java classes and create Java objects.
28
+ #
29
+ # Java classes are accessed as static methods on the Java module, for example:
30
+ # str = Java.java.lang.String.new('hai!')
31
+ # str.toUpperCase
32
+ # => 'HAI!'
33
+ # Java.java.lang.String.isInstance(str)
34
+ # => true
35
+ # Java.com.sun.tools.javac.Main.compile(args)
36
+ #
37
+ # The classpath attribute allows Buildr to add JARs and directories to the classpath,
38
+ # for example, we use it to load Ant and various Ant tasks, code generators, test
39
+ # frameworks, and so forth.
40
+ #
41
+ # When using an artifact specification, Buildr will automatically download and
42
+ # install the artifact before adding it to the classpath.
43
+ #
44
+ # For example, Ant is loaded as follows:
45
+ # Java.classpath << 'org.apache.ant:ant:jar:1.7.0'
46
+ #
47
+ # Artifacts can only be downloaded after the Buildfile has loaded, giving it
48
+ # a chance to specify which remote repositories to use, so adding to classpath
49
+ # does not by itself load any libraries. You must call Java.load before accessing
50
+ # any Java classes to give Buildr a chance to load the libraries specified in the
51
+ # classpath.
52
+ #
53
+ # When building an extension, make sure to follow these rules:
54
+ # 1. Add to the classpath when the extension is loaded (i.e. in module or class
55
+ # definition), so the first call to Java.load anywhere in the code will include
56
+ # the libraries you specify.
57
+ # 2. Call Java.load once before accessing any Java classes, allowing Buildr to
58
+ # set up the classpath.
59
+ # 3. Only call Java.load when invoked, otherwise you may end up loading the JVM
60
+ # with a partial classpath, or before all remote repositories are listed.
61
+ # 4. Check on a clean build with empty local repository.
62
+ module Java
63
+
64
+ module Package #:nodoc:
65
+
66
+ def method_missing(sym, *args, &block)
67
+ raise ArgumentError, 'No arguments expected' unless args.empty?
68
+ name = "#{@name}.#{sym}"
69
+ return ::Rjb.import(name) if sym.to_s =~ /^[[:upper:]]/
70
+ ::Java.send :__package__, name
71
+ end
72
+
73
+ end
74
+
75
+ class << self
76
+
77
+ # Returns the classpath, an array listing directories, JAR files and
78
+ # artifacts. Use when loading the extension to add any additional
79
+ # libraries used by that extension.
80
+ #
81
+ # For example, Ant is loaded as follows:
82
+ # Java.classpath << 'org.apache.ant:ant:jar:1.7.0'
83
+ def classpath
84
+ @classpath ||= []
85
+ end
86
+
87
+ # Loads the JVM and all the libraries listed on the classpath. Call this
88
+ # method before accessing any Java class, but only call it from methods
89
+ # used in the build, giving the Buildfile a chance to load all extensions
90
+ # that append to the classpath and specify which remote repositories to use.
91
+ def load
92
+ return self if @loaded
93
+ unless RUBY_PLATFORM =~ /darwin/i
94
+ home = ENV['JAVA_HOME'] or fail 'Are we forgetting something? JAVA_HOME not set.'
95
+ tools = File.expand_path('lib/tools.jar', home)
96
+ raise "I need tools.jar to compile, can't find it in #{home}/lib" unless File.exist?(tools)
97
+ classpath << tools
98
+ end
99
+ cp = Buildr.artifacts(classpath).map(&:to_s).each { |path| file(path).invoke }
100
+ java_opts = (ENV['JAVA_OPTS'] || ENV['JAVA_OPTIONS']).to_s.split
101
+ ::Rjb.load cp.join(File::PATH_SEPARATOR), java_opts
102
+
103
+ props = ::Rjb.import('java.lang.System').getProperties
104
+ enum = props.propertyNames
105
+ while enum.hasMoreElements
106
+ name = enum.nextElement.toString
107
+ ENV_JAVA[name] = props.getProperty(name)
108
+ end
109
+ @loaded = true
110
+ self
111
+ end
112
+
113
+ def method_missing(sym, *args, &block) #:nodoc:
114
+ raise ArgumentError, 'No arguments expected' unless args.empty?
115
+ name = sym.to_s
116
+ return ::Rjb.import(name) if name =~ /^[[:upper:]]/
117
+ __package__ name
118
+ end
119
+
120
+ private
121
+
122
+ def __package__(name) #:nodoc:
123
+ const = name.split('.').map { |part| part.gsub(/^./) { |char| char.upcase } }.join
124
+ return const_get(const) if const_defined?(const)
125
+ package = Module.new
126
+ package.extend Package
127
+ package.instance_variable_set :@name, name
128
+ const_set(const, package)
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+
136
+ class Array
137
+ # Converts a Ruby array into a typed Java array, argument specifies the element type.
138
+ # This is necessary for JRuby and causes no harm on RJB.
139
+ def to_java(cls)
140
+ map { |item| cls.new(item) }
141
+ end
142
+ end
@@ -0,0 +1,290 @@
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/core/build'
18
+ require 'buildr/core/compile'
19
+ require 'buildr/java/ant'
20
+
21
+ module Buildr
22
+
23
+ class TestFramework
24
+ module JavaTest
25
+
26
+ # Add buildr utilities (JavaTestFilter) to classpath
27
+ Java.classpath << File.join(File.dirname(__FILE__))
28
+
29
+ def self.included(mod)
30
+ super
31
+ mod.extend ClassMethods
32
+ end
33
+
34
+ private
35
+ # :call-seq:
36
+ # filter_classes(dependencies, criteria)
37
+ #
38
+ # Return a list of classnames that match the given criteria.
39
+ # The criteria parameter is a hash that must contain at least one of:
40
+ #
41
+ # * :class_names -- List of patterns to match against class name
42
+ # * :interfaces -- List of java interfaces or java classes
43
+ # * :class_annotations -- List of annotations on class level
44
+ # * :method_annotations -- List of annotations on method level
45
+ #
46
+ def filter_classes(dependencies, criteria = {})
47
+ return [] unless task.compile.target
48
+ target = task.compile.target.to_s
49
+ candidates = Dir["#{target}/**/*.class"].
50
+ map { |file| Util.relative_path(file, target).ext('').gsub(File::SEPARATOR, '.') }.
51
+ reject { |name| name =~ /\$/ }
52
+ result = []
53
+ if criteria[:class_names]
54
+ result.concat candidates.select { |name| criteria[:class_names].flatten.any? { |pat| pat === name } }
55
+ end
56
+ begin
57
+ Java.load
58
+ filter = Java.org.apache.buildr.JavaTestFilter.new(dependencies.to_java(Java.java.lang.String))
59
+ if criteria[:interfaces]
60
+ filter.add_interfaces(criteria[:interfaces].to_java(Java.java.lang.String))
61
+ end
62
+ if criteria[:class_annotations]
63
+ filter.add_class_annotations(criteria[:class_annotations].to_java(Java.java.lang.String))
64
+ end
65
+ if criteria[:method_annotations]
66
+ filter.add_method_annotations(criteria[:method_annotations].to_java(Java.java.lang.String))
67
+ end
68
+ result.concat filter.filter(candidates.to_java(Java.java.lang.String)).map(&:to_s)
69
+ rescue =>ex
70
+ puts "#{ex.class}: #{ex.message}" if verbose
71
+ raise
72
+ end
73
+ result.uniq
74
+ end
75
+
76
+ module ClassMethods
77
+ def applies_to?(project) #:nodoc:
78
+ project.test.compile.language == :java
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+
85
+ # JMock is available when using JUnit and TestNG, JBehave.
86
+ module JMock
87
+ # JMock version.
88
+ VERSION = '1.2.0' unless const_defined?('VERSION')
89
+ # JMock specification.
90
+ REQUIRES = ["jmock:jmock:jar:#{VERSION}"]
91
+ end
92
+
93
+
94
+ # JUnit test framework, the default test framework for Java tests.
95
+ #
96
+ # Support the following options:
97
+ # * :fork -- If true/:once (default), fork for each test class. If :each, fork for each individual
98
+ # test case. If false, run all tests in the same VM (fast, but dangerous).
99
+ # * :clonevm -- If true clone the VM each time it is forked.
100
+ # * :properties -- Hash of system properties available to the test case.
101
+ # * :environment -- Hash of environment variables available to the test case.
102
+ # * :java_args -- Arguments passed as is to the JVM.
103
+ class JUnit < TestFramework::Base
104
+
105
+ # Used by the junit:report task. Access through JUnit#report if you want to set various
106
+ # options for that task, for example:
107
+ # JUnit.report.frames = false
108
+ class Report
109
+
110
+ # Ant-Trax required for running the JUnitReport task.
111
+ Java.classpath << "org.apache.ant:ant-trax:jar:#{Ant::VERSION}"
112
+
113
+ # Parameters passed to the Ant JUnitReport task.
114
+ attr_reader :params
115
+ # True (default) to produce a report using frames, false to produce a single-page report.
116
+ attr_accessor :frames
117
+ # Directory for the report style (defaults to using the internal style).
118
+ attr_accessor :style_dir
119
+ # Target directory for generated report.
120
+ attr_accessor :target
121
+
122
+ def initialize
123
+ @params = {}
124
+ @frames = true
125
+ @target = 'reports/junit'
126
+ end
127
+
128
+ # :call-seq:
129
+ # generate(projects, target?)
130
+ #
131
+ # Generates a JUnit report for these projects (must run JUnit tests first) into the
132
+ # target directory. You can specify a target, or let it pick the default one from the
133
+ # target attribute.
134
+ def generate(projects, target = @target.to_s)
135
+ html_in = File.join(target, 'html')
136
+ rm_rf html_in ; mkpath html_in
137
+
138
+ Buildr.ant('junit-report') do |ant|
139
+ ant.junitreport :todir=>target do
140
+ projects.select { |project| project.test.framework == :junit }.
141
+ map { |project| project.test.report_to.to_s }.select { |path| File.exist?(path) }.
142
+ each { |path| ant.fileset(:dir=>path) { ant.include :name=>'TEST-*.xml' } }
143
+ options = { :format=>frames ? 'frames' : 'noframes' }
144
+ options[:styledir] = style_dir if style_dir
145
+ ant.report options.merge(:todir=>html_in) do
146
+ params.each { |key, value| ant.param :name=>key, :expression=>value }
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ end
153
+
154
+ class << self
155
+
156
+ # :call-seq:
157
+ # report()
158
+ #
159
+ # Returns the Report object used by the junit:report task. You can use this object to set
160
+ # various options that affect your report, for example:
161
+ # JUnit.report.frames = false
162
+ # JUnit.report.params['title'] = 'My App'
163
+ def report
164
+ @report ||= Report.new
165
+ end
166
+
167
+ end
168
+
169
+ # JUnit version number.
170
+ VERSION = '4.3.1' unless const_defined?('VERSION')
171
+
172
+ REQUIRES = ["junit:junit:jar:#{VERSION}"] + JMock::REQUIRES
173
+
174
+ # Ant-JUnit requires for JUnit and JUnit reports tasks.
175
+ Java.classpath << "org.apache.ant:ant-junit:jar:#{Ant::VERSION}"
176
+
177
+ include TestFramework::JavaTest
178
+
179
+ def tests(dependencies) #:nodoc:
180
+ filter_classes(dependencies,
181
+ :interfaces => %w{junit.framework.TestCase},
182
+ :class_annotations => %w{org.junit.runner.RunWith},
183
+ :method_annotations => %w{org.junit.Test})
184
+ end
185
+
186
+ def run(tests, dependencies) #:nodoc:
187
+ # Use Ant to execute the Junit tasks, gives us performance and reporting.
188
+ Buildr.ant('junit') do |ant|
189
+ case options[:fork]
190
+ when false
191
+ forking = {}
192
+ when :each
193
+ forking = { :fork=>true, :forkmode=>'perTest' }
194
+ when true, :once
195
+ forking = { :fork=>true, :forkmode=>'once' }
196
+ else
197
+ fail 'Option fork must be :once, :each or false.'
198
+ end
199
+ mkpath task.report_to.to_s
200
+ ant.junit forking.merge(:clonevm=>options[:clonevm] || false, :dir=>task.send(:project).path_to) do
201
+ ant.classpath :path=>dependencies.join(File::PATH_SEPARATOR)
202
+ (options[:properties] || []).each { |key, value| ant.sysproperty :key=>key, :value=>value }
203
+ (options[:environment] || []).each { |key, value| ant.env :key=>key, :value=>value }
204
+ ant.formatter :type=>'plain'
205
+ ant.formatter :type=>'plain', :usefile=>false # log test
206
+ ant.formatter :type=>'xml'
207
+ ant.batchtest :todir=>task.report_to.to_s, :failureproperty=>'failed' do
208
+ ant.fileset :dir=>task.compile.target.to_s do
209
+ tests.each { |test| ant.include :name=>File.join(*test.split('.')).ext('class') }
210
+ end
211
+ end
212
+ end
213
+ return tests unless ant.project.getProperty('failed')
214
+ end
215
+ # But Ant doesn't tell us what went kaput, so we'll have to parse the test files.
216
+ tests.inject([]) do |passed, test|
217
+ report_file = File.join(task.report_to.to_s, "TEST-#{test}.txt")
218
+ if File.exist?(report_file)
219
+ report = File.read(report_file)
220
+ # The second line (if exists) is the status line and we scan it for its values.
221
+ status = (report.split("\n")[1] || '').scan(/(run|failures|errors):\s*(\d+)/i).
222
+ inject(Hash.new(0)) { |hash, pair| hash[pair[0].downcase.to_sym] = pair[1].to_i ; hash }
223
+ passed << test if status[:failures] == 0 && status[:errors] == 0
224
+ end
225
+ passed
226
+ end
227
+ end
228
+
229
+ namespace 'junit' do
230
+ desc "Generate JUnit tests report in #{report.target}"
231
+ task('report') do |task|
232
+ report.generate Project.projects
233
+ puts "Generated JUnit tests report in #{report.target}" if verbose
234
+ end
235
+ end
236
+
237
+ task('clean') { rm_rf report.target.to_s }
238
+
239
+ end
240
+
241
+
242
+ # TestNG test framework. To use in your project:
243
+ # test.using :testng
244
+ #
245
+ # Support the following options:
246
+ # * :properties -- Hash of properties passed to the test suite.
247
+ # * :java_args -- Arguments passed to the JVM.
248
+ class TestNG < TestFramework::Base
249
+
250
+ # TestNG version number.
251
+ VERSION = '5.5' unless const_defined?('VERSION')
252
+ # TestNG specification.
253
+ REQUIRES = ["org.testng:testng:jar:jdk15:#{VERSION}"] + JMock::REQUIRES
254
+
255
+ include TestFramework::JavaTest
256
+
257
+ def tests(dependencies) #:nodoc:
258
+ filter_classes(dependencies,
259
+ :class_annotations => %w{org.testng.annotations.Test},
260
+ :method_annotations => %w{org.testng.annotations.Test})
261
+ end
262
+
263
+ def run(tests, dependencies) #:nodoc:
264
+ cmd_args = [ 'org.testng.TestNG', '-sourcedir', task.compile.sources.join(';'), '-suitename', task.send(:project).name ]
265
+ cmd_args << '-d' << task.report_to.to_s
266
+ cmd_options = { :properties=>options[:properties], :java_args=>options[:java_args],
267
+ :classpath=>dependencies }
268
+ tests.inject([]) do |passed, test|
269
+ begin
270
+ Java::Commands.java cmd_args, '-testclass', test, cmd_options.merge(:name=>test)
271
+ passed << test
272
+ rescue
273
+ passed
274
+ end
275
+ end
276
+ end
277
+
278
+ end
279
+
280
+ end
281
+
282
+
283
+ Buildr::TestFramework << Buildr::JUnit
284
+ Buildr::TestFramework << Buildr::TestNG
285
+
286
+ # Backward compatibility crap.
287
+ Buildr::JUnit::JUNIT_REQUIRES = Buildr::JUnit::REQUIRES
288
+ Buildr::TestNG::TestNG_REQUIRES = Buildr::TestNG::REQUIRES
289
+ Java::JUnit = Buildr::JUnit
290
+ Java::TestNG = Buildr::TestNG