mguymon-buildr 1.4.5-java

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 (220) hide show
  1. data/CHANGELOG +1291 -0
  2. data/LICENSE +176 -0
  3. data/NOTICE +26 -0
  4. data/README.rdoc +134 -0
  5. data/Rakefile +44 -0
  6. data/_buildr +35 -0
  7. data/_jbuildr +35 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/bnd.rb +147 -0
  10. data/addon/buildr/cobertura.rb +22 -0
  11. data/addon/buildr/drb.rb +281 -0
  12. data/addon/buildr/emma.rb +22 -0
  13. data/addon/buildr/hibernate.rb +149 -0
  14. data/addon/buildr/javacc.rb +85 -0
  15. data/addon/buildr/jaxb_xjc.rb +72 -0
  16. data/addon/buildr/jdepend.rb +60 -0
  17. data/addon/buildr/jetty.rb +248 -0
  18. data/addon/buildr/jibx.rb +86 -0
  19. data/addon/buildr/nailgun.rb +221 -0
  20. data/addon/buildr/openjpa.rb +88 -0
  21. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  22. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  23. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  25. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  26. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  27. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  28. data/addon/buildr/protobuf.rb +88 -0
  29. data/addon/buildr/xmlbeans.rb +93 -0
  30. data/bin/buildr +19 -0
  31. data/buildr.buildfile +58 -0
  32. data/buildr.gemspec +78 -0
  33. data/doc/_config.yml +1 -0
  34. data/doc/_layouts/default.html +90 -0
  35. data/doc/_layouts/preface.html +22 -0
  36. data/doc/artifacts.textile +217 -0
  37. data/doc/building.textile +276 -0
  38. data/doc/contributing.textile +268 -0
  39. data/doc/css/default.css +236 -0
  40. data/doc/css/print.css +101 -0
  41. data/doc/css/syntax.css +23 -0
  42. data/doc/download.textile +151 -0
  43. data/doc/extending.textile +212 -0
  44. data/doc/images/1442160941-frontcover.jpg +0 -0
  45. data/doc/images/asf-logo.gif +0 -0
  46. data/doc/images/asf-logo.png +0 -0
  47. data/doc/images/buildr-hires.png +0 -0
  48. data/doc/images/buildr.png +0 -0
  49. data/doc/images/favicon.png +0 -0
  50. data/doc/images/growl-icon.tiff +0 -0
  51. data/doc/images/note.png +0 -0
  52. data/doc/images/project-structure.png +0 -0
  53. data/doc/images/tip.png +0 -0
  54. data/doc/images/zbuildr.png +0 -0
  55. data/doc/images/zbuildr.tif +0 -0
  56. data/doc/index.textile +109 -0
  57. data/doc/installing.textile +284 -0
  58. data/doc/languages.textile +599 -0
  59. data/doc/mailing_lists.textile +29 -0
  60. data/doc/more_stuff.textile +845 -0
  61. data/doc/packaging.textile +618 -0
  62. data/doc/preface.textile +54 -0
  63. data/doc/projects.textile +276 -0
  64. data/doc/quick_start.textile +210 -0
  65. data/doc/releasing.textile +117 -0
  66. data/doc/scripts/buildr-git.rb +512 -0
  67. data/doc/scripts/gitflow.rb +296 -0
  68. data/doc/scripts/install-jruby.sh +44 -0
  69. data/doc/scripts/install-linux.sh +73 -0
  70. data/doc/scripts/install-osx.sh +52 -0
  71. data/doc/settings_profiles.textile +287 -0
  72. data/doc/testing.textile +247 -0
  73. data/etc/KEYS +189 -0
  74. data/lib/buildr.rb +44 -0
  75. data/lib/buildr/clojure.rb +34 -0
  76. data/lib/buildr/clojure/shell.rb +52 -0
  77. data/lib/buildr/core.rb +34 -0
  78. data/lib/buildr/core/application.rb +700 -0
  79. data/lib/buildr/core/build.rb +516 -0
  80. data/lib/buildr/core/cc.rb +166 -0
  81. data/lib/buildr/core/checks.rb +253 -0
  82. data/lib/buildr/core/common.rb +151 -0
  83. data/lib/buildr/core/compile.rb +622 -0
  84. data/lib/buildr/core/doc.rb +276 -0
  85. data/lib/buildr/core/environment.rb +129 -0
  86. data/lib/buildr/core/filter.rb +404 -0
  87. data/lib/buildr/core/generate.rb +197 -0
  88. data/lib/buildr/core/help.rb +119 -0
  89. data/lib/buildr/core/jrebel.rb +42 -0
  90. data/lib/buildr/core/linux.rb +30 -0
  91. data/lib/buildr/core/osx.rb +46 -0
  92. data/lib/buildr/core/progressbar.rb +161 -0
  93. data/lib/buildr/core/project.rb +975 -0
  94. data/lib/buildr/core/run.rb +43 -0
  95. data/lib/buildr/core/shell.rb +137 -0
  96. data/lib/buildr/core/test.rb +843 -0
  97. data/lib/buildr/core/transports.rb +575 -0
  98. data/lib/buildr/core/util.rb +537 -0
  99. data/lib/buildr/groovy.rb +20 -0
  100. data/lib/buildr/groovy/bdd.rb +106 -0
  101. data/lib/buildr/groovy/compiler.rb +153 -0
  102. data/lib/buildr/groovy/doc.rb +76 -0
  103. data/lib/buildr/groovy/shell.rb +57 -0
  104. data/lib/buildr/ide.rb +19 -0
  105. data/lib/buildr/ide/eclipse.rb +427 -0
  106. data/lib/buildr/ide/eclipse/java.rb +53 -0
  107. data/lib/buildr/ide/eclipse/plugin.rb +71 -0
  108. data/lib/buildr/ide/eclipse/scala.rb +68 -0
  109. data/lib/buildr/ide/idea.rb +576 -0
  110. data/lib/buildr/java.rb +25 -0
  111. data/lib/buildr/java/ant.rb +94 -0
  112. data/lib/buildr/java/bdd.rb +460 -0
  113. data/lib/buildr/java/cobertura.rb +297 -0
  114. data/lib/buildr/java/commands.rb +223 -0
  115. data/lib/buildr/java/compiler.rb +135 -0
  116. data/lib/buildr/java/deprecated.rb +141 -0
  117. data/lib/buildr/java/doc.rb +86 -0
  118. data/lib/buildr/java/ecj.rb +69 -0
  119. data/lib/buildr/java/emma.rb +244 -0
  120. data/lib/buildr/java/external.rb +73 -0
  121. data/lib/buildr/java/jruby.rb +122 -0
  122. data/lib/buildr/java/jtestr_result.rb +295 -0
  123. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  124. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  125. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +142 -0
  126. data/lib/buildr/java/packaging.rb +734 -0
  127. data/lib/buildr/java/pom.rb +178 -0
  128. data/lib/buildr/java/rjb.rb +154 -0
  129. data/lib/buildr/java/test_result.rb +101 -0
  130. data/lib/buildr/java/tests.rb +362 -0
  131. data/lib/buildr/java/version_requirement.rb +172 -0
  132. data/lib/buildr/packaging.rb +25 -0
  133. data/lib/buildr/packaging/archive.rb +535 -0
  134. data/lib/buildr/packaging/artifact.rb +904 -0
  135. data/lib/buildr/packaging/artifact_namespace.rb +984 -0
  136. data/lib/buildr/packaging/artifact_search.rb +140 -0
  137. data/lib/buildr/packaging/gems.rb +105 -0
  138. data/lib/buildr/packaging/package.rb +249 -0
  139. data/lib/buildr/packaging/repository_array.rb +108 -0
  140. data/lib/buildr/packaging/tar.rb +189 -0
  141. data/lib/buildr/packaging/version_requirement.rb +192 -0
  142. data/lib/buildr/packaging/zip.rb +178 -0
  143. data/lib/buildr/packaging/ziptask.rb +356 -0
  144. data/lib/buildr/resources/buildr.icns +0 -0
  145. data/lib/buildr/resources/completed.png +0 -0
  146. data/lib/buildr/resources/failed.png +0 -0
  147. data/lib/buildr/resources/icons-license.txt +17 -0
  148. data/lib/buildr/run.rb +195 -0
  149. data/lib/buildr/scala.rb +26 -0
  150. data/lib/buildr/scala/bdd.rb +118 -0
  151. data/lib/buildr/scala/compiler.rb +242 -0
  152. data/lib/buildr/scala/doc.rb +142 -0
  153. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.class +0 -0
  154. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.java +57 -0
  155. data/lib/buildr/scala/shell.rb +52 -0
  156. data/lib/buildr/scala/tests.rb +171 -0
  157. data/lib/buildr/shell.rb +185 -0
  158. data/lib/buildr/version.rb +18 -0
  159. data/rakelib/all-in-one.rake +113 -0
  160. data/rakelib/checks.rake +57 -0
  161. data/rakelib/doc.rake +137 -0
  162. data/rakelib/metrics.rake +39 -0
  163. data/rakelib/package.rake +73 -0
  164. data/rakelib/release.rake +160 -0
  165. data/rakelib/rspec.rake +91 -0
  166. data/rakelib/setup.rake +66 -0
  167. data/rakelib/stage.rake +220 -0
  168. data/spec/addon/bnd_spec.rb +330 -0
  169. data/spec/addon/drb_spec.rb +328 -0
  170. data/spec/addon/jaxb_xjc_spec.rb +125 -0
  171. data/spec/core/application_spec.rb +631 -0
  172. data/spec/core/build_spec.rb +837 -0
  173. data/spec/core/cc_spec.rb +224 -0
  174. data/spec/core/checks_spec.rb +519 -0
  175. data/spec/core/common_spec.rb +725 -0
  176. data/spec/core/compile_spec.rb +658 -0
  177. data/spec/core/doc_spec.rb +195 -0
  178. data/spec/core/extension_spec.rb +201 -0
  179. data/spec/core/generate_spec.rb +33 -0
  180. data/spec/core/project_spec.rb +772 -0
  181. data/spec/core/run_spec.rb +93 -0
  182. data/spec/core/shell_spec.rb +146 -0
  183. data/spec/core/test_spec.rb +1320 -0
  184. data/spec/core/transport_spec.rb +544 -0
  185. data/spec/core/util_spec.rb +141 -0
  186. data/spec/groovy/bdd_spec.rb +80 -0
  187. data/spec/groovy/compiler_spec.rb +251 -0
  188. data/spec/groovy/doc_spec.rb +65 -0
  189. data/spec/ide/eclipse_spec.rb +739 -0
  190. data/spec/ide/idea_spec.rb +1145 -0
  191. data/spec/java/ant_spec.rb +37 -0
  192. data/spec/java/bdd_spec.rb +374 -0
  193. data/spec/java/cobertura_spec.rb +112 -0
  194. data/spec/java/commands_spec.rb +93 -0
  195. data/spec/java/compiler_spec.rb +252 -0
  196. data/spec/java/doc_spec.rb +56 -0
  197. data/spec/java/ecj_spec.rb +115 -0
  198. data/spec/java/emma_spec.rb +121 -0
  199. data/spec/java/external_spec.rb +56 -0
  200. data/spec/java/java_spec.rb +132 -0
  201. data/spec/java/packaging_spec.rb +1266 -0
  202. data/spec/java/run_spec.rb +78 -0
  203. data/spec/java/test_coverage_helper.rb +257 -0
  204. data/spec/java/tests_spec.rb +497 -0
  205. data/spec/packaging/archive_spec.rb +775 -0
  206. data/spec/packaging/artifact_namespace_spec.rb +743 -0
  207. data/spec/packaging/artifact_spec.rb +1074 -0
  208. data/spec/packaging/packaging_helper.rb +63 -0
  209. data/spec/packaging/packaging_spec.rb +719 -0
  210. data/spec/packaging/repository_array_spec.rb +109 -0
  211. data/spec/sandbox.rb +165 -0
  212. data/spec/scala/bdd_spec.rb +124 -0
  213. data/spec/scala/compiler_spec.rb +289 -0
  214. data/spec/scala/doc_spec.rb +88 -0
  215. data/spec/scala/scala.rb +38 -0
  216. data/spec/scala/tests_spec.rb +283 -0
  217. data/spec/spec_helpers.rb +369 -0
  218. data/spec/version_requirement_spec.rb +143 -0
  219. data/spec/xpath_matchers.rb +121 -0
  220. metadata +600 -0
