buildr 1.3.3-java → 1.3.4-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 (144) hide show
  1. data/CHANGELOG +76 -0
  2. data/NOTICE +1 -1
  3. data/README.rdoc +9 -21
  4. data/Rakefile +17 -34
  5. data/_buildr +3 -12
  6. data/{doc/print.toc.yaml → _jbuildr} +14 -14
  7. data/addon/buildr/cobertura.rb +5 -219
  8. data/addon/buildr/drb.rb +281 -0
  9. data/addon/buildr/emma.rb +5 -221
  10. data/addon/buildr/nailgun.rb +93 -689
  11. data/bin/buildr +0 -9
  12. data/buildr.buildfile +4 -4
  13. data/buildr.gemspec +27 -21
  14. data/doc/_layouts/default.html +82 -0
  15. data/doc/_layouts/preface.html +22 -0
  16. data/doc/{pages/artifacts.textile → artifacts.textile} +82 -42
  17. data/doc/{pages/building.textile → building.textile} +89 -47
  18. data/doc/{pages/contributing.textile → contributing.textile} +53 -45
  19. data/doc/css/default.css +6 -5
  20. data/doc/css/print.css +17 -24
  21. data/doc/css/syntax.css +7 -36
  22. data/doc/download.textile +68 -0
  23. data/doc/{pages/extending.textile → extending.textile} +45 -24
  24. data/doc/{pages/getting_started.textile → getting_started.textile} +158 -88
  25. data/doc/images/asf-logo.gif +0 -0
  26. data/doc/images/note.png +0 -0
  27. data/doc/index.textile +47 -0
  28. data/doc/{pages/languages.textile → languages.textile} +108 -54
  29. data/doc/mailing_lists.textile +25 -0
  30. data/doc/{pages/more_stuff.textile → more_stuff.textile} +152 -73
  31. data/doc/{pages/packaging.textile → packaging.textile} +181 -96
  32. data/doc/preface.textile +28 -0
  33. data/doc/{pages/projects.textile → projects.textile} +55 -40
  34. data/doc/scripts/buildr-git.rb +364 -264
  35. data/doc/scripts/gitflow.rb +296 -0
  36. data/doc/scripts/install-jruby.sh +2 -2
  37. data/doc/scripts/install-linux.sh +6 -6
  38. data/doc/scripts/install-osx.sh +2 -2
  39. data/doc/{pages/settings_profiles.textile → settings_profiles.textile} +83 -45
  40. data/doc/{pages/testing.textile → testing.textile} +77 -41
  41. data/lib/buildr.rb +5 -5
  42. data/lib/buildr/core.rb +2 -0
  43. data/lib/buildr/core/application.rb +321 -151
  44. data/lib/buildr/core/build.rb +298 -167
  45. data/lib/buildr/core/checks.rb +4 -132
  46. data/lib/buildr/core/common.rb +1 -5
  47. data/lib/buildr/core/compile.rb +3 -9
  48. data/lib/buildr/core/environment.rb +12 -3
  49. data/lib/buildr/core/filter.rb +20 -18
  50. data/lib/buildr/core/generate.rb +36 -36
  51. data/lib/buildr/core/help.rb +2 -1
  52. data/lib/buildr/core/osx.rb +46 -0
  53. data/lib/buildr/core/progressbar.rb +1 -1
  54. data/lib/buildr/core/project.rb +7 -34
  55. data/lib/buildr/core/test.rb +12 -6
  56. data/lib/buildr/core/transports.rb +13 -11
  57. data/lib/buildr/core/util.rb +14 -23
  58. data/lib/buildr/groovy/bdd.rb +3 -2
  59. data/lib/buildr/groovy/compiler.rb +1 -1
  60. data/lib/buildr/ide/eclipse.rb +31 -21
  61. data/lib/buildr/ide/idea.rb +3 -2
  62. data/lib/buildr/ide/idea7x.rb +6 -4
  63. data/lib/buildr/java/ant.rb +3 -1
  64. data/lib/buildr/java/bdd.rb +9 -7
  65. data/lib/buildr/java/cobertura.rb +243 -0
  66. data/lib/buildr/java/compiler.rb +5 -4
  67. data/lib/buildr/java/emma.rb +244 -0
  68. data/lib/buildr/java/packaging.rb +11 -8
  69. data/lib/buildr/java/pom.rb +0 -4
  70. data/lib/buildr/java/rjb.rb +1 -1
  71. data/lib/buildr/java/test_result.rb +5 -7
  72. data/lib/buildr/java/tests.rb +17 -11
  73. data/lib/buildr/packaging.rb +5 -2
  74. data/lib/buildr/packaging/archive.rb +488 -0
  75. data/lib/buildr/packaging/artifact.rb +48 -29
  76. data/lib/buildr/packaging/artifact_namespace.rb +6 -6
  77. data/lib/buildr/packaging/gems.rb +4 -4
  78. data/lib/buildr/packaging/package.rb +3 -2
  79. data/lib/buildr/packaging/tar.rb +85 -3
  80. data/lib/buildr/packaging/version_requirement.rb +172 -0
  81. data/lib/buildr/packaging/zip.rb +24 -682
  82. data/lib/buildr/packaging/ziptask.rb +313 -0
  83. data/lib/buildr/scala.rb +5 -0
  84. data/lib/buildr/scala/bdd.rb +100 -0
  85. data/lib/buildr/scala/compiler.rb +45 -4
  86. data/lib/buildr/scala/tests.rb +12 -59
  87. data/rakelib/checks.rake +57 -0
  88. data/rakelib/doc.rake +58 -68
  89. data/rakelib/jekylltask.rb +110 -0
  90. data/rakelib/package.rake +35 -37
  91. data/rakelib/release.rake +119 -35
  92. data/rakelib/rspec.rake +29 -39
  93. data/rakelib/setup.rake +21 -59
  94. data/rakelib/stage.rake +184 -26
  95. data/spec/addon/drb_spec.rb +328 -0
  96. data/spec/core/application_spec.rb +32 -25
  97. data/spec/core/build_spec.rb +336 -126
  98. data/spec/core/checks_spec.rb +292 -310
  99. data/spec/core/common_spec.rb +8 -2
  100. data/spec/core/compile_spec.rb +17 -1
  101. data/spec/core/generate_spec.rb +3 -3
  102. data/spec/core/project_spec.rb +18 -10
  103. data/spec/core/test_spec.rb +8 -1
  104. data/spec/core/transport_spec.rb +40 -3
  105. data/spec/core/util_spec.rb +67 -0
  106. data/spec/ide/eclipse_spec.rb +96 -28
  107. data/spec/ide/idea7x_spec.rb +84 -0
  108. data/spec/java/ant.rb +5 -0
  109. data/spec/java/bdd_spec.rb +12 -3
  110. data/spec/{addon → java}/cobertura_spec.rb +6 -6
  111. data/spec/{addon → java}/emma_spec.rb +5 -6
  112. data/spec/java/java_spec.rb +12 -2
  113. data/spec/java/packaging_spec.rb +31 -2
  114. data/spec/{addon → java}/test_coverage_spec.rb +3 -3
  115. data/spec/java/tests_spec.rb +5 -0
  116. data/spec/packaging/archive_spec.rb +11 -1
  117. data/spec/{core → packaging}/artifact_namespace_spec.rb +10 -2
  118. data/spec/packaging/artifact_spec.rb +44 -3
  119. data/spec/packaging/packaging_spec.rb +1 -1
  120. data/spec/sandbox.rb +17 -14
  121. data/spec/scala/bdd_spec.rb +150 -0
  122. data/spec/scala/compiler_spec.rb +27 -0
  123. data/spec/scala/scala.rb +38 -0
  124. data/spec/scala/tests_spec.rb +78 -33
  125. data/spec/spec_helpers.rb +29 -5
  126. data/spec/version_requirement_spec.rb +6 -0
  127. metadata +176 -172
  128. data/DISCLAIMER +0 -7
  129. data/doc/images/apache-incubator-logo.png +0 -0
  130. data/doc/pages/download.textile +0 -51
  131. data/doc/pages/index.textile +0 -42
  132. data/doc/pages/mailing_lists.textile +0 -17
  133. data/doc/pages/recipes.textile +0 -103
  134. data/doc/pages/troubleshooting.textile +0 -103
  135. data/doc/pages/whats_new.textile +0 -323
  136. data/doc/print.haml +0 -51
  137. data/doc/site.haml +0 -56
  138. data/doc/site.toc.yaml +0 -47
  139. data/etc/git-svn-authors +0 -16
  140. data/lib/buildr/core/application_cli.rb +0 -139
  141. data/rakelib/apache.rake +0 -191
  142. data/rakelib/changelog.rake +0 -57
  143. data/rakelib/rubyforge.rake +0 -53
  144. data/rakelib/scm.rake +0 -49
