buildr 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/CHANGELOG +66 -4
  2. data/{README → README.rdoc} +29 -16
  3. data/Rakefile +16 -20
  4. data/_buildr +38 -0
  5. data/addon/buildr/cobertura.rb +49 -45
  6. data/addon/buildr/emma.rb +238 -0
  7. data/addon/buildr/jetty.rb +1 -1
  8. data/addon/buildr/nailgun.rb +585 -661
  9. data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail$Main.class +0 -0
  10. data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail.class +0 -0
  11. data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail.java +0 -0
  12. data/bin/buildr +9 -2
  13. data/buildr.buildfile +53 -0
  14. data/buildr.gemspec +21 -14
  15. data/doc/css/default.css +51 -48
  16. data/doc/css/print.css +60 -55
  17. data/doc/images/favicon.png +0 -0
  18. data/doc/images/growl-icon.tiff +0 -0
  19. data/doc/images/project-structure.png +0 -0
  20. data/doc/pages/artifacts.textile +46 -156
  21. data/doc/pages/building.textile +63 -323
  22. data/doc/pages/contributing.textile +112 -102
  23. data/doc/pages/download.textile +19 -27
  24. data/doc/pages/extending.textile +27 -81
  25. data/doc/pages/getting_started.textile +44 -119
  26. data/doc/pages/index.textile +26 -47
  27. data/doc/pages/languages.textile +407 -0
  28. data/doc/pages/more_stuff.textile +92 -173
  29. data/doc/pages/packaging.textile +71 -239
  30. data/doc/pages/projects.textile +58 -233
  31. data/doc/pages/recipes.textile +19 -43
  32. data/doc/pages/settings_profiles.textile +39 -104
  33. data/doc/pages/testing.textile +41 -304
  34. data/doc/pages/troubleshooting.textile +29 -47
  35. data/doc/pages/whats_new.textile +69 -167
  36. data/doc/print.haml +0 -1
  37. data/doc/print.toc.yaml +1 -0
  38. data/doc/scripts/buildr-git.rb +1 -1
  39. data/doc/site.haml +1 -0
  40. data/doc/site.toc.yaml +8 -5
  41. data/{KEYS → etc/KEYS} +0 -0
  42. data/etc/git-svn-authors +16 -0
  43. data/lib/buildr.rb +2 -5
  44. data/lib/buildr/core/application.rb +192 -98
  45. data/lib/buildr/core/build.rb +140 -91
  46. data/lib/buildr/core/checks.rb +5 -5
  47. data/lib/buildr/core/common.rb +1 -1
  48. data/lib/buildr/core/compile.rb +12 -10
  49. data/lib/buildr/core/filter.rb +151 -46
  50. data/lib/buildr/core/generate.rb +9 -9
  51. data/lib/buildr/core/progressbar.rb +1 -1
  52. data/lib/buildr/core/project.rb +8 -7
  53. data/lib/buildr/core/test.rb +51 -26
  54. data/lib/buildr/core/transports.rb +22 -38
  55. data/lib/buildr/core/util.rb +78 -26
  56. data/lib/buildr/groovy.rb +18 -0
  57. data/lib/buildr/groovy/bdd.rb +105 -0
  58. data/lib/buildr/groovy/compiler.rb +138 -0
  59. data/lib/buildr/ide/eclipse.rb +102 -71
  60. data/lib/buildr/ide/idea.rb +7 -12
  61. data/lib/buildr/ide/idea7x.rb +7 -8
  62. data/lib/buildr/java.rb +4 -7
  63. data/lib/buildr/java/ant.rb +26 -5
  64. data/lib/buildr/java/bdd.rb +449 -0
  65. data/lib/buildr/java/commands.rb +9 -9
  66. data/lib/buildr/java/{compilers.rb → compiler.rb} +8 -90
  67. data/lib/buildr/java/jruby.rb +29 -11
  68. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  69. data/lib/buildr/java/packaging.rb +23 -16
  70. data/lib/buildr/java/pom.rb +1 -1
  71. data/lib/buildr/java/rjb.rb +21 -8
  72. data/lib/buildr/java/test_result.rb +308 -0
  73. data/lib/buildr/java/tests.rb +324 -0
  74. data/lib/buildr/packaging/artifact.rb +12 -11
  75. data/lib/buildr/packaging/artifact_namespace.rb +7 -4
  76. data/lib/buildr/packaging/gems.rb +3 -3
  77. data/lib/buildr/packaging/zip.rb +13 -10
  78. data/lib/buildr/resources/buildr.icns +0 -0
  79. data/lib/buildr/scala.rb +19 -0
  80. data/lib/buildr/scala/compiler.rb +109 -0
  81. data/lib/buildr/scala/tests.rb +203 -0
  82. data/rakelib/apache.rake +71 -45
  83. data/rakelib/doc.rake +2 -2
  84. data/rakelib/package.rake +3 -2
  85. data/rakelib/rspec.rake +23 -21
  86. data/rakelib/setup.rake +34 -9
  87. data/rakelib/stage.rake +4 -1
  88. data/spec/addon/cobertura_spec.rb +77 -0
  89. data/spec/addon/emma_spec.rb +120 -0
  90. data/spec/addon/test_coverage_spec.rb +255 -0
  91. data/spec/{application_spec.rb → core/application_spec.rb} +82 -4
  92. data/spec/{artifact_namespace_spec.rb → core/artifact_namespace_spec.rb} +12 -1
  93. data/spec/core/build_spec.rb +415 -0
  94. data/spec/{checks_spec.rb → core/checks_spec.rb} +2 -2
  95. data/spec/{common_spec.rb → core/common_spec.rb} +119 -30
  96. data/spec/{compile_spec.rb → core/compile_spec.rb} +17 -13
  97. data/spec/core/generate_spec.rb +33 -0
  98. data/spec/{project_spec.rb → core/project_spec.rb} +9 -6
  99. data/spec/{test_spec.rb → core/test_spec.rb} +222 -28
  100. data/spec/{transport_spec.rb → core/transport_spec.rb} +5 -9
  101. data/spec/groovy/bdd_spec.rb +80 -0
  102. data/spec/{groovy_compilers_spec.rb → groovy/compiler_spec.rb} +1 -1
  103. data/spec/ide/eclipse_spec.rb +243 -0
  104. data/spec/{java_spec.rb → java/ant.rb} +7 -17
  105. data/spec/java/bdd_spec.rb +358 -0
  106. data/spec/{java_compilers_spec.rb → java/compiler_spec.rb} +1 -1
  107. data/spec/java/java_spec.rb +88 -0
  108. data/spec/{java_packaging_spec.rb → java/packaging_spec.rb} +65 -4
  109. data/spec/{java_test_frameworks_spec.rb → java/tests_spec.rb} +31 -10
  110. data/spec/{archive_spec.rb → packaging/archive_spec.rb} +12 -2
  111. data/spec/{artifact_spec.rb → packaging/artifact_spec.rb} +12 -5
  112. data/spec/{packaging_helper.rb → packaging/packaging_helper.rb} +0 -0
  113. data/spec/{packaging_spec.rb → packaging/packaging_spec.rb} +1 -1
  114. data/spec/sandbox.rb +22 -5
  115. data/spec/{scala_compilers_spec.rb → scala/compiler_spec.rb} +1 -1
  116. data/spec/{scala_test_frameworks_spec.rb → scala/tests_spec.rb} +11 -12
  117. data/spec/spec_helpers.rb +38 -17
  118. metadata +103 -70
  119. data/lib/buildr/java/bdd_frameworks.rb +0 -265
  120. data/lib/buildr/java/groovyc.rb +0 -137
  121. data/lib/buildr/java/test_frameworks.rb +0 -450
  122. data/spec/build_spec.rb +0 -193
  123. data/spec/java_bdd_frameworks_spec.rb +0 -238
  124. data/spec/spec.opts +0 -6
