0
# Testing is everything.
0
+task('clobber') { rm 'failing' rescue nil }
0
Spec::Rake::SpecTask.new('spec') do |task|
0
task.spec_files = FileList['spec/**/*_spec.rb']
0
task.spec_opts << '--options' << 'spec/spec.opts' << '--format' << 'failing_examples:failing' << '--example' << 'failing'
0
- desc 'Run all specs and generate test/coverage reports in html directory'
0
- Spec::Rake::SpecTask.new('report') do |task|
0
+ Rake::Task['rake:clobber'].enhance { rm_rf 'reports' }
0
+ desc 'Run all specs and generate specification and test coverage reports in html directory'
0
+ Spec::Rake::SpecTask.new('full'=>'reports') do |task|
0
task.spec_files = FileList['spec/**/*_spec.rb']
0
- task.spec_opts << '--format' << 'html:
html/report.html' << '--backtrace'
0
+ task.spec_opts << '--format' << 'html:
reports/specs.html' << '--backtrace'
0
- task.rcov_dir = '
html/coverage'
0
+ task.rcov_dir = '
reports/coverage'
0
task.rcov_opts = ['--exclude', 'spec,bin']
0
desc 'Generate RDoc documentation'
0
rdoc = Rake::RDocTask.new(:rdoc) do |rdoc|
0
- rdoc.rdoc_dir = '
html/rdoc'
0
+ rdoc.rdoc_dir = '
rdoc'
0
rdoc.title = ruby_spec.name
0
rdoc.options = ruby_spec.rdoc_options + ['--promiscuous']
0
rdoc.rdoc_files.include('lib/**/*.rb')
0
:collection => Docter.collection('Buildr').using('doc/web.toc.yaml').
0
include('doc/pages', 'LICENSE', 'CHANGELOG'),
0
:template => Docter.template('doc/web.haml').
0
- include('doc/css', 'doc/images', 'doc/scripts', '
html/report.html', 'html/coverage', 'html/rdoc')
0
+ include('doc/css', 'doc/images', 'doc/scripts', '
reports/specs.html', 'reports/coverage', 'rdoc')
0
:collection => Docter.collection('Buildr').using('doc/print.toc.yaml').
0
desc 'Generate HTML documentation'
0
html = Docter::Rake.generate('html', web_docs[:collection], web_docs[:template])
0
+ html.enhance ['spec:full']
0
desc 'Run Docter server'
0
Docter::Rake.serve 'docter', web_docs[:collection], web_docs[:template], :port=>3000
0
task('docs').enhance [html]
0
-# Commit to SVN, upload and do the release cycle.
0
- task :clean? do |task|
0
- status = `svn status`.reject { |line| line =~ /\s(pkg|html)$/ }
0
- fail "Cannot release unless all local changes are in SVN:\n#{status}" unless status.empty?
0
- cur_url = `svn info`.scan(/URL: (.*)/)[0][0]
0
- new_url = cur_url.sub(/(trunk$)|(branches\/\w*)$/, "tags/#{ruby_spec.version.to_s}")
0
- system 'svn', 'copy', cur_url, new_url, '-m', "Release #{ruby_spec.version.to_s}"
0
+ require 'highline/import'
0
+ Kernel.def_delegators :$terminal, :color
0
- task :docs=>'rake:docs' do |task|
0
- sh %{rsync -r --del --progress html/* people.apache.org:/www/incubator.apache.org/#{ruby_spec.rubyforge_project.downcase}/}
0
+ # This task does all prerequisites checks before starting the release, for example,
0
+ # that we have Groovy and Scala to run all the test cases, or that we have Allison
0
+ # and PrinceXML to generate the full documentation.
0
+ # This task does all the preparation work before making a release and also checks
0
+ # that we generate all the right material, for example, that we compiled Java sources,
0
+ # created the PDF, have coverage report.
0
+ task 'prepare'=>['clobber', 'check']
0
+ # Does CHANGELOG reflects current release?
0
+ say 'Checking that CHANGELOG indicates most recent version and today\'s date ... '
0
+ expecting = "#{ruby_spec.version} (#{Time.now.strftime('%Y-%m-%d')})"
0
+ header = File.readlines('CHANGELOG').first
0
+ fail "Expecting CHANGELOG to start with #{expecting}, but found #{header} instead" unless expecting == header
0
- task :packages=>['rake:docs', 'rake:package'] do |task|
0
- # Read the changes for this release.
0
- pattern = /(^(\d+\.\d+(?:\.\d+)?)\s+\(\d{4}-\d{2}-\d{2}\)\s*((:?^[^\n]+\n)*))/
0
- changelog = File.read(__FILE__.pathmap('%d/CHANGELOG'))
0
- changes = changelog.scan(pattern).inject({}) { |hash, set| hash[set[1]] = set[2] ; hash }
0
- current = changes[ruby_spec.version.to_s]
0
- if !current && ruby_spec.version.to_s =~ /\.0$/
0
- current = changes[ruby_spec.version.to_s.split('.')[0..-2].join('.')]
0
+ # License requirement.
0
+ say 'Checking that files contain the Apache license ... '
0
+ directories = 'lib', 'spec', 'docs', 'bin'
0
+ ignore = 'class', 'opts'
0
+ FileList['lib/**/*', 'spec/**/*', 'bin/**', 'doc/css/*', 'doc/scripts/*'].
0
+ exclude('doc/css/eiffel.css').reject { |file| File.directory?(file) || ignore.include?(file[/[^.]*$/]) }.each do |file|
0
+ comments = File.read(file).scan(/(\/\*(.*?)\*\/)|^#\s+(.*?)$|<!--(.*?)-->/m).
0
+ map { |match| match.reject(&:nil?) }.flatten.join("\n")
0
+ fail "File #{file} missing Apache License, please add it before making a release!" unless
0
+ comments =~ /Licensed to the Apache Software Foundation/ && comments =~ /http:\/\/www.apache.org\/licenses\/LICENSE-2.0/
0
- fail "No changeset found for version #{ruby_spec.version}" unless current
0
- puts "Uploading #{ruby_spec.name} #{ruby_spec.version}"
0
- files = Dir.glob('pkg/*.{gem,tgz,zip}')
0
- rubyforge = RubyForge.new
0
- File.open('.changes', 'w'){|f| f.write(current)}
0
- rubyforge.userconfig.merge!('release_changes' => '.changes', 'preformatted' => true)
0
- rubyforge.add_release ruby_spec.rubyforge_project.downcase, ruby_spec.name.downcase, ruby_spec.version, *files
0
- puts "Release #{ruby_spec.version} uploaded"
0
+ fail "Cannot release unless all local changes are in SVN:\n#{status}" unless status.empty?
0
+ # Compile Java libraries.
0
+ say 'Compiling Java libraries ... '
0
+ FileList['lib/**/*.class'].each { |file| rm file }
0
+ FileList['lib/**/*.java'].each { |src| fail "Can't find .class file for #{src}!" unless File.exist?(src.ext('class')) }
0
- # TODO: Check that we're using allison.
0
- # TODO: Check that we can generate PDFs.
0
+ # Tests, specs and coverage reports.
0
+ say 'Checking that we have JRuby, Scala and Groovy available ... '
0
+ fail 'Full testing requires JRuby!' if `which jruby`.empty?
0
+ fail 'Full testing requires Scala!' if `which scalac`.empty? || ENV['SCALA_HOME'].to_s.empty?
0
+ fail 'Full testing requires Groovy!' if `which groovyc`.empty?
0
+ say 'Running test suite using JRuby ...'
0
+ task('spec:jruby').invoke
0
+ say 'Running test suite using Ruby ...'
0
+ task('spec:ruby').invoke
0
- require 'highline/import'
0
+ # Documentation (derived from above).
0
+ say 'Checking that we can use Allison and PrinceXML ... '
0
+ fail 'Release requires the Allison RDoc template, please gem install allison!' unless rdoc.template =~ /allison.rb/
0
+ fail 'Release requires PrinceXML to generate PDF documentation!' if `which prince`.empty?
0
+ task 'prepare'=>'spec:full' do
0
+ say 'Generating RDocs and PDF ...'
0
- puts "This version: #{ruby_spec.version}"
0
- puts "Top 4 lines form CHANGELOG:'
0
- puts File.readlines('CHANGELOG')[0..3].map { |l| " #{l}" }
0
- ask('Top-entry in CHANGELOG file includes today\'s date?') =~ /yes/i or
0
- fail 'Please update CHANGELOG to include the right date'
0
+ say 'Checking that we have PDF, RDoc, specs and coverage report ... '
0
+ fail 'No RDocs if html/rdoc!' unless File.exist?('html/rdoc/files/lib/buildr_rb.html')
0
+ fail 'No PDF generated, you need to install PrinceXML!' unless File.exist?('html/buildr.pdf')
0
+ fail 'No specifications in html directory!' unless File.exist?('html/specs.html')
0
+ fail 'No coverage reports in html/coverage directory!' unless File.exist?('html/coverage/index.html')
0
- next_version = ruby_spec.version.to_ints.zip([0, 0, 1]).map { |a| a.inject(0) { |t,i| t + i } }.join('.')
0
- puts "Updating lib/buildr.rb to next version number: #{next_version}"
0
- buildr_rb = File.read(__FILE__.pathmap('%d/lib/buildr.rb')).
0
- sub(/(VERSION\s*=\s*)(['"])(.*)\2/) { |line| "#{$1}#{$2}#{next_version}#{$2}" }
0
- File.open(__FILE__.pathmap('%d/lib/buildr.rb'), 'w') { |file| file.write buildr_rb }
0
- puts 'Adding entry to CHANGELOG'
0
- changelog = File.read(__FILE__.pathmap('%d/CHANGELOG'))
0
- File.open(__FILE__.pathmap('%d/CHANGELOG'), 'w') { |file| file.write "#{next_version} (Pending)\n\n#{changelog}" }
0
+ require 'rubyforge' rescue fail 'RubyForge required, please gem install rubyforge!'
0
+ fail 'GnuPG required to create signatures!' if `which gpg`.empty?
0
+ gpg_user = ENV['GPG_USER'] or fail 'Please set GPG_USER (--local-user) environment variable so we know which key to use.'
0
+ sh('gpg', '--list-key', gpg_user) { |ok, res| ok or fail "No key matches for GPG_USER=#{gpg_user}" }
0
- task :meat=>['clobber', 'svn:clean?', 'spec:jruby', 'spec:report', 'upload:packages', 'upload:docs', 'svn:tag']
0
+ # Cut the release: upload Gem to RubyForge before updating site (fail safe).
0
+ task 'cut'=>['upload:rubyforge', 'upload:site']
0
-desc 'Upload release to RubyForge including docs, tag SVN'
0
-task :release=>[ 'release:ready?', 'release:meat', 'release:post' ]
0
+ # Upload site (html directory) to Apache.
0
+ task 'site'=>'rake:docs' do
0
+ say 'Uploading Web site to people.apache.org ... '
0
+ args = Dir.glob('html/*') + ['people.apache.org:/www/incubator.apache.org/' + ruby_spec.rubyforge_project.downcase]
0
+ verbose(false) { sh 'rsync ', '-r', '--del', '--progress', *files }
0
-# Handles Java libraries that are part of Buildr.
0
- $LOAD_PATH.unshift File.expand_path('lib')
0
- require 'buildr/jetty'
0
+ # Upload Gems to RubyForge.
0
+ task 'rubyforge'=>['rake:docs', 'rake:package'] do
0
- # RJB, JUnit and friends.
0
- Dir.chdir 'lib/java' do
0
- `javac -source 1.4 -target 1.4 -Xlint:all org/apache/buildr/*.java`
0
+ # Read the changes for this release.
0
+ say 'Looking for changes between this release and previous one ... '
0
+ pattern = /(^(\d+\.\d+(?:\.\d+)?)\s+\(\d{4}-\d{2}-\d{2}\)\s*((:?^[^\n]+\n)*))/
0
+ changelog = File.read(__FILE__.pathmap('%d/CHANGELOG'))
0
+ changes = changelog.scan(pattern).inject({}) { |hash, set| hash[set[1]] = set[2] ; hash }
0
+ current = changes[ruby_spec.version.to_s]
0
+ current = changes[ruby_spec.version.to_s.split('.')[0..-2].join('.')] if !current && ruby_spec.version.to_s =~ /\.0$/
0
+ fail "No changeset found for version #{ruby_spec.version}" unless current
0
- cp = artifacts(Buildr::Jetty::REQUIRES).each { |task| task.invoke }.map(&:name).join(File::PATH_SEPARATOR)
0
- Dir.chdir 'lib/buildr' do
0
- `javac -source 1.4 -target 1.4 -Xlint:all -cp #{cp} org/apache/buildr/*.java`
0
+ say "Uploading #{ruby_spec.version} to RubyForge ... "
0
+ files = Dir.glob('pkg/*.{gem,tgz,zip}')
0
+ rubyforge = RubyForge.new
0
+ File.open('.changes', 'w'){|f| f.write(current)}
0
+ rubyforge.userconfig.merge!('release_changes' => '.changes', 'preformatted' => true)
0
+ rubyforge.add_release ruby_spec.rubyforge_project.downcase, ruby_spec.name.downcase, ruby_spec.version, *files
0
+ task 'apache'=>['rake:package'] do
0
-# - Create MD5/SHA1/PGP signatures
0
-# - Upload to people.apache.org:/www/www.apache.org/dist/incubator/buildr
0
+ gpg_user = ENV['GPG_USER'] or fail 'Please set GPG_USER (--local-user) environment variable so we know which key to use.'
0
+ say 'Creating -incubating packages ... '
0
+ packages = FileList['pkg/*.{gem,zip,tgz}'].map do |package|
0
+ package.pathmap('incubating/%n-incubating%x').tap do |incubating|
0
+ cp package, incubating
0
- task 'prepare'=>'clobber'
0
+ say 'Signing -incubating packages ... '
0
+ files = packages.each do |package|
0
+ binary = File.read(package)
0
+ File.open(package + '.md5', 'w') { |file| file.write MD5.hexdigest(binary) << ' ' << package }
0
+ File.open(package + '.sha1', 'w') { |file| file.write SHA1.hexdigest(binary) << ' ' << package }
0
+ sh 'gpg', '--local-user', gpg_user, '--armor', '--output', package + '.asc', '--detach-sig', package, :verbose=>true
0
+ [package, package + '.md5', package + '.sha1', package + '.asc']
0
- # Check that all source files have licenses.
0
- puts 'Checking that files contain the Apache license'
0
- directories = 'lib', 'spec', 'docs', 'bin'
0
- ignore = 'class', 'opts'
0
- FileList['lib/**/*', 'spec/**/*', 'bin/**', 'doc/css/*', 'doc/scripts/*'].
0
- exclude('doc/css/eiffel.css').reject { |file| File.directory?(file) || ignore.include?(file[/[^.]*$/]) }.each do |file|
0
- comments = File.read(file).scan(/(\/\*(.*?)\*\/)|^#\s+(.*?)$|<!--(.*?)-->/m).
0
- map { |match| match.reject(&:nil?) }.flatten.join("\n")
0
- fail "File #{file} missing Apache License, please add it before making a release!" unless
0
- comments =~ /Licensed to the Apache Software Foundation/ && comments =~ /http:\/\/www.apache.org\/licenses\/LICENSE-2.0/
0
+ say 'Uploading packages to Apache dist ... '
0
+ args = files.flatten << 'KEYS' << 'people.apache.org:/www.apache.org/dist/incubator/buildr/'
0
+ verbose(false) { sh 'rsync', '-progress', *args }
0
+
Rake::Task['rake:clobber'].enhance { rm_rf 'incubating' }0
- # Compile Java libraries.
0
- task 'prepare'=>'compile' do
0
- FileList['lib/**/*.java'].each { |src| fail "Can't find .class file for #{src}!" unless File.exist?(src.ext('class')) }
0
- # Make sure we have RDoc template, Docter and PDF genereation.
0
- task 'prepare'=>[rdoc.template, pdf] do
0
- fail 'Release requires the Allison RDoc template, please gem install allison!' unless rdoc.template =~ /allison.rb/
0
- fail 'No PDF generated, you need to install PrinceXML!' unless File.exist?('html/buildr.pdf')
0
+ # Tag this release in SVN.
0
+ say "Tagging release as tags/#{ruby_spec.version} ... "
0
+ cur_url = `svn info`.scan(/URL: (.*)/)[0][0]
0
+ new_url = cur_url.sub(/(trunk$)|(branches\/\w*)$/, "tags/#{ruby_spec.version.to_s}")
0
+ sh 'svn', 'copy', cur_url, new_url, '-m', "Release #{ruby_spec.version.to_s}", :verbose=>false
0
- # Run specs on Ruby and JRuby, make sure we generate test/coverage reports.
0
- task 'prepare'=>['spec:jruby', 'spec:report'] do
0
- fail 'No test reports in html directory!' unless File.exist?('html/report.html')
0
- fail 'No coverage reports in html directory!' unless File.exist?('html/coverage/index.html')
0
+ # Update lib/buildr.rb to next vesion number, add new entry in CHANGELOG.
0
+ task 'next_version'=>'tag' do
0
+ next_version = ruby_spec.version.to_ints.zip([0, 0, 1]).map { |a| a.inject(0) { |t,i| t + i } }.join('.')
0
+ say "Updating lib/buildr.rb to next version number (#{next_version}) ... "
0
+ buildr_rb = File.read(__FILE__.pathmap('%d/lib/buildr.rb')).
0
+ sub(/(VERSION\s*=\s*)(['"])(.*)\2/) { |line| "#{$1}#{$2}#{next_version}#{$2}" }
0
+ File.open(__FILE__.pathmap('%d/lib/buildr.rb'), 'w') { |file| file.write buildr_rb }
0
+ say 'Adding new entry to CHANGELOG ... '
0
+ changelog = File.read(__FILE__.pathmap('%d/CHANGELOG'))
0
+ File.open(__FILE__.pathmap('%d/CHANGELOG'), 'w') { |file| file.write "#{next_version} (Pending)\n\n#{changelog}" }
0
+ # Wrapup comes after cut, and does things like tagging in SVN, updating Buildr version number, etc.
0
+ task 'wrapup'=>['tag', 'next_version']
0
+task 'release'=>['release:prepare', 'release:cut', 'release:wrapup']
Comments
No one has commented yet.