@@ -56,10 +56,8 @@ module Buildr
56
56
  project.recursive_task 'build'
57
57
  project.recursive_task 'clean'
58
58
  project.clean do
59
- verbose(true) do
60
- rm_rf project.path_to(:target)
61
- rm_rf project.path_to(:reports)
62
- end
59
+ rm_rf project.path_to(:target)
60
+ rm_rf project.path_to(:reports)
63
61
  end
64
62
  end
65
63
 
@@ -109,198 +107,331 @@ module Buildr
109
107
  end
110
108
 
111
109
 
112
- class Svn
110
+ module Git #:nodoc:
113
111
 
114
- class << self
115
- def commit(file, message)
116
- svn 'commit', '-m', message, file
117
- end
118
-
119
- def copy(dir, url, message)
120
- svn 'copy', dir, url, '-m', message
121
- end
122
-
123
- # Return the current SVN URL
124
- def repo_url
125
- svn('info').scan(/URL: (.*)/)[0][0]
126
- end
127
-
128
- def remove(url, message)
129
- svn 'remove', url, '-m', message
130
- end
131
-
132
- # Status check reveals modified files, but also SVN externals which we can safely ignore.
133
- def uncommitted_files
134
- svn('status', '--ignore-externals').reject { |line| line =~ /^X\s/ }
135
- end
136
-
137
- # :call-seq:
138
- # svn(*args)
139
- #
140
- # Executes SVN command and returns the output.
141
- def svn(*args)
142
- cmd = 'svn ' + args.map { |arg| arg[' '] ? %Q{"#{arg}"} : arg }.join(' ')
143
- trace cmd
144
- `#{cmd}`.tap { fail 'SVN command failed' unless $?.exitstatus == 0 }
145
- end
112
+ module_function
113
+
114
+ # :call-seq:
115
+ # git(*args)
116
+ #
117
+ # Executes a Git command and returns the output. Throws exception if the exit status
118
+ # is not zero. For example:
119
+ # git 'commit'
120
+ # git 'remote', 'show', 'origin'
121
+ def git(*args)
122
+ cmd = "git #{args.shift} #{args.map { |arg| arg.inspect }.join(' ')}"
123
+ output = `#{cmd}`
124
+ fail "GIT command \"#{cmd}\" failed with status #{$?.exitstatus}\n#{output}" unless $?.exitstatus == 0
125
+ return output
126
+ end
127
+
128
+ # Returns list of uncommited/untracked files as reported by git status.
129
+ def uncommitted_files
130
+ `git status`.scan(/^#\s{7}(\S.*)$/).map { |match| match.first.split.last }
131
+ end
132
+
133
+ # Commit the given file with a message.
134
+ # The file has to be known to Git meaning that it has either to have been already committed in the past
135
+ # or freshly added to the index. Otherwise it will fail.
136
+ def commit(file, message)
137
+ git 'commit', '-m', message, file
138
+ end
139
+
140
+ # Update the remote refs using local refs
141
+ #
142
+ # By default, the "remote" destination of the push is the the remote repo linked to the current branch.
143
+ # The default remote branch is the current local branch.
144
+ def push(remote_repo = remote, remote_branch = current_branch)
145
+ git 'push', remote, current_branch
146
146
  end
147
+
148
+ # Return the name of the remote repository whose branch the current local branch tracks,
149
+ # or nil if none.
150
+ def remote(branch = current_branch)
151
+ remote = git('config', '--get', "branch.#{branch}.remote").strip
152
+ remote if git('remote').include?(remote)
153
+ rescue
154
+ nil
155
+ end
156
+
157
+ # Return the name of the current branch
158
+ def current_branch
159
+ git('branch')[/^\* (.*)$/, 1]
160
+ end
161
+
162
+ end
163
+
164
+
165
+ module Svn #:nodoc:
166
+
167
+ module_function
168
+
169
+ # :call-seq:
170
+ # svn(*args)
171
+ #
172
+ # Executes a SVN command and returns the output. Throws exception if the exit status
173
+ # is not zero. For example:
174
+ # svn 'commit'
175
+ def svn(*args)
176
+ output = `svn #{args.shift} #{args.map { |arg| arg.inspect }.join(' ')}`
177
+ fail "SVN command failed with status #{$?.exitstatus}" unless $?.exitstatus == 0
178
+ return output
179
+ end
180
+
181
+ def tag(tag_name)
182
+ url = tag_url repo_url, tag_name
183
+ remove url, 'Removing old copy' rescue nil
184
+ copy Dir.pwd, url, "Release #{tag_name}"
185
+ end
186
+
187
+ # Status check reveals modified files, but also SVN externals which we can safely ignore.
188
+ def uncommitted_files
189
+ svn('status', '--ignore-externals').split("\n").reject { |line| line =~ /^X\s/ }
190
+ end
191
+
192
+ def commit(file, message)
193
+ svn 'commit', '-m', message, file
194
+ end
195
+
196
+ # :call-seq:
197
+ # tag_url(svn_url, version) => tag_url
198
+ #
199
+ # Returns the SVN url for the tag.
200
+ # Can tag from the trunk or from branches.
201
+ # Can handle the two standard repository layouts.
202
+ # - http://my.repo/foo/trunk => http://my.repo/foo/tags/1.0.0
203
+ # - http://my.repo/trunk/foo => http://my.repo/tags/foo/1.0.0
204
+ def tag_url(svn_url, tag)
205
+ trunk_or_branches = Regexp.union(%r{^(.*)/trunk(.*)$}, %r{^(.*)/branches(.*)/([^/]*)$})
206
+ match = trunk_or_branches.match(svn_url)
207
+ prefix = match[1] || match[3]
208
+ suffix = match[2] || match[4]
209
+ prefix + '/tags' + suffix + '/' + tag
210
+ end
211
+
212
+ # Return the current SVN URL
213
+ def repo_url
214
+ svn('info', '--xml')[/<url>(.*?)<\/url>/, 1].strip
215
+ end
216
+
217
+ def copy(dir, url, message)
218
+ svn 'copy', dir, url, '-m', message
219
+ end
220
+
221
+ def remove(url, message)
222
+ svn 'remove', url, '-m', message
223
+ end
224
+
147
225
  end
148
226
 
149
-
150
- class Release
227
+
228
+ class Release #:nodoc:
151
229
 
152
230
  THIS_VERSION_PATTERN = /(THIS_VERSION|VERSION_NUMBER)\s*=\s*(["'])(.*)\2/
153
231
 
154
232
  class << self
155
233
 
156
- # Use this to specify a different tag name for tagging the release in source control.
157
- # You can set the tag name or a proc that will be called with the version number,
158
- # for example:
159
- # Release.tag_name = lambda { |ver| "foo-#{ver}" }
160
- attr_accessor :tag_name
161
-
162
234
  # :call-seq:
163
- # make()
235
+ # add(MyReleaseClass)
164
236
  #
165
- # Make a release.
166
- def make
167
- check
168
- with_release_candidate_version do |release_candidate_buildfile|
169
- options = ['--buildfile', release_candidate_buildfile, 'DEBUG=no']
170
- options << '--environment' << Buildr.environment unless Buildr.environment.to_s.empty?
171
- buildr %w{clean upload}, options
172
- end
173
- tag_release
174
- commit_new_snapshot
237
+ # Add a Release implementation to the list of available Release classes.
238
+ def add(release)
239
+ @list ||= []
240
+ @list |= [release]
175
241
  end
242
+ alias :<< :add
176
243
 
177
- # :call-seq:
178
- # extract_version() => this_version
179
- #
180
- # Extract the current version number from the buildfile.
181
- # Raise an error if not found.
182
- def extract_version
183
- buildfile = File.read(Buildr.application.buildfile.to_s)
184
- buildfile.scan(THIS_VERSION_PATTERN)[0][2]
185
- rescue
186
- fail 'Looking for THIS_VERSION = "..." in your Buildfile, none found'
187
- end
188
-
189
- # :call-seq:
190
- # tag_url(svn_url, version) => tag_url
191
- #
192
- # Returns the SVN url for the tag.
193
- # Can tag from the trunk or from branches.
194
- # Can handle the two standard repository layouts.
195
- # - http://my.repo/foo/trunk => http://my.repo/foo/tags/1.0.0
196
- # - http://my.repo/trunk/foo => http://my.repo/tags/foo/1.0.0
197
- def tag_url(svn_url, version)
198
- trunk_or_branches = Regexp.union(%r{^(.*)/trunk(.*)$}, %r{^(.*)/branches(.*)/([^/]*)$})
199
- match = trunk_or_branches.match(svn_url)
200
- prefix = match[1] || match[3]
201
- suffix = match[2] || match[4]
202
- tag = tag_name || version
203
- tag = tag.call(version) if Proc === tag
204
- prefix + '/tags' + suffix + '/' + tag
205
- end
206
-
207
- # :call-seq:
208
- # check()
209
- #
210
- # Check that we don't have any local changes in the working copy. Fails if it finds anything
211
- # in the working copy that is not checked into source control.
212
- def check
213
- fail "SVN URL must contain 'trunk' or 'branches/...'" unless Svn.repo_url =~ /(trunk)|(branches.*)$/
214
- fail "Uncommitted SVN files violate the First Principle Of Release!\n#{Svn.uncommitted_files}" unless Svn.uncommitted_files.empty?
244
+ # The list of supported Release implementations
245
+ def list
246
+ @list ||= []
215
247
  end
216
248
 
217
- protected
249
+ end
250
+
251
+ # Use this to specify a different tag name for tagging the release in source control.
252
+ # You can set the tag name or a proc that will be called with the version number,
253
+ # for example:
254
+ # Release.tag_name = lambda { |ver| "foo-#{ver}" }
255
+ attr_accessor :tag_name
256
+
257
+ # Use this to specify a different commit message to commit the buildfile with the next version in source control.
258
+ # You can set the commit message or a proc that will be called with the next version number,
259
+ # for example:
260
+ # Release.commit_message = lambda { |ver| "Changed version number to #{ver}" }
261
+ attr_accessor :commit_message
218
262
 
219
- # :call-seq:
220
- # buildr(tasks, options)
221
- #
222
- # Calls another instance of buildr.
223
- def buildr(tasks, options)
224
- sh "#{command} _#{Buildr::VERSION}_ #{tasks.join(' ')} #{options.join(' ')}"
263
+ # :call-seq:
264
+ # make()
265
+ #
266
+ # Make a release.
267
+ def make
268
+ check
269
+ with_release_candidate_version do |release_candidate_buildfile|
270
+ args = '-S', 'buildr', "_#{Buildr::VERSION}_", '--buildfile', release_candidate_buildfile
271
+ args << '--environment' << Buildr.environment unless Buildr.environment.to_s.empty?
272
+ args << 'clean' << 'upload' << 'DEBUG=no'
273
+ ruby *args
225
274
  end
226
-
227
- def command #:nodoc:
228
- Config::CONFIG['arch'] =~ /dos|win32/i ? $PROGRAM_NAME.ext('cmd') : $PROGRAM_NAME
275
+ tag_release resolve_tag
276
+ update_version_to_next
277
+ end
278
+
279
+ # :call-seq:
280
+ # extract_version() => this_versin
281
+ #
282
+ # Extract the current version number from the buildfile.
283
+ # Raise an error if not found.
284
+ def extract_version
285
+ buildfile = File.read(Buildr.application.buildfile.to_s)
286
+ buildfile.scan(THIS_VERSION_PATTERN)[0][2]
287
+ rescue
288
+ fail 'Looking for THIS_VERSION = "..." in your Buildfile, none found'
289
+ end
290
+
291
+ protected
292
+
293
+ # :call-seq:
294
+ # with_release_candidate_version() { |filename| ... }
295
+ #
296
+ # Yields to block with release candidate buildfile, before committing to use it.
297
+ #
298
+ # We need a Buildfile with upgraded version numbers to run the build, but we don't want the
299
+ # Buildfile modified unless the build succeeds. So this method updates the version number in
300
+ # a separate (Buildfile.next) file, yields to the block with that filename, and if successful
301
+ # copies the new file over the existing one.
302
+ #
303
+ # The release version is the current version without '-SNAPSHOT'. So:
304
+ # THIS_VERSION = 1.1.0-SNAPSHOT
305
+ # becomes:
306
+ # THIS_VERSION = 1.1.0
307
+ # for the release buildfile.
308
+ def with_release_candidate_version
309
+ release_candidate_buildfile = Buildr.application.buildfile.to_s + '.next'
310
+ release_candidate_buildfile_contents = change_version { |version| version[-1] = version[-1].to_i }
311
+ File.open(release_candidate_buildfile, 'w') { |file| file.write release_candidate_buildfile_contents }
312
+ begin
313
+ yield release_candidate_buildfile
314
+ mv release_candidate_buildfile, Buildr.application.buildfile.to_s
315
+ ensure
316
+ rm release_candidate_buildfile rescue nil
229
317
  end
318
+ end
230
319
 
231
- # :call-seq:
232
- # with_release_candidate_version() { |filename| ... }
233
- #
234
- # Yields to block with release candidate buildfile, before committing to use it.
235
- #
236
- # We need a Buildfile with upgraded version numbers to run the build, but we don't want the
237
- # Buildfile modified unless the build succeeds. So this method updates the version number in
238
- # a separate (Buildfile.next) file, yields to the block with that filename, and if successful
239
- # copies the new file over the existing one.
240
- #
241
- # The release version is the current version without '-SNAPSHOT'. So:
242
- # THIS_VERSION = 1.1.0-SNAPSHOT
243
- # becomes:
244
- # THIS_VERSION = 1.1.0
245
- # for the release buildfile.
246
- def with_release_candidate_version
247
- release_candidate_buildfile = Buildr.application.buildfile.to_s + '.next'
248
- release_candidate_buildfile_contents = change_version { |version| version[-1] = version[-1].to_i }
249
- File.open(release_candidate_buildfile, 'w') { |file| file.write release_candidate_buildfile_contents }
250
- begin
251
- yield release_candidate_buildfile
252
- mv release_candidate_buildfile, Buildr.application.buildfile.to_s
253
- ensure
254
- rm release_candidate_buildfile rescue nil
255
- end
256
- end
320
+ # :call-seq:
321
+ # change_version() { |this_version| ... } => buildfile
322
+ #
323
+ # Change version number in the current Buildfile, but without writing a new file (yet).
324
+ # Returns the contents of the Buildfile with the modified version number.
325
+ #
326
+ # This method yields to the block with the current (this) version number as an array and expects
327
+ # the block to update it.
328
+ def change_version
329
+ this_version = extract_version
330
+ new_version = this_version.split('.')
331
+ yield(new_version)
332
+ new_version = new_version.join('.')
333
+ buildfile = File.read(Buildr.application.buildfile.to_s)
334
+ buildfile.gsub(THIS_VERSION_PATTERN) { |ver| ver.sub(/(["']).*\1/, %Q{"#{new_version}"}) }
335
+ end
257
336
 
258
- # :call-seq:
259
- # change_version() { |this_version| ... } => buildfile
260
- #
261
- # Change version number in the current Buildfile, but without writing a new file (yet).
262
- # Returns the contents of the Buildfile with the modified version number.
263
- #
264
- # This method yields to the block with the current (this) version number as an array and expects
265
- # the block to update it.
266
- def change_version
267
- this_version = extract_version
268
- new_version = this_version.split('.')
269
- yield(new_version)
270
- new_version = new_version.join('.')
271
- buildfile = File.read(Buildr.application.buildfile.to_s)
272
- buildfile.gsub(THIS_VERSION_PATTERN) { |ver| ver.sub(/(["']).*\1/, %Q{"#{new_version}"}) }
273
- end
337
+ # Return the name of the tag to tag the release with.
338
+ def resolve_tag
339
+ version = extract_version
340
+ tag = tag_name || version
341
+ tag = tag.call(version) if Proc === tag
342
+ tag
343
+ end
274
344
 
275
- # :call-seq:
276
- # tag_release()
277
- #
278
- # Tags the current working copy with the release version number.
279
- def tag_release
280
- version = extract_version
281
- info "Tagging release #{version}"
282
- url = tag_url Svn.repo_url, version
283
- Svn.remove url, 'Removing old copy' rescue nil
284
- Svn.copy Dir.pwd, url, "Release #{version}"
285
- end
345
+ # Move the version to next and save the updated buildfile
346
+ def update_buildfile
347
+ buildfile = change_version { |version| version[-1] = (version[-1].to_i + 1).to_s + '-SNAPSHOT' }
348
+ File.open(Buildr.application.buildfile.to_s, 'w') { |file| file.write buildfile }
349
+ end
286
350
 
287
- # :call-seq:
288
- # commit_new_snapshot()
289
- #
290
- # Last, we commit what we currently have in the working copy with an upgraded version number.
291
- def commit_new_snapshot
292
- buildfile = change_version { |version| version[-1] = (version[-1].to_i + 1).to_s + '-SNAPSHOT' }
293
- File.open(Buildr.application.buildfile.to_s, 'w') { |file| file.write buildfile }
294
- Svn.commit Buildr.application.buildfile.to_s, "Changed version number to #{extract_version}"
295
- info "Current version is now #{extract_version}"
351
+ # Return the message to use to cimmit the buildfile with the next version
352
+ def message
353
+ version = extract_version
354
+ msg = commit_message || "Changed version number to #{version}"
355
+ msg = msg.call(version) if Proc === msg
356
+ msg
357
+ end
358
+
359
+ def update_version_to_next
360
+ update_buildfile
361
+ end
362
+ end
363
+
364
+
365
+ class GitRelease < Release
366
+ class << self
367
+ def applies_to?(directory = '.')
368
+ File.exist? File.join(directory, '.git/config')
296
369
  end
297
370
  end
371
+
372
+ # Fails if one of theses 2 conditions are not met:
373
+ # 1. the repository is clean: no content staged or unstaged
374
+ # 2. some remote repositories are defined but the current branch does not track any
375
+ def check
376
+ uncommitted = Git.uncommitted_files
377
+ fail "Uncommitted files violate the First Principle Of Release!\n#{uncommitted.join("\n")}" unless uncommitted.empty?
378
+ fail "You are releasing from a local branch that does not track a remote!" unless Git.remote
379
+ end
380
+
381
+ # Add a tag reference in .git/refs/tags and push it to the remote if any.
382
+ # If a tag with the same name already exists it will get deleted (in both local and remote repositories).
383
+ def tag_release(tag)
384
+ info "Committing buildfile with version number #{extract_version}"
385
+ Git.commit File.basename(Buildr.application.buildfile.to_s), message
386
+ Git.push if Git.remote
387
+ info "Tagging release #{tag}"
388
+ Git.git 'tag', '-d', tag rescue nil
389
+ Git.git 'push', Git.remote, ":refs/tags/#{tag}" rescue nil if Git.remote
390
+ Git.git 'tag', '-a', tag, '-m', "[buildr] Cutting release #{tag}"
391
+ Git.git 'push', Git.remote, 'tag', tag if Git.remote
392
+ end
393
+
394
+ def update_version_to_next
395
+ super
396
+ info "Current version is now #{extract_version}"
397
+ Git.commit File.basename(Buildr.application.buildfile.to_s), message
398
+ Git.push if Git.remote
399
+ end
298
400
  end
401
+
299
402
 
403
+ class SvnRelease < Release
404
+ class << self
405
+ def applies_to?(directory = '.')
406
+ File.exist? File.join(directory, '.svn')
407
+ end
408
+ end
409
+
410
+ def check
411
+ fail "Uncommitted files violate the First Principle Of Release!\n"+Svn.uncommitted_files.join("\n") unless Svn.uncommitted_files.empty?
412
+ fail "SVN URL must contain 'trunk' or 'branches/...'" unless Svn.repo_url =~ /(trunk)|(branches.*)$/
413
+ end
414
+
415
+ def tag_release(tag)
416
+ info "Tagging release #{tag}"
417
+ Svn.tag tag
418
+ end
419
+
420
+ def update_version_to_next
421
+ super
422
+ info "Current version is now #{extract_version}"
423
+ Svn.commit Buildr.application.buildfile.to_s, message
424
+ end
425
+ end
300
426
 
427
+ Release.add SvnRelease
428
+ Release.add GitRelease
429
+
301
430
  desc 'Make a release'
302
431
  task 'release' do |task|
303
- Release.make
432
+ klass = Release.list.detect { |impl| impl.applies_to? }
433
+ fail 'Unable to detect the Version Control System.' unless klass
434
+ klass.new.make
304
435
  end
305
436
 
306
437
  end