@@ -27,7 +27,6 @@
27
27
  %body
28
28
  #wrap
29
29
  #header
30
- %img{ :src=>'images/apache-incubator-logo.png', :alt=>'Apache Incubator', :style=>'float:right;width:10em' }
31
30
  %img{ :src=>'images/buildr-hires.png', :alt=>collection.title, :style=>'width:20em' }
32
31
  .tagline= ''
33
32
  #content
@@ -21,6 +21,7 @@
21
21
  - Packaging: packaging.html
22
22
  - Testing: testing.html
23
23
  - Settings/Profiles: settings_profiles.html
24
+ - Languages: languages.html
24
25
  - More Stuff: more_stuff.html
25
26
  - Extending: extending.html
26
27
  - Recipes: recipes.html
@@ -28,7 +28,7 @@ require 'ostruct'
28
28
 
29
29
  # Pager from http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
30
30
  def run_pager
31
- return if PLATFORM =~ /win32/
31
+ return if RUBY_PLATFORM =~ /win32/
32
32
  return unless STDOUT.tty?
33
33
 
34
34
  read, write = IO.pipe
@@ -25,6 +25,7 @@
25
25
  @import 'css/print.css';
26
26
  \#header { display: none }
27
27
  %meta{ :name=>'subject', :content=>'Official Buildr documentation from the people in the know' }