@@ -0,0 +1,166 @@
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/common'
17
+ require 'buildr/core/project'
18
+ require 'buildr/core/build'
19
+ require 'buildr/core/compile'
20
+
21
+ module Buildr
22
+ class CCTask < Rake::Task
23
+ attr_accessor :delay
24
+ attr_reader :project
25
+
26
+ def initialize(*args)
27
+ super
28
+ @delay = 0.2
29
+ enhance do
30
+ monitor_and_compile
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # run block on sub-projects depth-first, then on this project
37
+ def each_project(&block)
38
+ depth_first = lambda do |p|
39
+ p.projects.each { |c| depth_first.call(c, &block) }
40
+ block.call(p)
41
+ end
42
+ depth_first.call(@project)
43
+ end
44
+
45
+ def associate_with(project)
46
+ @project = project
47
+ end
48
+
49
+ def monitor_and_compile
50
+ # we don't want to actually fail if our dependencies don't succeed
51
+ begin
52
+ each_project { |p| p.test.compile.invoke }
53
+ build_completed(project)
54
+ rescue Exception => ex
55
+ $stderr.puts $terminal.color(ex.message, :red)
56
+ $stderr.puts
57
+
58
+ build_failed(project, ex)
59
+ end
60
+
61
+ dirs = []
62
+ each_project do |p|
63
+ dirs += p.compile.sources.map(&:to_s)
64
+ dirs += p.test.compile.sources.map(&:to_s)
65
+ dirs += p.resources.sources.map(&:to_s)
66
+ end
67
+ if dirs.length == 1
68
+ info "Monitoring directory: #{dirs.first}"
69
+ else
70
+ info "Monitoring directories: [#{dirs.join ', '}]"
71
+ end
72
+
73
+ timestamps = lambda do
74
+ times = {}
75
+ dirs.each { |d| Dir.glob("#{d}/**/*").map { |f| times[f] = File.mtime f } }
76
+ times
77
+ end
78
+
79
+ old_times = timestamps.call()
80
+
81
+ while true
82
+ sleep delay
83
+
84
+ new_times = timestamps.call()
85
+ changed = changed(new_times, old_times)
86
+ old_times = new_times
87
+
88
+ unless changed.empty?
89
+ info '' # better spacing
90
+
91
+ changed.each do |file|
92
+ info "Detected changes in #{file}"
93
+ end
94
+
95
+ each_project do |p|
96
+ # transitively reenable prerequisites
97
+ reenable = lambda do |t|
98
+ t = task(t)
99
+ t.reenable
100
+ t.prerequisites.each { |c| reenable.call(c) }
101
+ end
102
+ reenable.call(p.test.compile)
103
+ end
104
+
105
+ successful = true
106
+ begin
107
+ each_project { |p| p.test.compile.invoke }
108
+ build_completed(project)
109
+ rescue Exception => ex
110
+ $stderr.puts $terminal.color(ex.message, :red)
111
+ build_failed(project, ex)
112
+ successful = false
113
+ end
114
+
115
+ puts $terminal.color("Build complete", :green) if successful
116
+ end
117
+ end
118
+ end
119
+
120
+ def build_completed(project)
121
+ Buildr.application.build_completed('Compilation successful', project.path_to)
122
+ end
123
+
124
+ def build_failed(project, ex = nil)
125
+ Buildr.application.build_failed('Compilation failed', project.path_to, ex)
126
+ end
127
+
128
+ def changed(new_times, old_times)
129
+ changed = []
130
+ new_times.each do |(fname,newtime)|
131
+ if old_times[fname].nil? || old_times[fname] < newtime
132
+ changed << fname
133
+ end
134
+ end
135
+
136
+ # detect deletion (slower than it could be)
137
+ old_times.each_key do |fname|
138
+ changed << fname unless new_times.has_key? fname
139
+ end
140
+
141
+ changed
142
+ end
143
+ end
144
+
145
+ module CC
146
+ include Extension
147
+
148
+ first_time do
149
+ desc 'Execute continuous compilation, listening to changes'
150
+ Project.local_task('cc') { |name| "Executing continuous compilation for #{name}" }
151
+ end
152
+
153
+ before_define do |project|
154
+ cc = CCTask.define_task :cc
155
+ cc.send :associate_with, project
156
+ end
157
+
158
+ def cc
159
+ task :cc
160
+ end
161
+ end
162
+
163
+ class Project
164
+ include CC
165
+ end
166
+ end
@@ -0,0 +1,253 @@
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/project'
18
+ autoload :RSpec, 'rspec'
19
+
20
+ module Buildr
21
+ # Methods added to Project to allow checking the build.
22
+ module Checks
23
+
24
+ module Matchers #:nodoc:
25
+
26
+ class << self
27
+
28
+ # Define matchers that operate by calling a method on the tested object.
29
+ # For example:
30
+ # foo.should contain(bar)
31
+ # calls:
32
+ # foo.contain(bar)
33
+ def match_using(*names)
34
+ names.each do |name|
35
+ matcher = Class.new do
36
+ # Initialize with expected arguments (i.e. contain(bar) initializes with bar).
37
+ define_method(:initialize) { |*args| @expects = args }
38
+ # Matches against actual value (i.e. foo.should exist called with foo).
39
+ define_method(:matches?) do |actual|
40
+ @actual = actual
41
+ return actual.send("#{name}?", *@expects) if actual.respond_to?("#{name}?")
42
+ return actual.send(name, *@expects) if actual.respond_to?(name)
43
+ raise "You can't check #{actual}, it doesn't respond to #{name}."
44
+ end
45
+ # Some matchers have arguments, others don't, treat appropriately.
46
+ define_method :failure_message do
47
+ args = " " + @expects.map{ |arg| "'#{arg}'" }.join(", ") unless @expects.empty?
48
+ "Expected #{@actual} to #{name}#{args}"
49
+ end
50
+ define_method :negative_failure_message do
51
+ args = " " + @expects.map{ |arg| "'#{arg}'" }.join(", ") unless @expects.empty?
52
+ "Expected #{@actual} to not #{name}#{args}"
53
+ end
54
+ end
55
+ # Define method to create matcher.
56
+ define_method(name) { |*args| matcher.new(*args) }
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ # Define delegate matchers for exist and contain methods.
63
+ match_using :exist, :contain
64
+
65
+ end
66
+
67
+
68
+ # An expectation has subject, description and block. The expectation is validated by running the block,
69
+ # and can access the subject from the method #it. The description is used for reporting.
70
+ #
71
+ # The expectation is run by calling #run_against. You can share expectations by running them against
72
+ # different projects (or any other context for that matter).
73
+ #
74
+ # If the subject is missing, it is set to the argument of #run_against, typically the project itself.
75
+ # If the description is missing, it is set from the project. If the block is missing, the default behavior
76
+ # prints "Pending" followed by the description. You can use this to write place holders and fill them later.
77
+ class Expectation
78
+
79
+ attr_reader :description, :subject, :block
80
+
81
+ # :call-seq:
82
+ # initialize(subject, description?) { .... }
83
+ # initialize(description?) { .... }
84
+ #
85
+ # First argument is subject (returned from it method), second argument is description. If you omit the
86
+ # description, it will be set from the subject. If you omit the subject, it will be set from the object
87
+ # passed to run_against.
88
+ def initialize(*args, &block)
89
+ @description = args.pop if String === args.last
90
+ @subject = args.shift
91
+ raise ArgumentError, "Expecting subject followed by description, and either one is optional. Not quite sure what to do with this list of arguments." unless args.empty?
92
+ @block = block || lambda { |klass| info "Pending: #{description}" }
93
+ end
94
+
95
+ # :call-seq:
96
+ # run_against(context)
97
+ #
98
+ # Runs this expectation against the context object. The context object is different from the subject,
99
+ # but used as the subject if no subject specified (i.e. returned from the it method).
100
+ #
101
+ # This method creates a new context object modeled after the context argument, but a separate object
102
+ # used strictly for running this expectation, and used only once. The context object will pass methods
103
+ # to the context argument, so you can call any method, e.g. package(:jar).
104
+ #
105
+ # It also adds all matchers defined in Buildr and RSpec, and two additional methods:
106
+ # * it() -- Returns the subject.
107
+ # * description() -- Returns the description.
108
+ def run_against(context)
109
+ subject = @subject || context
110
+ description = @description ? "#{subject} #{@description}" : subject.to_s
111
+ # Define anonymous class and load it with:
112
+ # - All instance methods defined in context, so we can pass method calls to the context.
113
+ # - it() method to return subject, description() method to return description.
114
+ # - All matchers defined by Buildr and RSpec.
115
+ klass = Class.new
116
+ klass.instance_eval do
117
+ context.class.instance_methods.each do |method|
118
+ define_method(method) { |*args| context.send(method, *args) } unless instance_methods.include?(method)
119
+ end
120
+ define_method(:it) { subject }
121
+ define_method(:description) { description }
122
+ include ::RSpec::Matchers
123
+ include Matchers
124
+ end
125
+
126
+ # Run the expectation. We only print the expectation name when tracing (to know they all ran),
127
+ # or when we get a failure.
128
+ begin
129
+ trace description
130
+ klass.new.instance_eval &@block
131
+ rescue Exception=>error
132
+ raise error.exception("#{description}\n#{error}").tap { |wrapped| wrapped.set_backtrace(error.backtrace) }
133
+ end
134
+ end
135
+
136
+ end
137
+
138
+
139
+ include Extension
140
+
141
+ before_define(:check => :package) do |project|
142
+ # The check task can do any sort of interesting things, but the most important is running expectations.
143
+ project.task("check") do |task|
144
+ project.expectations.inject(true) do |passed, expect|
145
+ begin
146
+ expect.run_against project
147
+ passed
148
+ rescue Exception=>ex
149
+ if verbose
150
+ error ex
151
+ error ex.backtrace.select { |line| line =~ /#{Buildr.application.buildfile}/ }.join("\n")
152
+ end
153
+ false
154
+ end
155
+ end or fail "Checks failed for project #{project.name} (see errors above)."
156
+ end
157
+ project.task("package").enhance do |task|
158
+ # Run all actions before checks.
159
+ task.enhance { project.task("check").invoke }
160
+ end
161
+ end
162
+
163
+
164
+ # :call-seq:
165
+ # check(description) { ... }
166
+ # check(subject, description) { ... }
167
+ #
168
+ # Adds an expectation. The expectation is run against the project by the check task, executed after packaging.
169
+ # You can access any package created by the project.
170
+ #
171
+ # An expectation is written using a subject, description and block to validate the expectation. For example:
172
+ #
173
+ # For example:
174
+ # check package(:jar), "should exist" do
175
+ # it.should exist
176
+ # end
177
+ # check package(:jar), "should contain a manifest" do
178
+ # it.should contain("META-INF/MANIFEST.MF")
179
+ # end
180
+ # check package(:jar).path("com/acme"), "should contain classes" do
181
+ # it.should_not be_empty
182
+ # end
183
+ # check package(:jar).entry("META-INF/MANIFEST"), "should be a recent license" do
184
+ # it.should contain(/Copyright (C) 2007/)
185
+ # end
186
+ #
187
+ # If you omit the subject, the project is used as the subject. If you omit the description, the subject is
188
+ # used as description.
189
+ #
190
+ # During development you can write placeholder expectations by omitting the block. This will simply report
191
+ # the expectation as pending.
192
+ def check(*args, &block)
193
+ expectations << Checks::Expectation.new(*args, &block)
194
+ end
195
+
196
+ # :call-seq:
197
+ # expectations() => Expectation*
198
+ #
199
+ # Returns a list of expectations (see #check).
200
+ def expectations()
201
+ @expectations ||= []
202
+ end
203
+
204
+ end
205
+
206
+ end
207
+
208
+
209
+ module Rake #:nodoc:
210
+ class FileTask
211
+
212
+ # :call-seq:
213
+ # exist?() => boolean
214
+ #
215
+ # Returns true if this file exists.
216
+ def exist?()
217
+ File.exist?(name)
218
+ end
219
+
220
+ # :call-seq:
221
+ # empty?() => boolean
222
+ #
223
+ # Returns true if file/directory is empty.
224
+ def empty?()
225
+ File.directory?(name) ? Dir.glob("#{name}/*").empty? : File.read(name).empty?
226
+ end
227
+
228
+ # :call-seq:
229
+ # contain?(pattern*) => boolean
230
+ # contain?(file*) => boolean
231
+ #
232
+ # For a file, returns true if the file content matches against all the arguments. An argument may be
233
+ # a string or regular expression.
234
+ #
235
+ # For a directory, return true if the directory contains the specified files. You can use relative
236
+ # file names and glob patterns (using *, **, etc).
237
+ def contain?(*patterns)
238
+ if File.directory?(name)
239
+ patterns.map { |pattern| "#{name}/#{pattern}" }.all? { |pattern| !Dir[pattern].empty? }
240
+ else
241
+ contents = File.read(name)
242
+ patterns.map { |pattern| Regexp === pattern ? pattern : Regexp.new(Regexp.escape(pattern.to_s)) }.
243
+ all? { |pattern| contents =~ pattern }
244
+ end
245
+ end
246
+
247
+ end
248
+ end
249
+
250
+
251
+ class Buildr::Project
252
+ include Buildr::Checks
253
+ end
@@ -0,0 +1,151 @@
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 'rake'
18
+ require 'buildr/core/util'
19
+
20
+
21
+ module Buildr
22
+
23
+ # :call-seq:
24
+ # struct(hash) => Struct
25
+ #
26
+ # Convenience method for creating an anonymous Struct.
27
+ #
28
+ # For example:
29
+ # COMMONS = struct(
30
+ # :collections =>'commons-collections:commons-collections:jar:3.1',
31
+ # :lang =>'commons-lang:commons-lang:jar:2.1',
32
+ # :logging =>'commons-logging:commons-logging:jar:1.0.3',
33
+ # )
34
+ #
35
+ # compile.with COMMONS.logging
36
+ def struct(hash)
37
+ Struct.new(nil, *hash.keys).new(*hash.values)
38
+ end
39
+
40
+ # :call-seq:
41
+ # write(name, content)
42
+ # write(name) { ... }
43
+ #
44
+ # Write the contents into a file. The second form calls the block and writes the result.
45
+ #
46
+ # For example:
47
+ # write 'TIMESTAMP', Time.now
48
+ # write('TIMESTAMP') { Time.now }
49
+ #
50
+ # Yields to the block before writing the file, so you can chain read and write together.
51
+ # For example:
52
+ # write('README') { read('README').sub("${build}", Time.now) }
53
+ def write(name, content = nil)
54
+ mkpath File.dirname(name)
55
+ content = yield if block_given?
56
+ File.open(name.to_s, 'wb') { |file| file.write content.to_s }
57
+ content.to_s
58
+ end
59
+
60
+ # :call-seq:
61
+ # read(args) => string
62
+ # read(args) { |string| ... } => result
63
+ #
64
+ # Reads and returns the contents of a file. The second form yields to the block and returns
65
+ # the result of the block. The args passed to read are passed on to File.open.
66
+ #
67
+ # For example:
68
+ # puts read('README')
69
+ # read('README') { |text| puts text }
70
+ def read(*args)
71
+ args[0] = args[0].to_s
72
+ contents = File.open(*args) { |f| f.read }
73
+ if block_given?
74
+ yield contents
75
+ else
76
+ contents
77
+ end
78
+ end
79
+
80
+ # :call-seq:
81
+ # download(url_or_uri) => task
82
+ # download(path=>url_or_uri) =>task
83
+ #
84
+ # Create a task that will download a file from a URL.
85
+ #
86
+ # Takes a single argument, a hash with one pair. The key is the file being
87
+ # created, the value if the URL to download. The task executes only if the
88
+ # file does not exist; the URL is not checked for updates.
89
+ #
90
+ # The task will show download progress on the console; if there are MD5/SHA1
91
+ # checksums on the server it will verify the download before saving it.
92
+ #
93
+ # For example:
94
+ # download 'image.jpg'=>'http://example.com/theme/image.jpg'
95
+ def download(args)
96
+ args = URI.parse(args) if String === args
97
+ if URI === args
98
+ # Given only a download URL, download into a temporary file.
99
+ # You can infer the file from task name.
100
+ temp = Tempfile.open(File.basename(args.to_s))
101
+ file(temp.path).tap do |task|
102
+ # Since temporary file exists, force a download.
103
+ class << task ; def needed? ; true ; end ; end
104
+ task.sources << args
105
+ task.enhance { args.download temp }
106
+ end
107
+ else
108
+ # Download to a file created by the task.
109
+ fail unless args.keys.size == 1
110
+ uri = URI.parse(args.values.first.to_s)
111
+ file(args.keys.first.to_s).tap do |task|
112
+ task.sources << uri
113
+ task.enhance { uri.download task.name }
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ # A file task that concatenates all its prerequisites to create a new file.
120
+ #
121
+ # For example:
122
+ # concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
123
+ #
124
+ # See also Buildr#concat.
125
+ class ConcatTask < Rake::FileTask
126
+ def initialize(*args) #:nodoc:
127
+ super
128
+ enhance do |task|
129
+ content = prerequisites.inject("") do |content, prereq|
130
+ content << File.read(prereq.to_s) if File.exists?(prereq) && !File.directory?(prereq)
131
+ content
132
+ end
133
+ File.open(task.name, "wb") { |file| file.write content }
134
+ end
135
+ end
136
+ end
137
+
138
+ # :call-seq:
139
+ # concat(target=>files) => task
140
+ #
141
+ # Creates and returns a file task that concatenates all its prerequisites to create
142
+ # a new file. See #ConcatTask.
143
+ #
144
+ # For example:
145
+ # concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
146
+ def concat(args)
147
+ file, arg_names, deps = Buildr.application.resolve_args([args])
148
+ ConcatTask.define_task(File.expand_path(file)=>deps)
149
+ end
150
+
151
+ end