28
+ %link{ :rel=>'shortcut icon', :href=>'images/favicon.png'}
28
29
  %body
29
30
  #wrap
30
31
  #header
@@ -13,11 +13,12 @@
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
15
 
16
- - Main:
16
+ - Start Here:
17
17
  - Welcome: index.html
18
18
  - Download and Installation: download.html
19
- - Printable PDF: buildr.pdf
20
- - New: whats_new.html
19
+ - User Guide (PDF): buildr.pdf
20
+ - What's New: whats_new.html
21
+ - Community Wiki: http://cwiki.apache.org/confluence/display/BUILDR/Index
21
22
  - Using Buildr:
22
23
  - Getting Started: getting_started.html
23
24
  - Projects: projects.html
@@ -26,6 +27,7 @@
26
27
  - Packaging: packaging.html
27
28
  - Testing: testing.html
28
29
  - Settings/Profiles: settings_profiles.html
30
+ - Languages: languages.html
29
31
  - More Stuff: more_stuff.html
30
32
  - Extending: extending.html
31
33
  - Recipes: recipes.html
@@ -34,11 +36,12 @@
34
36
  - Rake: http://docs.rubyrake.org
35
37
  - Antwrap: http://antwrap.rubyforge.org
36
38
  - Troubleshooting: troubleshooting.html
37
- - Getting Involved:
38
- - Contributing: contributing.html
39
+ - Get Involved:
39
40
  - Mailing Lists: mailing_lists.html
40
41
  - Issues/Bugs: http://issues.apache.org/jira/browse/Buildr
42
+ - Contributing: contributing.html
41
43
  - Project Status:
42
44
  - License: license.html
43
45
  - Change Log: changelog.html
44
46
  - Specs: specs.html
47
+ - Coverage: coverage/index.html
File without changes
@@ -0,0 +1,16 @@
1
+ # This file is used by git-svn
2
+ #
3
+ # Format is
4
+ # <apache svn login> = John Doe <john.doe@hacker.mail>
5
+ #
6
+ # If you are a committer and want to use git-svn to hack on
7
+ # buildr, please add yourself here and commit this file via svn.
8
+ # Then run the buildr-git.rb script to obtain and configure
9
+ # a local buildr-git copy.
10
+ #
11
+
12
+ assaf = Assaf Arkin <assaf@apache.org>
13
+ boisvert = Alex Boisvert <alex.boisvert@gmail.com>
14
+ lacton = Lacton <lacton@apache.org>
15
+ mriou = Matthieu Riou <mriou@apache.org>
16
+ vborja = Victor Hugo Borja <vic.borja@gmail.com>
@@ -13,10 +13,8 @@
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
15
 
16
-
17
- $KCODE = 'utf8'
18
16
  module Buildr
19
- VERSION = '1.3.2'.freeze # unless const_defined?(:VERSION)
17
+ VERSION = '1.3.3'.freeze
20
18
  end
21
19
 
22
20
  require 'buildr/core'
@@ -34,5 +32,4 @@ class Object #:nodoc:
34
32
  end
35
33
 
36
34
  # Prevent RSpec runner from running at_exit.
37
- require 'spec'
38
- Spec.run = true
35
+ require 'spec'
@@ -36,7 +36,6 @@
36
36
 
37
37
 
38
38
  require 'highline/import'
39
- require 'benchmark'
40
39
  require 'rake'
41
40
  require 'rubygems/source_info_cache'
42
41
  require 'buildr/core/application_cli'
@@ -47,12 +46,13 @@ require 'buildr/core/util'
47
46
  ENV["HOME"] ||= File.expand_path(Gem::user_home)
48
47
  ENV['BUILDR_ENV'] ||= 'development'
49
48
 
49
+
50
50
  module Buildr
51
51
 
52
52
  # Provide settings that come from three sources.
53
53
  #
54
54
  # User settings are placed in the .buildr/settings.yaml file located in the user's home directory.
55
- # The should only be used for settings that are specific to the user and applied the same way
55
+ # They should only be used for settings that are specific to the user and applied the same way
56
56
  # across all builds. Example for user settings are preferred repositories, path to local repository,
57
57
  # user/name password for uploading to remote repository.
58
58
  #
@@ -93,11 +93,12 @@ module Buildr
93
93
  private
94
94
 
95
95
  def load_from(base_name, dir = nil)
96
- file_name = ['yaml', 'yml'].map { |ext| File.expand_path("#{base_name}.#{ext}", dir) }.find { |fn| File.exist?(fn) }
96
+ base_name = File.expand_path(base_name, dir) if dir
97
+ file_name = ['yaml', 'yml'].map { |ext| "#{base_name}.#{ext}" }.find { |fn| File.exist?(fn) }
97
98
  return {} unless file_name
98
99
  yaml = YAML.load(File.read(file_name)) || {}
99
100
  fail "Expecting #{file_name} to be a map (name: value)!" unless Hash === yaml
100
- @application.build_files << file_name
101
+ @application.buildfile.enhance [file_name]
101
102
  yaml
102
103
  end
103
104
 
@@ -121,10 +122,11 @@ module Buildr
121
122
  @top_level_tasks = []
122
123
  parse_options
123
124
  collect_tasks
124
- top_level_tasks.unshift 'buildr:initialize'
125
125
  @home_dir = File.expand_path('.buildr', ENV['HOME'])
126
- mkpath @home_dir unless File.exist?(@home_dir)
126
+ mkpath @home_dir, :verbose=>false unless File.exist?(@home_dir)
127
127
  @environment = ENV['BUILDR_ENV'] ||= 'development'
128
+ @on_completion = []
129
+ @on_failure = []
128
130
  end
129
131
 
130
132
  # Returns list of Gems associated with this buildfile, as listed in build.yaml.
@@ -139,23 +141,80 @@ module Buildr
139
141
 
140
142
  # Returns the Settings associated with this build.
141
143
  def settings
144
+ fail "Internal error: Called Buildr.settings before buildfile located" unless rakefile
142
145
  @settings ||= Settings.new(self)
143
146
  end
144
147
 
145
148
  # :call-seq:
146
149
  # buildfile
150
+ # Returns the buildfile as a task that you can use as a dependency.
147
151
  def buildfile
148
- rakefile
152
+ @buildfile_task ||= BuildfileTask.define_task(File.expand_path(rakefile))
153
+ end
154
+
155
+ # Files that complement the buildfile itself
156
+ def build_files #:nodoc:
157
+ buildfile.prerequisites
158
+ end
159
+
160
+ def run
161
+ standard_exception_handling do
162
+ find_buildfile
163
+ load_gems
164
+ load_artifacts
165
+ load_tasks
166
+ load_requires
167
+ load_buildfile
168
+ load_imports
169
+ task('buildr:initialize').invoke
170
+ top_level
171
+ end
172
+ title, message = 'Your build has completed', "#{Dir.pwd}\nbuildr #{@top_level_tasks.join(' ')}"
173
+ @on_completion.each { |block| block.call(title, message) rescue nil }
174
+ end
175
+
176
+ # Yields to block on successful completion. Primarily used for notifications.
177
+ def on_completion(&block)
178
+ @on_completion << block
179
+ end
180
+
181
+ # Yields to block on failure with exception. Primarily used for notifications.
182
+ def on_failure(&block)
183
+ @on_failure << block
184
+ end
185
+
186
+ # Not for external consumption.
187
+ def switch_to_namespace(names) #:nodoc:
188
+ current, @scope = @scope, names
189
+ begin
190
+ yield
191
+ ensure
192
+ @scope = current
193
+ end
149
194
  end
150
195
 
151
196
  # :call-seq:
152
- # build_files => files
197
+ # deprecated(message)
198
+ #
199
+ # Use with deprecated methods and classes. This method automatically adds the file name and line number,
200
+ # and the text 'Deprecated' before the message, and eliminated duplicate warnings. It only warns when
201
+ # running in verbose mode.
153
202
  #
154
- # Returns a list of build files. These are files used by the build,
155
- def build_files
156
- [buildfile].compact + Array(@build_files)
203
+ # For example:
204
+ # deprecated 'Please use new_foo instead of foo.'
205
+ def deprecated(message) #:nodoc:
206
+ return unless verbose
207
+ "#{caller[1]}: Deprecated: #{message}".tap do |message|
208
+ @deprecated ||= {}
209
+ unless @deprecated[message]
210
+ @deprecated[message] = true
211
+ warn message
212
+ end
213
+ end
157
214
  end
158
215
 
216
+ private
217
+
159
218
  # Returns Gem::Specification for every listed and installed Gem, Gem::Dependency
160
219
  # for listed and uninstalled Gem, which is the installed before loading the buildfile.
161
220
  def listed_gems #:nodoc:
@@ -167,27 +226,6 @@ module Buildr
167
226
  Gem::SourceIndex.from_installed_gems.search(dep).last || dep
168
227
  end
169
228
  end
170
- private :listed_gems
171
-
172
- def run
173
- times = Benchmark.measure do
174
- standard_exception_handling do
175
- find_buildfile
176
- load_gems
177
- load_artifacts
178
- load_tasks
179
- load_buildfile
180
- top_level
181
- end
182
- end
183
- if verbose
184
- real = []
185
- real << ("%ih" % (times.real / 3600)) if times.real >= 3600
186
- real << ("%im" % ((times.real / 60) % 60)) if times.real >= 60
187
- real << ("%.3fs" % (times.real % 60))
188
- puts "Completed in #{real.join}"
189
- end
190
- end
191
229
 
192
230
  # Load artifact specs from the build.yaml file, making them available
193
231
  # by name ( ruby symbols ).
@@ -203,36 +241,27 @@ module Buildr
203
241
  def load_gems #:nodoc:
204
242
  missing_deps, installed = listed_gems.partition { |gem| gem.is_a?(Gem::Dependency) }
205
243
  unless missing_deps.empty?
206
- remote = missing_deps.map { |dep| Gem::SourceInfoCache.search(dep).last || dep }
207
- not_found_deps, install = remote.partition { |gem| gem.is_a?(Gem::Dependency) }
208
- fail Gem::LoadError, "Build requires the gems #{not_found_deps.join(', ')}, which cannot be found in local or remote repository." unless not_found_deps.empty?
209
- uses = "This build requires the gems #{install.map(&:full_name).join(', ')}:"
210
- fail Gem::LoadError, "#{uses} to install, run Buildr interactively." unless $stdout.isatty
211
- unless agree("#{uses} do you want me to install them? [Y/n]", true)
212
- fail Gem::LoadError, 'Cannot build without these gems.'
213
- end
214
- install.each do |spec|
215
- say "Installing #{spec.full_name} ... " if verbose
216
- Util.ruby 'install', spec.name, '-v', spec.version.to_s, :command => 'gem', :sudo => true, :verbose => false
217
- Gem.source_index.load_gems_in Gem::SourceIndex.installed_spec_directories
218
- end
219
- installed += install
244
+ newly_installed = Util::Gems.install(*missing_deps)
245
+ installed += newly_installed
220
246
  end
221
-
222
247
  installed.each do |spec|
223
248
  if gem(spec.name, spec.version.to_s)
224
- # FileList[spec.require_paths.map { |path| File.expand_path("#{path}/*.rb", spec.full_gem_path) }].
225
- # map { |path| File.basename(path) }.each { |file| require file }
226
- # FileList[File.expand_path('tasks/*.rake', spec.full_gem_path)].each do |file|
227
- # Buildr.application.add_import file
228
- # end
249
+ # TODO: is this intended to load rake tasks from the installed gems?
250
+ # We should use a convention like .. if the gem has a _buildr.rb file, load it.
251
+
252
+ #FileList[spec.require_paths.map { |path| File.expand_path("#{path}/*.rb", spec.full_gem_path) }].
253
+ # map { |path| File.basename(path) }.each { |file| require file }
254
+ #FileList[File.expand_path('tasks/*.rake', spec.full_gem_path)].each do |file|
255
+ # Buildr.application.add_import file
256
+ #end
229
257
  end
230
258
  end
231
259
  @gems = installed
232
260
  end
233
261
 
234
- def find_buildfile
235
- here = Dir.pwd
262
+ def find_buildfile #:nodoc:
263
+ here = original_dir
264
+ Dir.chdir(here) unless Dir.pwd == here
236
265
  while ! have_rakefile
237
266
  Dir.chdir('..')
238
267
  if Dir.pwd == here || options.nosearch
@@ -248,30 +277,33 @@ module Buildr
248
277
  end
249
278
  end
250
279
 
251
- def load_buildfile
252
- @requires.each { |name| require name }
253
- puts "(in #{Dir.pwd}, #{environment})"
280
+ def load_buildfile #:nodoc:
281
+ info "(in #{Dir.pwd}, #{environment})"
254
282
  load File.expand_path(@rakefile) if @rakefile != ''
255
- load_imports
283
+ buildfile.enhance @requires.select { |f| File.file?(f) }.map{ |f| File.expand_path(f) }
284
+ end
285
+
286
+ def load_requires #:nodoc:
287
+ @requires.each { |name| require name }
256
288
  end
257
289
 
258
- # Loads buildr.rake files from users home directory and project directory.
290
+ # Loads buildr.rb files from users home directory and project directory.
259
291
  # Loads custom tasks from .rake files in tasks directory.
260
292
  def load_tasks #:nodoc:
261
- @build_files = [ File.expand_path('buildr.rb', ENV['HOME']), 'buildr.rb' ].select { |file| File.exist?(file) }
262
- @build_files += [ File.expand_path('buildr.rake', ENV['HOME']), File.expand_path('buildr.rake') ].
293
+ files = [ File.expand_path('buildr.rb', ENV['HOME']), 'buildr.rb' ].select { |file| File.exist?(file) }
294
+ files += [ File.expand_path('buildr.rake', ENV['HOME']), File.expand_path('buildr.rake') ].
263
295
  select { |file| File.exist?(file) }.each { |file| warn "Please use '#{file.ext('rb')}' instead of '#{file}'" }
264
296
  #Load local tasks that can be used in the Buildfile.
265
- @build_files += Dir["#{Dir.pwd}/tasks/*.rake"]
266
- @build_files.each do |file|
297
+ files += Dir[File.expand_path('tasks/*.rake')]
298
+ files.each do |file|
267
299
  unless $LOADED_FEATURES.include?(file)
268
300
  load file
269
301
  $LOADED_FEATURES << file
270
302
  end
271
303
  end
304
+ buildfile.enhance files
272
305
  true
273
306
  end
274
- private :load_tasks
275
307
 
276
308
  def display_prerequisites
277
309
  invoke_task('buildr:initialize')
@@ -282,37 +314,44 @@ module Buildr
282
314
  end
283
315
  end
284
316
  end
285
-
286
- # :call-seq:
287
- # deprecated(message)
288
- #
289
- # Use with deprecated methods and classes. This method automatically adds the file name and line number,
290
- # and the text 'Deprecated' before the message, and eliminated duplicate warnings. It only warns when
291
- # running in verbose mode.
292
- #
293
- # For example:
294
- # deprecated 'Please use new_foo instead of foo.'
295
- def deprecated(message) #:nodoc:
296
- return unless verbose
297
- "#{caller[1]}: Deprecated: #{message}".tap do |message|
298
- @deprecated ||= {}
299
- unless @deprecated[message]
300
- @deprecated[message] = true
301
- warn message
302
- end
303
- end
304
- end
305
-
306
- # Not for external consumption.
307
- def switch_to_namespace(names) #:nodoc:
308
- current, @scope = @scope, names
317
+
318
+ # Provide standard execption handling for the given block.
319
+ def standard_exception_handling
309
320
  begin
310
321
  yield
311
- ensure
312
- @scope = current
322
+ rescue SystemExit => ex
323
+ # Exit silently with current status
324
+ exit(ex.status)
325
+ rescue SystemExit, GetoptLong::InvalidOption => ex
326
+ # Exit silently
327
+ exit(1)
328
+ rescue Exception => ex
329
+ title, message = 'Your build failed with an error', "#{Dir.pwd}:\n#{ex.message}"
330
+ @on_failure.each { |block| block.call(title, message, ex) rescue nil }
331
+ # Exit with error message
332
+ $stderr.puts "buildr aborted!"
333
+ $stderr.puts $terminal.color(ex.message, :red)
334
+ if options.trace
335
+ $stderr.puts ex.backtrace.join("\n")
336
+ else
337
+ $stderr.puts ex.backtrace.select { |str| str =~ /#{buildfile}/ }.map { |line| $terminal.color(line, :red) }.join("\n")
338
+ $stderr.puts "(See full trace by running task with --trace)"
339
+ end
340
+ exit(1)
313
341
  end
314
342
  end
315
-
343
+
344
+ end
345
+
346
+
347
+ # This task stands for the buildfile and all its associated helper files (e.g., buildr.rb, build.yaml).
348
+ # By using this task as a prerequisite for other tasks, you can ensure these tasks will be needed
349
+ # whenever the buildfile changes.
350
+ class BuildfileTask < Rake::FileTask
351
+
352
+ def timestamp
353
+ ([name] + prerequisites).map { |f| File.stat(f).mtime }.max rescue Time.now
354
+ end
316
355
  end
317
356
 
318
357
 
@@ -348,22 +387,72 @@ module Buildr
348
387
  end
349
388
 
350
389
 
351
- # Add a touch of colors (red) to warnings.
390
+ # Add a touch of color when available and running in terminal.
352
391
  if $stdout.isatty
353
392
  begin
354
393
  require 'Win32/Console/ANSI' if Config::CONFIG['host_os'] =~ /mswin/
355
394
  HighLine.use_color = true
356
395
  rescue LoadError
357
396
  end
397
+ else
398
+ HighLine.use_color = false
358
399
  end
359
400
 
360
- if HighLine.use_color?
361
- module Kernel #:nodoc:
362
- alias :warn_without_color :warn
363
- def warn(message)
364
- warn_without_color $terminal.color(message.to_s, :red)
401
+
402
+ # Let's see if we can use Growl. We do this at the very end, loading Ruby Cocoa
403
+ # could slow the build down, so later is better. We only do this when running
404
+ # from the console in verbose mode.
405
+ if $stdout.isatty && verbose && RUBY_PLATFORM =~ /darwin/
406
+ begin
407
+ require 'osx/cocoa'
408
+ icon = OSX::NSApplication.sharedApplication.applicationIconImage
409
+ icon = OSX::NSImage.alloc.initWithContentsOfFile(File.join(File.dirname(__FILE__), '../resources/buildr.icns'))
410
+
411
+ # Register with Growl, that way you can turn notifications on/off from system preferences.
412
+ OSX::NSDistributedNotificationCenter.defaultCenter.
413
+ postNotificationName_object_userInfo_deliverImmediately(:GrowlApplicationRegistrationNotification, nil,
414
+ { :ApplicationName=>'Buildr', :AllNotifications=>['Completed', 'Failed'],
415
+ :ApplicationIcon=>icon.TIFFRepresentation }, true)
416
+
417
+ notify = lambda do |type, title, message|
418
+ OSX::NSDistributedNotificationCenter.defaultCenter.
419
+ postNotificationName_object_userInfo_deliverImmediately(:GrowlNotification, nil,
420
+ { :ApplicationName=>'Buildr', :NotificationName=>type,
421
+ :NotificationTitle=>title, :NotificationDescription=>message }, true)
365
422
  end
423
+ Buildr.application.on_completion { |title, message| notify['Completed', title, message] }
424
+ Buildr.application.on_failure { |title, message, ex| notify['Failed', title, message] }
425
+ rescue Exception # No growl
366
426
  end
427
+ elsif $stdout.isatty && verbose
428
+ notify = lambda { |type, title, message| $stdout.puts "[#{type}] #{title}: #{message}" }
429
+ Buildr.application.on_completion { |title, message| notify['Completed', title, message] }
430
+ Buildr.application.on_failure { |title, message, ex| notify['Failed', title, message] }
431
+ end
432
+
433
+
434
+ alias :warn_without_color :warn
435
+
436
+ # Show warning message.
437
+ def warn(message)
438
+ warn_without_color $terminal.color(message.to_s, :blue) if verbose
439
+ end
440
+
441
+ # Show error message. Use this when you need to show an error message and not throwing
442
+ # an exception that will stop the build.
443
+ def error(message)
444
+ puts $terminal.color(message.to_s, :red)
445
+ end
446
+
447
+ # Show optional information. The message is printed only when running in verbose
448
+ # mode (the default).
449
+ def info(message)
450
+ puts message if verbose
451
+ end
452
+
453
+ # Show message. The message is printed out only when running in trace mode.
454
+ def trace(message)
455
+ puts message if Buildr.application.options.trace
367
456
  end
368
457
 
369
458
 
@@ -382,7 +471,12 @@ module Rake #:nodoc
382
471
  end
383
472
  return if @already_invoked
384
473
  @already_invoked = true
385
- invoke_prerequisites(task_args, new_chain)
474
+ begin
475
+ invoke_prerequisites(task_args, new_chain)
476
+ rescue
477
+ trace "Exception while invoking prerequisites of task #{self.inspect}"
478
+ raise
479
+ end
386
480
  begin
387
481
  old_chain, Thread.current[:rake_chain] = Thread.current[:rake_chain], new_chain
388
482
  execute(task_args) if needed?