You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by as...@apache.org on 2007/12/21 10:28:09 UTC

svn commit: r606144 [1/2] - in /incubator/buildr/trunk: ./ doc/pages/ lib/ lib/buildr/ lib/core/ lib/java/ lib/tasks/ spec/ test/

Author: assaf
Date: Fri Dec 21 01:28:05 2007
New Revision: 606144

URL: http://svn.apache.org/viewvc?rev=606144&view=rev
Log:
Upgraded to Rake 0.8 and refactoring of CompileTask to allow multiple compilers

Added:
    incubator/buildr/trunk/lib/core/compile.rb
    incubator/buildr/trunk/lib/core/environment.rb
    incubator/buildr/trunk/spec/
      - copied from r605377, incubator/buildr/trunk/test/
    incubator/buildr/trunk/spec/archive_spec.rb
      - copied unchanged from r605377, incubator/buildr/trunk/test/archive.rb
    incubator/buildr/trunk/spec/artifact_spec.rb
      - copied unchanged from r605377, incubator/buildr/trunk/test/artifact.rb
    incubator/buildr/trunk/spec/build_spec.rb
      - copied unchanged from r605377, incubator/buildr/trunk/test/build.rb
    incubator/buildr/trunk/spec/checks_spec.rb
      - copied unchanged from r605992, incubator/buildr/trunk/test/checks.rb
    incubator/buildr/trunk/spec/common_spec.rb
      - copied, changed from r605377, incubator/buildr/trunk/test/common.rb
    incubator/buildr/trunk/spec/compile_spec.rb
      - copied, changed from r605377, incubator/buildr/trunk/test/compile.rb
    incubator/buildr/trunk/spec/packaging_spec.rb
      - copied, changed from r605992, incubator/buildr/trunk/test/packaging.rb
    incubator/buildr/trunk/spec/project_spec.rb
      - copied, changed from r605377, incubator/buildr/trunk/test/project.rb
    incubator/buildr/trunk/spec/sandbox.rb
      - copied, changed from r606143, incubator/buildr/trunk/test/sandbox.rb
    incubator/buildr/trunk/spec/spec.opts
      - copied unchanged from r606143, incubator/buildr/trunk/test/spec.opts
    incubator/buildr/trunk/spec/test_spec.rb
      - copied, changed from r605992, incubator/buildr/trunk/test/test.rb
    incubator/buildr/trunk/spec/transport_spec.rb
      - copied unchanged from r605377, incubator/buildr/trunk/test/transport.rb
Removed:
    incubator/buildr/trunk/lib/core/rake_ext.rb
    incubator/buildr/trunk/spec/archive.rb
    incubator/buildr/trunk/spec/artifact.rb
    incubator/buildr/trunk/spec/build.rb
    incubator/buildr/trunk/spec/checks.rb
    incubator/buildr/trunk/spec/common.rb
    incubator/buildr/trunk/spec/compile.rb
    incubator/buildr/trunk/spec/packaging.rb
    incubator/buildr/trunk/spec/project.rb
    incubator/buildr/trunk/spec/rake_ext.rb
    incubator/buildr/trunk/spec/test.rb
    incubator/buildr/trunk/spec/transport.rb
    incubator/buildr/trunk/test/
Modified:
    incubator/buildr/trunk/CHANGELOG
    incubator/buildr/trunk/Rakefile
    incubator/buildr/trunk/doc/pages/contributing.textile
    incubator/buildr/trunk/lib/buildr/hibernate.rb
    incubator/buildr/trunk/lib/core.rb
    incubator/buildr/trunk/lib/core/build.rb
    incubator/buildr/trunk/lib/core/checks.rb
    incubator/buildr/trunk/lib/core/common.rb
    incubator/buildr/trunk/lib/core/help.rb
    incubator/buildr/trunk/lib/core/project.rb
    incubator/buildr/trunk/lib/java/compile.rb
    incubator/buildr/trunk/lib/java/packaging.rb
    incubator/buildr/trunk/lib/java/test.rb
    incubator/buildr/trunk/lib/tasks/concat.rb
    incubator/buildr/trunk/lib/tasks/zip.rb

Modified: incubator/buildr/trunk/CHANGELOG
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/CHANGELOG?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/CHANGELOG (original)
+++ incubator/buildr/trunk/CHANGELOG Fri Dec 21 01:28:05 2007
@@ -1,7 +1,8 @@
 1.3.0 (Pending)
 * Added: Mechanism to simplify creating extensions (see Extension module).
 * Added: To run all test cases 'rake spec'.  Test coverage reports will show up in html/coverage.  To run failing tests against, 'rake failing'.
-* Changed: Upgraded to RSpec 1.1.1.
+* Changed: Upgraded to Rake 0.8 and RSpec 1.1.
+* Changed: Resources are now copied to target/resources instead of target/classes.
 * Fixed: Artifact.pom resolves artifact without classifier, i.e org.testng:testng:jar:jdk15:5.1 uses org.testng:testng:pom:5.1 (Tommy).
 * Fixed: More patches towards JRuby support, courtesy of Vic Borja.
 

Modified: incubator/buildr/trunk/Rakefile
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/Rakefile?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/Rakefile (original)
+++ incubator/buildr/trunk/Rakefile Fri Dec 21 01:28:05 2007
@@ -1,44 +1,44 @@
-require "rubygems"
+require 'rubygems'
 Gem::manage_gems
-require "rake/gempackagetask"
-require "spec/rake/spectask"
+require 'rake/gempackagetask'
+require 'spec/rake/spectask'
 
 
 # Gem specification comes first, other tasks rely on it.
 def specify(platform)
   Gem::Specification.new do |spec|
-    spec.name         = "buildr"
-    spec.version      = File.read(__FILE__.pathmap("%d/lib/buildr.rb")).scan(/VERSION\s*=\s*(['"])(.*)\1/)[0][1]
-    spec.author       = "Apache Buildr"
-    spec.email        = "buildr-user@incubator.apache.org"
+    spec.name         = 'buildr'
+    spec.version      = File.read(__FILE__.pathmap('%d/lib/buildr.rb')).scan(/VERSION\s*=\s*(['"])(.*)\1/)[0][1]
+    spec.author       = 'Apache Buildr'
+    spec.email        = 'buildr-user@incubator.apache.org'
     spec.homepage     = "http://incubator.apache.org/#{spec.name}/"
-    spec.summary      = "A build system that doesn't suck"
-    spec.files        = FileList["lib/**/*", "CHANGELOG", "README", "LICENSE", "NOTICE", "DISCLAIMER",
-                                 "Rakefile", "test/**/*", "doc/**/*"].collect
-    spec.require_path = "lib"
-    spec.autorequire  = "buildr.rb"
+    spec.summary      = 'A build system that doesn\'t suck'
+    spec.files        = FileList['lib/**/*', 'CHANGELOG', 'README', 'LICENSE', 'NOTICE', 'DISCLAIMER',
+                                 'Rakefile', 'spec/**/*', 'doc/**/*'].collect
+    spec.require_path = 'lib'
+    spec.autorequire  = 'buildr.rb'
     spec.has_rdoc     = true
-    spec.extra_rdoc_files = ["README", "CHANGELOG", "LICENSE"]
-    spec.rdoc_options << "--title" << "Buildr -- #{spec.summary}" <<
-                         "--main" << "README" << "--line-numbers" << "--inline-source" << "-p" <<
-                         "--webcvs" << "http://svn.apache.org/repos/asf/incubator/buildr/trunk/"
-    spec.rubyforge_project = "buildr"
+    spec.extra_rdoc_files = ['README', 'CHANGELOG', 'LICENSE']
+    spec.rdoc_options << '--title' << "Buildr -- #{spec.summary}" <<
+                         '--main' << 'README' << '--line-numbers' << '--inline-source' << '-p' <<
+                         '--webcvs' << 'http://svn.apache.org/repos/asf/incubator/buildr/trunk/'
+    spec.rubyforge_project = 'buildr'
 
-    spec.bindir = "bin"                               # Use these for applications.
-    spec.executables = ["buildr"]
+    spec.bindir = 'bin'                               # Use these for applications.
+    spec.executables = ['buildr']
 
     # Tested against these dependencies.
-    spec.add_dependency "rake",                 "= 0.7.3"
-    spec.add_dependency "facets",               "= 1.8.54"
-    spec.add_dependency "builder",              "= 2.1.2"
-    spec.add_dependency "net-ssh",              "= 1.1.2"
-    spec.add_dependency "net-sftp",             "= 1.1.0"
-    spec.add_dependency "rubyzip",              "= 0.9.1"
-    spec.add_dependency "highline",             "= 1.4.0"
-    spec.add_dependency "Antwrap",              "= 0.6.0"
-    spec.add_dependency "rspec",                "= 1.1.1"
-    spec.add_dependency "xml-simple",           "= 1.0.11"
-    spec.add_dependency "archive-tar-minitar",  "= 0.5.1"
+    spec.add_dependency 'rake',                 '= 0.8.0'
+    spec.add_dependency 'facets',               '= 1.8.54'
+    spec.add_dependency 'builder',              '= 2.1.2'
+    spec.add_dependency 'net-ssh',              '= 1.1.2'
+    spec.add_dependency 'net-sftp',             '= 1.1.0'
+    spec.add_dependency 'rubyzip',              '= 0.9.1'
+    spec.add_dependency 'highline',             '= 1.4.0'
+    spec.add_dependency 'Antwrap',              '= 0.6.0'
+    spec.add_dependency 'rspec',                '= 1.1.1'
+    spec.add_dependency 'xml-simple',           '= 1.0.11'
+    spec.add_dependency 'archive-tar-minitar',  '= 0.5.1'
     
     spec.platform = platform
 
@@ -46,7 +46,7 @@
   end
 end
 
-spec = specify(Gem::Platform::RUBY) { |spec| spec.add_dependency "rjb", ">= 1.0.11" }
+spec = specify(Gem::Platform::RUBY) { |spec| spec.add_dependency 'rjb', '>= 1.0.11' }
 jruby_spec = specify('java')
 package = Rake::GemPackageTask.new(spec) do |pkg|
   pkg.need_tar = true
@@ -54,36 +54,36 @@
 end
 jruby_package = Rake::GemPackageTask.new(jruby_spec)
 
-desc "Install the package locally"
+desc 'Install the package locally'
 task :install=>:package do |task|
   install = RUBY_PLATFORM == 'java' ? jruby_package : package
   system 'gem', 'install', File.expand_path(install.gem_file, install.package_dir)
 end
 
-desc "Uninstall previously installed packaged"
+desc 'Uninstall previously installed packaged'
 task :uninstall do |task|
   install = RUBY_PLATFORM == 'java' ? jruby_package : package
-  system "gem", "uninstall", install.name, "-v", install.version.to_s
+  system 'gem', 'uninstall', install.name, '-v', install.version.to_s
 end
 
 
 # Testing is everything.
-desc "Run all specs"
+desc 'Run all specs'
 Spec::Rake::SpecTask.new('spec') do |task|
-  task.spec_files = FileList['test/**/*.rb']
-  task.spec_opts << '--options' << 'test/spec.opts' << '--format' << 'failing_examples:failing'
+  task.spec_files = FileList['spec/**/*_spec.rb']
+  task.spec_opts << '--options' << 'spec/spec.opts' << '--format' << 'failing_examples:failing'
 end
 
-desc "Run all failing examples"
+desc 'Run all failing examples'
 Spec::Rake::SpecTask.new('failing') do |task|
-  task.spec_files = FileList['test/**/*.rb']
-  task.spec_opts << '--options' << 'test/spec.opts' << '--format' << 'failing_examples:failing' << '--example' << 'failing'
+  task.spec_files = FileList['spec/**/*_spec.rb']
+  task.spec_opts << '--options' << 'spec/spec.opts' << '--format' << 'failing_examples:failing' << '--example' << 'failing'
 end
 
-desc "Run all specs and store html output in doc/output/report.html"
-Spec::Rake::SpecTask.new('spec:html') do |task|
-  task.spec_files = FileList['test/**/*.rb']
-  task.spec_opts << '--format html:html/report.html' << '--backtrace'
+desc 'Run all specs and generate reports in html directory'
+Spec::Rake::SpecTask.new('spec:report') do |task|
+  task.spec_files = FileList['spec/**/*_spec.rb']
+  task.spec_opts << '--format' << 'html:html/report.html' << '--backtrace'
   task.rcov = true
   task.rcov_dir = 'html/coverage'
 end
@@ -91,53 +91,53 @@
 
 # Documentation.
 begin
-  require "rake/rdoctask"
-  require "docter"
-  require "docter/server"
-  require "docter/ultraviolet"
+  require 'rake/rdoctask'
+  require 'docter'
+  require 'docter/server'
+  require 'docter/ultraviolet'
 
-  desc "Generate RDoc documentation"
+  desc 'Generate RDoc documentation'
   rdoc = Rake::RDocTask.new(:rdoc) do |rdoc|
-    rdoc.rdoc_dir = "html/rdoc"
+    rdoc.rdoc_dir = 'html/rdoc'
     rdoc.title    = spec.name
     rdoc.options  = spec.rdoc_options
-    rdoc.rdoc_files.include("lib/**/*.rb")
+    rdoc.rdoc_files.include('lib/**/*.rb')
     rdoc.rdoc_files.include spec.extra_rdoc_files
   end
 
-  web_collection = Docter.collection.using("doc/web.toc.textile").include("doc/pages", "CHANGELOG")
-  web_template = Docter.template("doc/web.haml").include("doc/css", "doc/images")
-  print_collection = Docter.collection.using("doc/print.toc.textile").include("doc/pages")
-  print_template = Docter.template("doc/print.haml").include("doc/css", "doc/images")
+  web_collection = Docter.collection.using('doc/web.toc.textile').include('doc/pages', 'CHANGELOG')
+  web_template = Docter.template('doc/web.haml').include('doc/css', 'doc/images')
+  print_collection = Docter.collection.using('doc/print.toc.textile').include('doc/pages')
+  print_template = Docter.template('doc/print.haml').include('doc/css', 'doc/images')
 
   Docter.filter_for(:footnote) do |html|
     html.gsub(/<p id="fn(\d+)">(.*?)<\/p>/, %{<p id="fn\\1" class="footnote">\\2</p>})
   end
 
-  desc "Produce PDF"
-  print = Docter::Rake.generate("print", print_collection, print_template, :one_page)
-  pdf_file = file("html/buildr.pdf"=>print) do |task|
-    mkpath "html"
+  desc 'Produce PDF'
+  print = Docter::Rake.generate('print', print_collection, print_template, :one_page)
+  pdf_file = file('html/buildr.pdf'=>print) do |task|
+    mkpath 'html'
     sh *%W{prince #{print}/index.html -o #{task.name}} do |ok, res|
-      fail "Failed to create PDF, see errors above" unless ok
+      fail 'Failed to create PDF, see errors above' unless ok
     end
   end
-  task("pdf"=>pdf_file) { |task| `kpdf #{File.expand_path(pdf_file.to_s)}` }
+  task('pdf'=>pdf_file) { |task| `kpdf #{File.expand_path(pdf_file.to_s)}` }
 
-  desc "Generate HTML documentation"
-  html = Docter::Rake.generate("html", web_collection, web_template)
-  desc "Run Docter server"
+  desc 'Generate HTML documentation'
+  html = Docter::Rake.generate('html', web_collection, web_template)
+  desc 'Run Docter server'
   Docter::Rake.serve :docter, web_collection, web_template, :port=>3000
 
-  desc "Generate all documentation merged into the html directory"
-  task "docs"=>[html, rdoc.name, pdf_file]
-  task("clobber") { rm_rf [html, print].map(&:to_s) }
+  desc 'Generate all documentation merged into the html directory'
+  task 'docs'=>[html, rdoc.name, pdf_file]
+  task('clobber') { rm_rf [html, print].map(&:to_s) }
 
 rescue LoadError=>error
   puts error
-  puts "To create the Buildr documentation you need to:"
-  puts "  gem install docter"
-  puts "  gem install ultraviolet"
+  puts 'To create the Buildr documentation you need to:'
+  puts '  gem install docter'
+  puts '  gem install ultraviolet'
 end
 
 
@@ -151,26 +151,26 @@
   task :tag do |task|
     cur_url = `svn info`.scan(/URL: (.*)/)[0][0]
     new_url = cur_url.sub(/(trunk$)|(branches\/\w*)$/, "tags/#{spec.version.to_s}")
-    system "svn", "copy", cur_url, new_url, "-m", "Release #{spec.version.to_s}"
+    system 'svn', 'copy', cur_url, new_url, '-m', "Release #{spec.version.to_s}"
   end
 end
 
 namespace :upload do
 
-  task :docs=>"rake:docs" do |task|
-    sh "rsync -r --del --progress html/*  people.apache.org:/www/incubator.apache.org/#{spec.rubyforge_project.downcase}/"
+  task :docs=>'rake:docs' do |task|
+    sh %{rsync -r --del --progress html/*  people.apache.org:/www/incubator.apache.org/#{spec.rubyforge_project.downcase}/}
   end
 
-  task :packages=>["rake:docs", "rake:package"] do |task|
+  task :packages=>['rake:docs', 'rake:package'] do |task|
     require 'rubyforge'
 
     # Read the changes for this release.
     pattern = /(^(\d+\.\d+(?:\.\d+)?)\s+\(\d+\/\d+\/\d+\)\s*((:?^[^\n]+\n)*))/
-    changelog = File.read(__FILE__.pathmap("%d/CHANGELOG"))
+    changelog = File.read(__FILE__.pathmap('%d/CHANGELOG'))
     changes = changelog.scan(pattern).inject({}) { |hash, set| hash[set[1]] = set[2] ; hash }
     current = changes[spec.version.to_s]
     if !current && spec.version.to_s =~ /\.0$/
-      current = changes[spec.version.to_s.split(".")[0..-2].join(".")] 
+      current = changes[spec.version.to_s.split('.')[0..-2].join('.')] 
     end
     fail "No changeset found for version #{spec.version}" unless current
 
@@ -178,10 +178,10 @@
     files = Dir.glob('pkg/*.{gem,tgz,zip}')
     rubyforge = RubyForge.new
     rubyforge.login    
-    File.open(".changes", 'w'){|f| f.write(current)}
-    rubyforge.userconfig.merge!("release_changes" => ".changes",  "preformatted" => true)
+    File.open('.changes', 'w'){|f| f.write(current)}
+    rubyforge.userconfig.merge!('release_changes' => '.changes',  'preformatted' => true)
     rubyforge.add_release spec.rubyforge_project.downcase, spec.name.downcase, spec.version, *files
-    rm ".changes"
+    rm '.changes'
     puts "Release #{spec.version} uploaded"
   end
 end
@@ -193,42 +193,42 @@
 
     puts "This version: #{spec.version}"
     puts
-    puts "Top 4 lines form CHANGELOG:"
-    puts File.readlines("CHANGELOG")[0..3].map { |l| "  #{l}" }
+    puts "Top 4 lines form CHANGELOG:'
+    puts File.readlines('CHANGELOG')[0..3].map { |l| "  #{l}" }
     puts
-    ask("Top-entry in CHANGELOG file includes today's date?") =~ /yes/i or
-      fail "Please update CHANGELOG to include the right date"
+    ask('Top-entry in CHANGELOG file includes today\'s date?') =~ /yes/i or
+      fail 'Please update CHANGELOG to include the right date'
   end
 
   task :post do
     # Practical example of functional read but not comprehend code:
-    next_version = spec.version.to_ints.zip([0, 0, 1]).map { |a| a.inject(0) { |t,i| t + i } }.join(".")
+    next_version = spec.version.to_ints.zip([0, 0, 1]).map { |a| a.inject(0) { |t,i| t + i } }.join('.')
     puts "Updating lib/buildr.rb to next version number: #{next_version}"
-    buildr_rb = File.read(__FILE__.pathmap("%d/lib/buildr.rb")).
+    buildr_rb = File.read(__FILE__.pathmap('%d/lib/buildr.rb')).
       sub(/(VERSION\s*=\s*)(['"])(.*)\2/) { |line| "#{$1}#{$2}#{next_version}#{$2}" } 
-    File.open(__FILE__.pathmap("%d/lib/buildr.rb"), "w") { |file| file.write buildr_rb }
-    puts "Adding entry to CHANGELOG"
-    changelog = File.read(__FILE__.pathmap("%d/CHANGELOG"))
-    File.open(__FILE__.pathmap("%d/CHANGELOG"), "w") { |file| file.write "#{next_version} (Pending)\n\n#{changelog}" }
+    File.open(__FILE__.pathmap('%d/lib/buildr.rb'), 'w') { |file| file.write buildr_rb }
+    puts 'Adding entry to CHANGELOG'
+    changelog = File.read(__FILE__.pathmap('%d/CHANGELOG'))
+    File.open(__FILE__.pathmap('%d/CHANGELOG'), 'w') { |file| file.write "#{next_version} (Pending)\n\n#{changelog}" }
   end
 
-  task :meat=>["clobber", "svn:clean?", "spec:html", "upload:packages", "upload:docs", "svn:tag"]
+  task :meat=>['clobber', 'svn:clean?', 'spec:report', 'upload:packages', 'upload:docs', 'svn:tag']
 end
 
-desc "Upload release to RubyForge including docs, tag SVN"
-task :release=>[ "release:ready?", "release:meat", "release:post" ]
+desc 'Upload release to RubyForge including docs, tag SVN'
+task :release=>[ 'release:ready?', 'release:meat', 'release:post' ]
 
 
 # Misc, may not survive so don't rely on these.
 task :report do |task|
   puts "#{spec.name} #{spec.version}"
   puts spec.summary
-  sources = (spec.files + FileList["test/**/*.rb"]).reject { |f| File.directory?(f) }
+  sources = (spec.files + FileList['spec/**/*.rb']).reject { |f| File.directory?(f) }
   sources.inject({}) do |lists, file|
     File.readlines(file).each_with_index do |line, i|
       if line =~ /(TODO|FIXME|NOTE):\s*(.*)/
         list = lists[$1] ||= []
-        list << sprintf("%s (%d): %s", file, i, $2)
+        list << sprintf('%s (%d): %s', file, i, $2)
       end
     end
     lists
@@ -243,9 +243,9 @@
 
 namespace :setup do
   task :jetty do
-    cp = ["jetty-6.1.1.jar", "jetty-util-6.1.1.jar", "servlet-api-2.5-6.1.1"].
+    cp = ['jetty-6.1.1.jar', 'jetty-util-6.1.1.jar', 'servlet-api-2.5-6.1.1'].
       map { |jar| `locate #{jar}`.split.first }.join(File::PATH_SEPARATOR)
-    Dir.chdir "lib/buildr/jetty" do
+    Dir.chdir 'lib/buildr/jetty' do
       `javac -cp #{cp} JettyWrapper.java`
     end
   end

Modified: incubator/buildr/trunk/doc/pages/contributing.textile
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/doc/pages/contributing.textile?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/doc/pages/contributing.textile (original)
+++ incubator/buildr/trunk/doc/pages/contributing.textile Fri Dec 21 01:28:05 2007
@@ -1,15 +1,18 @@
 h1. Contributing
 
-Step 1, join the "mailing list":mailing_lists.html.  It's the best place to ask questions, report
-"features", submit patches and let us know how you use Buildr in your own projects.
+Step 1, join the "mailing list":mailing_lists.html.  It's the best place to ask
+questions, report "features", submit patches and let us know how you use Buildr
+in your own projects.
 
-Step 2, checkout "Buildr from SVN":http://svn.apache.org/repos/asf/incubator/buildr:
+Step 2, checkout "Buildr from
+SVN":http://svn.apache.org/repos/asf/incubator/buildr:
 
 {{{!sh
 $ svn co http://svn.apache.org/repos/asf/incubator/buildr/trunk buildr
 }}}
 
-You can also search the "Buildr repository":http://svn.apache.org/repos/asf/incubator/buildr.
+You can also search the "Buildr
+repository":http://svn.apache.org/repos/asf/incubator/buildr.
 
 Step 3, install Buildr from your working copy:
 
@@ -20,8 +23,11 @@
 
 (@sudo rake install@ if you're running on Linux)
 
-Step 4, send a patch to the mailing list.  And please help us by providing a proper test case.  Buildr uses "RSpec":http://rspec.rubyforge.org/ , a behavior-driven development test framework.  Check out the existing test cases in the @test@ directory, and make sure all tests pass by running:
+Step 4, send a patch to the mailing list.  And please help us by providing a
+proper test case.  Buildr uses "RSpec":http://rspec.rubyforge.org/ , a
+behavior-driven development test framework.  Check out the existing tests
+(specs) in the @spec@ directory, and make sure they all pass by running:
 
 {{{!sh
-$ spec test
+$ rake spec
 }}}

Modified: incubator/buildr/trunk/lib/buildr/hibernate.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/hibernate.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/hibernate.rb (original)
+++ incubator/buildr/trunk/lib/buildr/hibernate.rb Fri Dec 21 01:28:05 2007
@@ -105,7 +105,7 @@
     #     end
     #   end
     def hibernate_schemaexport(args, &block)
-      path, deps = Rake.application.resolve_args(args)
+      path, arg_names, deps = Rake.application.resolve_args([args])
       unless Rake::Task.task_defined?(path)
         class << file(path) ; attr_accessor :ant ; end
         file(path).enhance { |task| task.ant = Hibernate.schemaexport }

Modified: incubator/buildr/trunk/lib/core.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core.rb (original)
+++ incubator/buildr/trunk/lib/core.rb Fri Dec 21 01:28:05 2007
@@ -1,7 +1,9 @@
 require 'core/application'
 require 'core/project'
-require 'core/build'
+require 'core/environment'
 require 'core/help'
+require 'core/build'
+require 'core/compile'
 require 'core/generate'
 
 class Buildr::Project

Modified: incubator/buildr/trunk/lib/core/build.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/build.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/build.rb (original)
+++ incubator/buildr/trunk/lib/core/build.rb Fri Dec 21 01:28:05 2007
@@ -39,9 +39,6 @@
       Project.local_task("uninstall") { |name| "Uninstalling packages from #{name}" }
       desc "Upload packages created by the project"
       Project.local_task("upload"=>"package") { |name| "Deploying packages from #{name}" }
-      task("deploy"=>"upload") do
-        warn_deprecated "Please use the 'upload' task instead of 'deploy'."
-      end
 
       desc "The default task it build"
       task "default"=>"build"

Modified: incubator/buildr/trunk/lib/core/checks.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/checks.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/checks.rb (original)
+++ incubator/buildr/trunk/lib/core/checks.rb Fri Dec 21 01:28:05 2007
@@ -6,7 +6,7 @@
   # Methods added to Project to allow checking the build.
   module Checks
 
-    module Matchers
+    module Matchers #:nodoc:
 
       class << self
 
@@ -267,94 +267,92 @@
 end
 
 
-module Buildr
-  class ArchiveTask
+class Buildr::ArchiveTask
 
-    class Path
-
-      # :call-seq:
-      #   exist() => boolean
-      #
-      # Returns true if this path exists. This only works if the path has any entries in it,
-      # so exist on path happens to be the opposite of empty.
-      def exist?()
-        !entries.empty?
-      end
-
-      # :call-seq:
-      #   empty?() => boolean
-      #
-      # Returns true if this path is empty (has no other entries inside).
-      def empty?()
-        entries.all? { |entry| entry.empty? }
-      end
-
-      # :call-seq:
-      #   contain(file*) => boolean
-      #
-      # Returns true if this ZIP file path contains all the specified files. You can use relative
-      # file names and glob patterns (using *, **, etc).
-      def contain?(*files)
-        files.all? { |file| entries.detect { |entry| File.fnmatch(file, entry.to_s) } }
-      end
-
-      # :call-seq:
-      #   entry(name) => ZipEntry
-      #
-      # Returns a ZIP file entry. You can use this to check if the entry exists and its contents,
-      # for example:
-      #   package(:jar).path("META-INF").entry("LICENSE").should contain(/Apache Software License/)
-      def entry(name)
-        root.entry("#{@path}#{name}")
-      end
-
-    protected
-
-      def entries() #:nodoc:
-        return root.entries unless @path
-        @entries ||= root.entries.inject([]) { |selected, entry|
-          selected << entry.name.sub(@path, "") if entry.name.starts_with?(@path)
-          selected
-        }
-      end
+  class Path #:nodoc:
 
+    # :call-seq:
+    #   exist() => boolean
+    #
+    # Returns true if this path exists. This only works if the path has any entries in it,
+    # so exist on path happens to be the opposite of empty.
+    def exist?()
+      !entries.empty?
     end
 
     # :call-seq:
     #   empty?() => boolean
     #
-    # Returns true if this ZIP file is empty (has no other entries inside).
+    # Returns true if this path is empty (has no other entries inside).
     def empty?()
-      path("").empty
+      entries.all? { |entry| entry.empty? }
     end
 
     # :call-seq:
     #   contain(file*) => boolean
     #
-    # Returns true if this ZIP file contains all the specified files. You can use absolute
+    # Returns true if this ZIP file path contains all the specified files. You can use relative
     # file names and glob patterns (using *, **, etc).
     def contain?(*files)
-      path("").contain?(*files)
+      files.all? { |file| entries.detect { |entry| File.fnmatch(file, entry.to_s) } }
     end
 
-  end
-
-
-  class ZipTask
-
     # :call-seq:
-    #   entry(name) => Entry
+    #   entry(name) => ZipEntry
     #
     # Returns a ZIP file entry. You can use this to check if the entry exists and its contents,
     # for example:
-    #   package(:jar).entry("META-INF/LICENSE").should contain(/Apache Software License/)
-    def entry(entry_name)
-      ::Zip::ZipEntry.new(name, entry_name)
+    #   package(:jar).path("META-INF").entry("LICENSE").should contain(/Apache Software License/)
+    def entry(name)
+      root.entry("#{@path}#{name}")
     end
 
+  protected
+
     def entries() #:nodoc:
-      @entries ||= Zip::ZipFile.open(name) { |zip| zip.entries }
+      return root.entries unless @path
+      @entries ||= root.entries.inject([]) { |selected, entry|
+        selected << entry.name.sub(@path, "") if entry.name.starts_with?(@path)
+        selected
+      }
     end
 
   end
+
+  # :call-seq:
+  #   empty?() => boolean
+  #
+  # Returns true if this ZIP file is empty (has no other entries inside).
+  def empty?()
+    path("").empty
+  end
+
+  # :call-seq:
+  #   contain(file*) => boolean
+  #
+  # Returns true if this ZIP file contains all the specified files. You can use absolute
+  # file names and glob patterns (using *, **, etc).
+  def contain?(*files)
+    path("").contain?(*files)
+  end
+
+end
+
+
+class Buildr::ZipTask #:nodoc:
+
+  # :call-seq:
+  #   entry(name) => Entry
+  #
+  # Returns a ZIP file entry. You can use this to check if the entry exists and its contents,
+  # for example:
+  #   package(:jar).entry("META-INF/LICENSE").should contain(/Apache Software License/)
+  def entry(entry_name)
+    ::Zip::ZipEntry.new(name, entry_name)
+  end
+
+  def entries() #:nodoc:
+    @entries ||= Zip::ZipFile.open(name) { |zip| zip.entries }
+  end
+
 end

Modified: incubator/buildr/trunk/lib/core/common.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/common.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/common.rb (original)
+++ incubator/buildr/trunk/lib/core/common.rb Fri Dec 21 01:28:05 2007
@@ -67,127 +67,18 @@
 end
 
 
-module Buildr
-
-  # Collection of options for controlling Buildr. For example for running builds without running
-  # test cases, using a proxy server, JVM arguments, etc. You access this object by calling options,
-  # for example:
-  #   options.proxy.http = "http://proxy.acme.com:8080"
-  #   options.java_args = "-Xmx512M"
-  class Options
-
-    # We use this to present environment variable as arrays.
-    class EnvArray < Array #:nodoc:
-    
-      def initialize(name)
-        @name = name.upcase
-        replace((ENV[@name] || ENV[@name.downcase] || "").split(/\s*,\s*/).reject(&:empty?))
-      end
-
-      (Array.instance_methods - Object.instance_methods - Enumerable.instance_methods).sort.each do |method|
-        class_eval %{def #{method}(*args, &block) ; result = super ; write ; result ; end}
-      end
-
-    private
-
-      def write()
-        ENV[@name.downcase] = nil
-        ENV[@name] = map(&:to_s).join(",")
-      end
-
-    end
-
-    # Wraps around the proxy environment variables:
-    # * :http -- HTTP_PROXY
-    # * :exclude -- NO_PROXY
-    class Proxies
-
-      # Returns the HTTP_PROXY URL.
-      def http()
-        ENV["HTTP_PROXY"] || ENV["http_proxy"]
+module Rake #:nodoc
+  class FileList
+    class << self
+      def recursive(*dirs)
+        FileList[dirs.map { |dir| File.join(dir, "/**/{*,.*}") }].reject { |file| File.basename(file) =~ /^[.]{1,2}$/ }
       end
-
-      # Sets the HTTP_PROXY URL.
-      def http=(url)
-        ENV["http_proxy"] = nil
-        ENV["HTTP_PROXY"] = url
-      end
-   
-      # Returns list of hosts to exclude from proxying (NO_PROXY). 
-      def exclude()
-        @exclude ||= EnvArray.new("NO_PROXY")
-      end
-
-      # Sets list of hosts to exclude from proxy (NO_PROXY). Accepts host name, array of names,
-      # or nil to clear the list.
-      def exclude=(url)
-        exclude.clear
-        exclude.concat [url].flatten if url
-        exclude
-      end
-
-    end
-
-    # :call-seq:
-    #   proxy() => options
-    #
-    # Returns the proxy options. Currently supported options are:
-    # * :http -- HTTP proxy for use when downloading.
-    # * :exclude -- Do not use proxy for these hosts/domains.
-    #
-    # For example:
-    #   options.proxy.http = "http://proxy.acme.com:8080"
-    # You can also set it using the environment variable HTTP_PROXY.
-    #
-    # You can exclude individual hosts from being proxied, or entire domains, for example:
-    #   options.proxy.exclude = "optimus"
-    #   options.proxy.exclude = ["optimus", "prime"]
-    #   options.proxy.exclude << "*.internal"
-    def proxy()
-      @proxy ||= Proxies.new
-    end
-
-  end
-
-  class << self
-
-    # :call-seq:
-    #   options() => Options
-    #
-    # Returns the Buildr options. See Options.
-    def options()
-      @options ||= Options.new
     end
-
   end
+end
 
-  # :call-seq:
-  #   options() => Options
-  #
-  # Returns the Buildr options. See Options.
-  def options()
-    Buildr.options
-  end
 
-  # :call-seq:
-  #   environment() => string or nil
-  #
-  # Returns the environment name.  Use this when your build depends on the environment,
-  # for example, development, production, etc.  The value comes from the BUILDR_ENV environment variable.
-  # 
-  # For example:
-  #   buildr -e production
-  def environment()
-    ENV['BUILDR_ENV']
-  end
-
-  # :call-seq:
-  #   environment(env)
-  #
-  # Sets the environment name.
-  def environment=(env)
-    ENV['BUILDR_ENV'] = env
-  end
+module Buildr
 
   # :call-seq:
   #   struct(hash) => Struct
@@ -290,7 +181,9 @@
   #
   # You can specify the mapping using a Hash, and it will map ${key} fields found in each source
   # file into the appropriate value in the target file. For example:
+  #
   #   filter.using "version"=>"1.2", "build"=>Time.now
+  #
   # will replace all occurrences of <tt>${version}</tt> with <tt>1.2</tt>, and <tt>${build}</tt>
   # with the current date/time.
   #
@@ -318,18 +211,6 @@
     # Returns the list of source directories (each being a file task).
     attr_reader :sources
 
-    # *Deprecated* Use #sources instead.
-    def source()
-      warn_deprecated "Please use sources instead."
-      @sources.first
-    end
-
-    # *Deprecated* Use #from instead.
-    def source=(dir)
-      warn_deprecated "Please use from instead."
-      from(dir)
-    end
-    
     # :call-seq:
     #   from(*sources) => self
     #

Added: incubator/buildr/trunk/lib/core/compile.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/compile.rb?rev=606144&view=auto
==============================================================================
--- incubator/buildr/trunk/lib/core/compile.rb (added)
+++ incubator/buildr/trunk/lib/core/compile.rb Fri Dec 21 01:28:05 2007
@@ -0,0 +1,449 @@
+require "core/common"
+
+module Buildr
+
+
+  module Compiler
+
+    COMPILERS = []
+
+    class << self
+
+      def select(compiler)
+        cls = COMPILERS.detect { |cls| cls.compiler_name == compiler.to_s }
+        raise "No #{compiler} compiler available. Did you install it?" unless cls
+        cls.new
+      end
+
+      def identify(project)
+        cls = COMPILERS.detect { |compiler| compiler.identify?(project) }
+        cls && cls.new
+      end
+
+    end
+
+
+    class Base
+
+      def self.compiler_name
+        name.split('::').last.downcase
+      end
+
+      def name
+        self.class.compiler_name
+      end
+
+    end
+
+
+    class Java < Base
+
+      COMPILERS << self
+
+      def self.identify?(project)
+        !Dir[project.path_to('src/main/java/**/*.java')].empty?
+      end
+
+      def configure(task, project)
+        task.options.warnings ||= verbose
+        task.options.deprecation ||= false
+        task.options.lint ||= false
+        task.options.debug ||= Buildr.options.debug
+        task.from project.path_to('src/main/java') if task.sources.empty?
+        task.into project.path_to(:target, 'classes') unless task.target
+      end
+
+      def compile(sources, target, dependencies, options, name)
+        ::Buildr::Java.javac source_files(sources, target).keys, :sourcepath=>sources.map(&:to_s).select { |source| File.directory?(source) }.uniq,
+          :classpath=>dependencies, :output=>target, :javac_args=>javac_args_from(options), :name=>name
+      end
+
+      # Returns the files to compile. This list is derived from the list of sources,
+      # expanding directories into files, and includes only source files that are
+      # newer than the corresponding class file. Includes all files if one or more
+      # classpath dependency has been updated.
+      def source_files(sources, target)
+        @source_files ||= sources.map(&:to_s).inject({}) do |map, source|
+          raise "Compile task #{name} has source files, but no target directory" unless target
+          target_dir = target.to_s
+          if File.directory?(source)
+            base = Pathname.new(source)
+            FileList["#{source}/**/*.java"].reject { |file| File.directory?(file) }.
+              each { |file| map[file] = File.join(target_dir, Pathname.new(file).relative_path_from(base).to_s.ext('.class')) }
+          else
+            map[source] = File.join(target_dir, File.basename(source).ext('.class'))
+          end
+          map
+        end
+      end
+
+      def javac_args_from(options)
+        args = []  
+        args << '-nowarn' unless options.warnings
+        args << '-verbose' if Rake.application.options.trace
+        args << '-g' if options.debug
+        args << '-deprecation' if options.deprecation
+        args << '-source' << options.source.to_s if options.source
+        args << '-target' << options.target.to_s if options.target
+        case options.lint
+          when Array; args << "-Xlint:#{options.lint.join(',')}"
+          when String; args << "-Xlint:#{options.lint}"
+          when true; args << '-Xlint'
+        end
+        options.other = options.other.map { |name, value| [ "-#{name}", value.to_s ] }.flatten if Hash === options.other
+        args + Array(options.other)
+      end
+
+    end
+
+  end
+
+
+
+
+=begin
+  # Compiler options, accessible from CompileTask#options.
+  #
+  # Supported options are:
+  # - warnings -- Generate warnings if true (opposite of -nowarn).
+  # - deprecation -- Output source locations where deprecated APIs are used.
+  # - source -- Source compatibility with specified release.
+  # - target -- Class file compatibility with specified release.
+  # - lint -- Value to pass to xlint argument. Use true to enable default lint
+  #   options, or pass a specific setting as string or array of strings.
+  # - debug -- Generate debugging info.
+  # - other -- Array of options to pass to the Java compiler as is.
+  #
+  # For example:
+  #   compile.options.warnings = true
+  #   compile.options.source = options.target = "1.6"
+  module Javac
+
+    def self.extended(base)
+      base.instance_variable_set(:@classpath, [])
+      base.options.warnings ||= verbose
+      base.options.deprecation ||= false
+      base.options.lint ||= false
+      base.options.debug ||= Buildr.options.debug
+    end
+
+    def self.recognize?(project)
+      File.exist?(project.path_to('src/main/java'))
+    end
+
+    def compile
+      Java.javac source_files.keys, :sourcepath=>sources.map(&:to_s).select { |source| File.directory?(source) }.uniq,
+        :classpath=>classpath, :output=>target, :javac_args=>javac_args, :name=>name
+    end
+
+    # Classpath dependencies.
+    attr_accessor :classpath
+
+    # :call-seq:
+    #   with(*artifacts) => self
+    #
+    # Adds files and artifacts as classpath dependencies, and returns self.
+    #
+    # Calls #artifacts on the arguments, so you can pass artifact specifications,
+    # tasks, projects, etc. Use this rather than setting the classpath directly.
+    #
+    # For example:
+    #   compile.with("module1.jar", "log4j:log4j:jar:1.0", project("foo"))
+    def with(*specs)
+      @classpath |= Buildr.artifacts(specs.flatten).uniq
+      self
+    end
+
+    def prerequisites #:nodoc:
+      super + classpath + sources
+    end
+
+    # Returns the files to compile. This list is derived from the list of sources,
+    # expanding directories into files, and includes only source files that are
+    # newer than the corresponding class file. Includes all files if one or more
+    # classpath dependency has been updated.
+    def source_files
+      @source_files ||= @sources.map(&:to_s).inject({}) do |map, source|
+        raise "Compile task #{name} has source files, but no target directory" unless target
+        target_dir = target.to_s
+        if File.directory?(source)
+          base = Pathname.new(source)
+          FileList["#{source}/**/*.java"].reject { |file| File.directory?(file) }.
+            each { |file| map[file] = File.join(target_dir, Pathname.new(file).relative_path_from(base).to_s.ext('.class')) }
+        else
+          map[source] = File.join(target_dir, File.basename(source).ext('.class'))
+        end
+        map
+      end
+    end
+
+    def needed? #:nodoc:
+      return false if source_files.empty?
+      return true unless File.exist?(target.to_s)
+      return true if source_files.any? { |j, c| !File.exist?(c) || File.stat(j).mtime > File.stat(c).mtime }
+      oldest = source_files.map { |j, c| File.stat(c).mtime }.min
+      return classpath.any? { |path| application[path].timestamp > oldest }
+    end
+
+    def javac_args
+      args = []  
+      args << '-nowarn' unless options.warnings
+      args << '-verbose' if Rake.application.options.trace
+      args << '-g' if options.debug
+      args << '-deprecation' if options.deprecation
+      args << '-source' << options.source.to_s if options.source
+      args << '-target' << options.target.to_s if options.target
+      case options.lint
+        when Array; args << "-Xlint:#{options.lint.join(',')}"
+        when String; args << "-Xlint:#{options.lint}"
+        when true; args << '-Xlint'
+      end
+      options.other = options.other.map { |name, value| [ "-#{name}", value.to_s ] }.flatten if Hash === options.other
+      args + Array(options.other)
+    end
+
+  end
+=end
+
+
+  # Wraps Javac in a task that does all the heavy lifting.
+  #
+  # Accepts multiple source directories that are invoked as prerequisites before compilation.
+  # You can pass a task as a source directory, e.g. compile.from(apt).
+  #
+  # Likewise, classpath dependencies are invoked before compiling. All classpath dependencies
+  # are evaluated as #artifacts, so you can pass artifact specifications and even projects.
+  #
+  # Creates a file task for the target directory, so executing that task as a dependency will
+  # execute the compile task first.
+  #
+  # Compiler options are inherited form a parent task, e.g. the foo:bar:compile task inherits
+  # its options from the foo:compile task. Even if foo is an empty project that does not compile
+  # any classes itself, you can use it to set compile options for all its sub-projects.
+  #
+  # Normally, the project will take care of setting the source and target directory, and you
+  # only need to set options and classpath dependencies. See Project#compile.
+  class CompileTask < Rake::Task
+
+    def initialize(*args) #:nodoc:
+      super
+      parent = Project.task_in_parent_project(name)
+      @options = parent && parent.respond_to?(:options) && parent.options.clone || OpenStruct.new
+      @sources = []
+      @dependencies = []
+
+      project = Project.project_from_task(self)
+      @compiler = Compiler.identify(project)
+      compiler.configure(self, project) if compiler
+
+      enhance do |task|
+        unless target.nil? || sources.empty?
+          raise "No compiler selected and can't determine default compiler to use" unless compiler
+          mkpath target.to_s, :verbose=>false
+          compiler.compile(sources, target, dependencies, options, task.name)
+          # By touching the target we let other tasks know we did something,
+          # and also prevent recompiling again for dependencies.
+          touch target.to_s, :verbose=>false
+        end
+      end
+    end
+
+    # :call-seq:
+    #   from(*sources) => self
+    #
+    # Adds source directories and files to compile, and returns self.
+    #
+    # For example:
+    #   compile.from("src/java").into("classes").with("module1.jar")
+    def from(*sources)  
+      @sources |= sources.flatten
+      self
+    end
+
+    # *Deprecated*: Use dependencies instead.
+    def classpath
+      warn_deprecated 'Use dependencies instead.'
+      dependencies
+    end
+
+    # *Deprecated*: Use dependencies= instead.
+    def classpath=(artifacts)
+      warn_deprecated 'Use dependencies= instead.'
+      self.dependencies = artifacts
+    end
+
+    # Compilation dependencies.
+    attr_accessor :dependencies
+
+    # :call-seq:
+    #   with(*artifacts) => self
+    #
+    # Adds files and artifacts as dependencies, and returns self.
+    #
+    # Calls #artifacts on the arguments, so you can pass artifact specifications,
+    # tasks, projects, etc. Use this rather than setting the dependencies array directly.
+    #
+    # For example:
+    #   compile.with("module1.jar", "log4j:log4j:jar:1.0", project("foo"))
+    def with(*specs)
+      @dependencies |= Buildr.artifacts(specs.flatten).uniq
+      self
+    end
+
+    # The target directory for the compiled code.
+    attr_reader :target
+
+    # :call-seq:
+    #   into(path) => self
+    #
+    # Sets the target directory and returns self. This will also set the compile task
+    # as a prerequisite to a file task on the target directory.
+    #
+    # For example:
+    #   compile(src_dir).into(target_dir).with(artifacts)
+    # Both compile.invoke and file(target_dir).invoke will compile the source files.
+    def into(path)
+      path = File.expand_path(path.to_s)
+      @target = file(path).enhance([self]) unless @target && @target.to_s == path
+      self
+    end
+
+    # Returns the compiler options.
+    attr_reader :options
+
+    # :call-seq:
+    #   using(options) => self
+    #
+    # Sets the compiler options from a hash and returns self.  Can also be used to
+    # select the compiler.
+    #
+    # For example:
+    #   compile.using(:warnings=>true, :source=>"1.5")
+    #   compile.using(:scala)
+    def using(*args)
+      args.pop.each { |key, value| options.send "#{key}=", value } if Hash === args.last
+      select args.first unless args.empty?
+      self
+    end
+
+    # Returns the compiler if known.  The compiler is either automatically selected
+    # based on existing source directories (e.g. src/main/java), or by requesting
+    # a specific compiler (see #using).
+    attr_reader :compiler
+
+    def select(compiler) #:nodoc:
+      raise "#{compiler.name} already selected for this project" if @compiler
+      @compiler = Compiler.select(compiler.to_s)
+      self
+    end
+
+    def timestamp #:nodoc:
+      # If we compiled successfully, then the target directory reflects that.
+      # If we didn't, see needed?
+      target ? target.timestamp : Rake::EARLY
+    end
+
+    def needed? #:nodoc:
+      return false if source_files.empty?
+      return true unless File.exist?(target.to_s)
+      return true if source_files.any? { |j, c| !File.exist?(c) || File.stat(j).mtime > File.stat(c).mtime }
+      oldest = source_files.map { |j, c| File.stat(c).mtime }.min
+      return dependencies.any? { |path| application[path].timestamp > oldest }
+    end
+
+    def invoke_prerequisites(args, chain) #:nodoc:
+      @prerequisites |= dependencies + sources
+      super
+    end
+
+  private
+
+    # Returns the files to compile. This list is derived from the list of sources,
+    # expanding directories into files, and includes only source files that are
+    # newer than the corresponding class file. Includes all files if one or more
+    # dependency has been updated.
+    def source_files
+      @source_files ||= @sources.map(&:to_s).inject({}) do |map, source|
+        raise "Compile task #{name} has source files, but no target directory" unless target
+        target_dir = target.to_s
+        if File.directory?(source)
+          base = Pathname.new(source)
+          FileList["#{source}/**/*.java"].reject { |file| File.directory?(file) }.
+            each { |file| map[file] = File.join(target_dir, Pathname.new(file).relative_path_from(base).to_s.ext('.class')) }
+        else
+          map[source] = File.join(target_dir, File.basename(source).ext('.class'))
+        end
+        map
+      end
+    end
+
+  end
+
+
+  # The resources task is executed by the compile task to copy resource files over
+  # to the target directory. You can enhance this task in the normal way, but mostly
+  # you will use the task's filter.
+  #
+  # For example:
+  #   resources.filter.using "Copyright"=>"Acme Inc, 2007"
+  class ResourcesTask < Rake::Task
+
+    # Returns the filter used to copy resources over. See Buildr::Filter.
+    attr_reader :filter
+
+    def initialize(*args) #:nodoc:
+      super
+      @filter = Buildr::Filter.new
+      enhance { filter.run unless filter.sources.empty? }
+    end
+
+    # :call-seq:
+    #   include(*files) => self
+    #
+    # Includes the specified files in the filter and returns self.
+    def include(*files)
+      filter.include *files
+      self
+    end
+
+    # :call-seq:
+    #   exclude(*files) => self
+    #
+    # Excludes the specified files in the filter and returns self.
+    def exclude(*files)
+      filter.exclude *files
+      self
+    end
+
+    # :call-seq:
+    #   from(*sources) => self
+    #
+    # Adds additional directories from which to copy resources.
+    #
+    # For example:
+    #   resources.from _("src/etc")
+    def from(*sources)
+      filter.from *sources
+      self
+    end
+
+    # Returns the list of source directories (each being a file task).
+    def sources
+      filter.sources
+    end
+
+    # :call-seq:
+    #   target() => task
+    #
+    # Returns the filter's target directory as a file task.
+    def target
+      filter.target
+    end
+
+    def prerequisites #:nodoc:
+      super + filter.sources.flatten
+    end
+
+  end
+
+end

Added: incubator/buildr/trunk/lib/core/environment.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/environment.rb?rev=606144&view=auto
==============================================================================
--- incubator/buildr/trunk/lib/core/environment.rb (added)
+++ incubator/buildr/trunk/lib/core/environment.rb Fri Dec 21 01:28:05 2007
@@ -0,0 +1,148 @@
+require 'yaml'
+
+
+module Buildr
+
+  # Collection of options for controlling Buildr. For example for running builds without running
+  # test cases, using a proxy server, JVM arguments, etc. You access this object by calling options,
+  # for example:
+  #   options.proxy.http = 'http://proxy.acme.com:8080'
+  #   options.java_args = '-Xmx512M'
+  class Options
+
+    # We use this to present environment variable as arrays.
+    class EnvArray < Array #:nodoc:
+    
+      def initialize(name)
+        @name = name.upcase
+        replace((ENV[@name] || ENV[@name.downcase] || '').split(/\s*,\s*/).reject(&:empty?))
+      end
+
+      (Array.instance_methods - Object.instance_methods - Enumerable.instance_methods).sort.each do |method|
+        class_eval %{def #{method}(*args, &block) ; result = super ; write ; result ; end}
+      end
+
+    private
+
+      def write
+        ENV[@name.downcase] = nil
+        ENV[@name] = map(&:to_s).join(',')
+      end
+
+    end
+
+
+    # Wraps around the proxy environment variables:
+    # * :http -- HTTP_PROXY
+    # * :exclude -- NO_PROXY
+    class Proxies
+
+      # Returns the HTTP_PROXY URL.
+      def http()
+        ENV['HTTP_PROXY'] || ENV['http_proxy']
+      end
+
+      # Sets the HTTP_PROXY URL.
+      def http=(url)
+        ENV['http_proxy'] = nil
+        ENV['HTTP_PROXY'] = url
+      end
+   
+      # Returns list of hosts to exclude from proxying (NO_PROXY). 
+      def exclude()
+        @exclude ||= EnvArray.new('NO_PROXY')
+      end
+
+      # Sets list of hosts to exclude from proxy (NO_PROXY). Accepts host name, array of names,
+      # or nil to clear the list.
+      def exclude=(url)
+        exclude.clear
+        exclude.concat [url].flatten if url
+        exclude
+      end
+
+    end
+
+    # :call-seq:
+    #   proxy() => options
+    #
+    # Returns the proxy options. Currently supported options are:
+    # * :http -- HTTP proxy for use when downloading.
+    # * :exclude -- Do not use proxy for these hosts/domains.
+    #
+    # For example:
+    #   options.proxy.http = "http://proxy.acme.com:8080"
+    # You can also set it using the environment variable HTTP_PROXY.
+    #
+    # You can exclude individual hosts from being proxied, or entire domains, for example:
+    #   options.proxy.exclude = 'optimus'
+    #   options.proxy.exclude = ['optimus', 'prime']
+    #   options.proxy.exclude << '*.internal'
+    def proxy
+      @proxy ||= Proxies.new
+    end
+
+  end
+
+
+  class << self
+
+    # :call-seq:
+    #   options() => Options
+    #
+    # Returns the Buildr options. See Options.
+    def options
+      @options ||= Options.new
+    end
+
+  end
+
+  # :call-seq:
+  #   options() => Options
+  #
+  # Returns the Buildr options. See Options.
+  def options
+    Buildr.options
+  end
+
+  # :call-seq:
+  #   environment() => string or nil
+  #
+  # Returns the environment name.  Use this when your build depends on the environment,
+  # for example, development, production, etc.  The value comes from the BUILDR_ENV environment variable.
+  # 
+  # For example:
+  #   buildr -e production
+  def environment
+    ENV['BUILDR_ENV']
+  end
+
+  # :call-seq:
+  #   environment(env)
+  #
+  # Sets the environment name.
+  def environment=(env)
+    ENV['BUILDR_ENV'] = env
+  end
+
+  # :call-seq:
+  #    profile => hash
+  #
+  # Returns the profile for the current environment.
+  def profile
+    profiles[environment] ||= {}
+  end
+
+  # :call-seq:
+  #    profiles => hash
+  #
+  # Returns all the profiles loaded from the profiles.yaml file.
+  def profiles
+    unless @profiles
+      filename = File.expand_path('profiles.yaml', File.dirname(Rake.application.rakefile))
+      @profiles = File.exist?(filename) ? YAML::load(File.read(filename)) : {}
+    end
+    @profiles
+  end
+
+end

Modified: incubator/buildr/trunk/lib/core/help.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/help.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/help.rb (original)
+++ incubator/buildr/trunk/lib/core/help.rb Fri Dec 21 01:28:05 2007
@@ -64,9 +64,3 @@
   end
 
 end
-
-
-task "projects" do
-  warn_deprecated "Please run help:projects instead."
-  task("help:projects").invoke
-end

Modified: incubator/buildr/trunk/lib/core/project.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/project.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/project.rb (original)
+++ incubator/buildr/trunk/lib/core/project.rb Fri Dec 21 01:28:05 2007
@@ -1,30 +1,15 @@
-require "core/rake_ext"
-require "core/common"
+require 'core/common'
 
 module Buildr
 
-  # An inherited attribute gets its value an accessor with the same name.
-  # But if the value is not set, it will obtain a value from the parent,
-  # so setting the value in the parent make it accessible to all the children
-  # that did not override it.
-  module InheritedAttributes
+  # *Deprecated*
+  module InheritedAttributes #:nodoc:
 
     def self.included(base)
       base.extend(self)
+      warn_deprecated 'InheritedAttributes are deprecated'
     end
 
-    # :call-seq:
-    #    inherited_attr(symbol, default?)
-    #    inherited_attr(symbol) { |obj| ... }
-    #
-    # Defines an inherited attribute. The first form can provide a default value
-    # for the top-level object, used if the attribute was not set. The second form
-    # provides a default value by calling the block.
-    #
-    # For example:
-    #   inherited_attr :version
-    #   inherited_attr :src_dir, "src"
-    #   inherited_attr(:created_on) { Time.now }
     def inherited_attr(symbol, default = nil, &block)
       block ||= proc { default }
       attr_accessor symbol
@@ -92,28 +77,28 @@
   # definition using #project. The order in which you define projects is not important,
   # project definitions are evaluated when you ask for them. Circular dependencies will not
   # work. Rake tasks are only created after the project is evaluated, so if you need to access
-  # a task (e.g. compile) use <code>project("foo").compile</code> instead of <code>task("foo:compile")</code>.
+  # a task (e.g. compile) use <code>project('foo').compile</code> instead of <code>task('foo:compile')</code>.
   #
   # For example:
-  #   define "myapp", :version=>"1.1" do
+  #   define 'myapp', :version=>'1.1' do
   #
-  #     define "wepapp" do
-  #       compile.with project("myapp:beans")
+  #     define 'wepapp' do
+  #       compile.with project('myapp:beans')
   #       package :war
   #     end
   #
-  #     define "beans" do
+  #     define 'beans' do
   #       compile.with DEPENDS
   #       package :jar
   #     end
   #   end
   #
   #   puts projects.map(&:name)
-  #   => [ "myapp", "myapp:beans", "myapp:webapp" ]
-  #   puts project("myapp:webapp").parent.name
-  #   => "myapp"
-  #   puts project("myapp:webapp").compile.classpath.map(&:to_spec)
-  #   => "myapp:myapp-beans:jar:1.1"
+  #   => [ 'myapp', 'myapp:beans', 'myapp:webapp' ]
+  #   puts project('myapp:webapp').parent.name
+  #   => 'myapp'
+  #   puts project('myapp:webapp').compile.classpath.map(&:to_spec)
+  #   => 'myapp:myapp-beans:jar:1.1'
   class Project < Rake::Task
 
     class << self
@@ -126,7 +111,7 @@
         # Make sure a sub-project is only defined within the parent project,
         # to prevent silly mistakes that lead to inconsistencies (e.g.
         # namespaces will be all out of whack).
-        Rake.application.current_scope == name.split(":")[0...-1] or
+        Rake.application.current_scope == name.split(':')[0...-1] or
           raise "You can only define a sub project (#{name}) within the definition of its parent project"
 
         @projects ||= {}
@@ -164,18 +149,18 @@
       def project(*args) #:nodoc:
         options = args.pop if Hash === args.last
         rake_check_options options, :scope if options
-        raise ArgumentError, "Only one project name at a time" unless args.size == 1
+        raise ArgumentError, 'Only one project name at a time' unless args.size == 1
         @projects ||= {}
         name = args.first
         if options && options[:scope]
           # We assume parent project is evaluated.
-          project = options[:scope].split(":").inject([[]]) { |scopes, scope| scopes << (scopes.last + [scope]) }.
-            map { |scope| @projects[(scope + [name]).join(":")] }.
+          project = options[:scope].split(':').inject([[]]) { |scopes, scope| scopes << (scopes.last + [scope]) }.
+            map { |scope| @projects[(scope + [name]).join(':')] }.
             select { |project| project }.last
         end
         unless project
           # Parent project not evaluated.
-          name.split(":").tap { |parts| @projects[parts.first].invoke if parts.size > 1 }
+          name.split(':').tap { |parts| @projects[parts.first].invoke if parts.size > 1 }
           project = @projects[name]
         end
         raise "No such project #{name}" unless project
@@ -207,7 +192,7 @@
           @projects.keys.map { |name| project(name) or raise "No such project #{name}" }.sort_by(&:name)
         else
           # Parent project(s) not evaluated, for the sub-projects we may need to find.
-          names.map { |name| name.split(":") }.select { |name| name.size > 1 }.map(&:first).uniq.each { |name| project(name) }
+          names.map { |name| name.split(':') }.select { |name| name.size > 1 }.map(&:first).uniq.each { |name| project(name) }
           names.uniq.map { |name| project(name) or raise "No such project #{name}" }.sort_by(&:name)
         end
       end
@@ -216,7 +201,7 @@
       #   clear()
       #
       # Discard all project definitions.
-      def clear()
+      def clear
         @projects.clear if @projects
       end
 
@@ -281,13 +266,22 @@
       #   task_in_parent_project(task_name) => task_name or nil
       #
       # Assuming the task name is prefixed with the current project, finds and returns a task with the
-      # same name in a parent project.  Call this with "foo:bar:test" will return "foo:test", but call
-      # this with "foo:test" will return nil.
-      def task_in_parent_project(task_name)
-        namespace = task_name.split(":")
+      # same name in a parent project.  Call this with 'foo:bar:test' will return 'foo:test', but call
+      # this with 'foo:test' will return nil.
+      def task_in_parent_project(task_name) #:nodoc:
+        namespace = task_name.split(':')
         last_name = namespace.pop
         namespace.pop
-        Rake.application.lookup((namespace + [last_name]).join(":"), []) unless namespace.empty?
+        Rake.application.lookup((namespace + [last_name]).join(':'), []) unless namespace.empty?
+      end
+
+      # :call-seq:
+      #   project_from_task(task) => project
+      #
+      # Figure out project associated to this task and return it.
+      def project_from_task(task) #:nodoc:
+        project = Rake.application.lookup('rake:' + task.to_s.gsub(/:[^:]*$/, ''))
+        project if Project === project
       end
 
       # Callback classes.
@@ -297,9 +291,8 @@
 
     end
 
-    include InheritedAttributes
 
-    # The project name. For example, "foo" for the top-level project, and "foo:bar"
+    # The project name. For example, 'foo' for the top-level project, and 'foo:bar'
     # for its sub-project.
     attr_reader :name
 
@@ -308,12 +301,12 @@
 
     def initialize(*args) #:nodoc:
       super
-      split = name.split(":")
+      split = name.split(':')
       if split.size > 1
         # Get parent project, but do not invoke it's definition to prevent circular
         # dependencies (it's being invoked right now, so calling project() will fail).
-        @parent = task(split[0...-1].join(":"))
-        raise "No parent project #{split[0...-1].join(":")}" unless @parent && Project === parent
+        @parent = task(split[0...-1].join(':'))
+        raise "No parent project #{split[0...-1].join(':')}" unless @parent && Project === parent
       end
       callbacks = Project.callbacks.uniq.map(&:new)
       @callbacks = [:before_define, :after_define].inject({}) do |hash, state|
@@ -332,15 +325,15 @@
     # a base directory that is one level down, with the same name as the sub-project.
     #
     # For example:
-    #   /home/foo/          <-- base_directory of project "foo"
-    #   /home/foo/Buildfile <-- builds "foo"
-    #   /home/foo/bar       <-- sub-project "foo:bar"
-    def base_dir()
+    #   /home/foo/          <-- base_directory of project 'foo'
+    #   /home/foo/Buildfile <-- builds 'foo'
+    #   /home/foo/bar       <-- sub-project 'foo:bar'
+    def base_dir
       if @base_dir.nil?
         if parent
           # For sub-project, a good default is a directory in the parent's base_dir,
           # using the same name as the project.
-          @base_dir = File.join(parent.base_dir, name.split(":").last)
+          @base_dir = File.join(parent.base_dir, name.split(':').last)
         else
           # For top-level project, a good default is the directory where we found the Buildfile.
           @base_dir = Dir.pwd
@@ -350,22 +343,6 @@
     end
 
     # :call-seq:
-    #   base_dir = dir
-    #
-    # Sets the project's base directory. Allows you to specify a base directory by calling
-    # this accessor, or with the :base_dir property when calling #define.
-    #
-    # You can only set the base directory once for a given project, and only before accessing
-    # the base directory (for example, by calling #file or #path_to).
-    # Set the base directory. Note: you can only do this once for a project,
-    # and only before accessing the base directory. If you try reading the
-    # value with #base_dir, the base directory cannot be set again.
-    def base_dir=(dir)
-      raise "Cannot set base directory twice, or after reading its value" if @base_dir
-      @base_dir = File.expand_path(dir)
-    end
-
-    # :call-seq:
     #   path_to(*names) => path
     #
     # Returns a path from a combination of name, relative to the project's base directory.
@@ -376,11 +353,11 @@
     # so you want to use #path_to to get the actual path within the project as a matter of practice.
     #
     # For example:
-    #   path_to("foo", "bar")
+    #   path_to('foo', 'bar')
     #   => /home/project1/foo/bar
-    #   path_to("/tmp")
+    #   path_to('/tmp')
     #   => /tmp
-    #   path_to(:base_dir, "foo") # same as path_to("foo")
+    #   path_to(:base_dir, 'foo') # same as path_to('foo")
     #   => /home/project1/foo
     def path_to(*names)
       File.expand_path(File.join(names.map { |name| Symbol === name ? send(name) : name.to_s }), base_dir)
@@ -388,53 +365,6 @@
     alias :_ :path_to
 
     # :call-seq:
-    #   define(name, properties?) { |project| ... } => project
-    #
-    # Define a new sub-project within this project. See Buildr#define.
-    def define(name, properties = nil, &block)
-      Project.define "#{self.name}:#{name}", properties, &block
-    end
-
-    # :call-seq:
-    #   project(name) => project
-    #   project => self
-    #
-    # Same as Buildr#project. This method is called on a project, so a relative name is
-    # sufficient to find a sub-project.
-    #
-    # When called on a project without a name, returns the project itself. You can use that when
-    # setting project properties, for example:
-    #   define "foo" do
-    #     project.version = "1.0"
-    #   end
-    def project(*args)
-      if Hash === args.last
-        options = args.pop
-      else
-        options = {}
-      end
-      if args.empty?
-        self
-      else
-        Project.project *(args + [{ :scope=>self.name }.merge(options)])
-      end
-    end
-
-    # :call-seq:
-    #   projects(*names) => projects
-    #
-    # Same as Buildr#projects. This method is called on a project, so relative names are
-    # sufficient to find sub-projects.
-    def projects(*args)
-      if Hash === args.last
-        options = args.pop
-      else
-        options = {}
-      end
-      Project.projects *(args + [{ :scope=>self.name }.merge(options)])
-    end
-
-    # :call-seq:
     #   file(path) => Task
     #   file(path=>prereqs) => Task
     #   file(path) { |task| ... } => Task
@@ -444,18 +374,19 @@
     # and the task executes in the project's base directory.
     #
     # For example:
-    #   define "foo" do
-    #     define "bar" do
-    #       file("src") { ... }
+    #   define 'foo' do
+    #     define 'bar' do
+    #       file('src') { ... }
     #     end
     #   end
     #
-    #   puts project("foo:bar").file("src").to_s
-    #   => "/home/foo/bar/src"
-    def file(args, &block)
-      task_name, deps = Rake.application.resolve_args(args)
-      deps = [deps] unless deps.respond_to?(:to_ary)
-      Rake::FileTask.define_task(path_to(task_name)=>deps, &block)
+    #   puts project('foo:bar').file('src').to_s
+    #   => '/home/foo/bar/src'
+    def file(*args, &block)
+      task_name, arg_names, deps = Rake.application.resolve_args(args)
+      task = Rake::FileTask.define_task(path_to(task_name))
+      task.set_arg_names(arg_names) unless arg_names.empty?
+      task.enhance Array(deps), &block
     end
 
     # :call-seq:
@@ -468,12 +399,12 @@
     # in the project's base directory.
     #
     # For example:
-    #   define "foo" do
-    #     task "doda"
+    #   define 'foo' do
+    #     task 'doda'
     #   end
     #
-    #   puts project("foo").task("doda").name
-    #   => "foo:doda"
+    #   puts project('foo').task('doda').name
+    #   => 'foo:doda'
     #
     # When called from within the project definition, creates a new task if the task
     # does not already exist. If called from outside the project definition, returns
@@ -481,28 +412,26 @@
     #
     # As with Rake's task method, calling this method enhances the task with the
     # prerequisites and optional block.
-    def task(args, &block)
-      task_name, deps = Rake.application.resolve_args(args)
+    def task(*args, &block)
+      task_name, arg_names, deps = Rake.application.resolve_args(args)
       if task_name =~ /^:/
         Rake.application.instance_eval do
           scope, @scope = @scope, []
           begin
-            Rake::Task.define_task(task_name[1..-1]=>deps, &block)
+            task = Rake::Task.define_task(task_name[1..-1])
           ensure
             @scope = scope
           end
         end
-      elsif Rake.application.current_scope == name.split(":")
-        Rake::Task.define_task(task_name=>deps, &block)
+      elsif Rake.application.current_scope == name.split(':')
+        task = Rake::Task.define_task(task_name)
       else
-        if task = Rake.application.lookup(task_name, name.split(":"))
-          deps = [deps] unless deps.respond_to?(:to_ary)
-          task.enhance deps, &block
-        else
-          full_name = "#{name}:#{task_name}"
-          raise "You cannot define a project task outside the project definition, and no task #{full_name} defined in the project"
+        unless task = Rake.application.lookup(task_name, name.split(':'))
+          raise "You cannot define a project task outside the project definition, and no task #{name}:#{task_name} defined in the project"
         end
       end
+      task.set_arg_names(arg_names) unless arg_names.empty?
+      task.enhance Array(deps), &block
     end
 
     # :call-seq:
@@ -510,23 +439,94 @@
     #
     # Define a recursive task. A recursive task executes itself and the same task
     # in all the sub-projects.
-    def recursive_task(args, &block)
-      task_name, deps = Rake.application.resolve_args(args)
-      deps = [deps] unless deps.respond_to?(:to_ary)
+    def recursive_task(*args, &block)
+      task_name, arg_names, deps = Rake.application.resolve_args(args)
       task = Buildr.options.parallel ? multitask(task_name) : task(task_name)
       parent.task(task_name).enhance [task] if parent
-      task.enhance deps, &block
+      task.set_arg_names(arg_names) unless arg_names.empty?
+      task.enhance Array(deps), &block
     end
 
-    def execute() #:nodoc:
-      # Reset the namespace, so all tasks are automatically defined in the project's namespace.
-      Rake.application.in_namespace(":#{name}") { super }
+    # :call-seq:
+    #   project(name) => project
+    #   project => self
+    #
+    # Same as Buildr#project. This method is called on a project, so a relative name is
+    # sufficient to find a sub-project.
+    #
+    # When called on a project without a name, returns the project itself. You can use that when
+    # setting project properties, for example:
+    #   define 'foo' do
+    #     project.version = '1.0'
+    #   end
+    def project(*args)
+      if Hash === args.last
+        options = args.pop
+      else
+        options = {}
+      end
+      if args.empty?
+        self
+      else
+        Project.project *(args + [{ :scope=>self.name }.merge(options)])
+      end
+    end
+
+    # :call-seq:
+    #   projects(*names) => projects
+    #
+    # Same as Buildr#projects. This method is called on a project, so relative names are
+    # sufficient to find sub-projects.
+    def projects(*args)
+      if Hash === args.last
+        options = args.pop
+      else
+        options = {}
+      end
+      Project.projects *(args + [{ :scope=>self.name }.merge(options)])
     end
 
-    def inspect() #:nodoc:
+    def inspect #:nodoc:
       %Q{project(#{name.inspect})}
     end
 
+protected
+
+    # :call-seq:
+    #   base_dir = dir
+    #
+    # Sets the project's base directory. Allows you to specify a base directory by calling
+    # this accessor, or with the :base_dir property when calling #define.
+    #
+    # You can only set the base directory once for a given project, and only before accessing
+    # the base directory (for example, by calling #file or #path_to).
+    # Set the base directory. Note: you can only do this once for a project,
+    # and only before accessing the base directory. If you try reading the
+    # value with #base_dir, the base directory cannot be set again.
+    def base_dir=(dir)
+      raise 'Cannot set base directory twice, or after reading its value' if @base_dir
+      @base_dir = File.expand_path(dir)
+    end
+
+    # :call-seq:
+    #   define(name, properties?) { |project| ... } => project
+    #
+    # Define a new sub-project within this project. See Buildr#define.
+    def define(name, properties = nil, &block)
+      Project.define "#{self.name}:#{name}", properties, &block
+    end
+
+    def execute(args) #:nodoc:
+      begin
+        # Reset the namespace, so all tasks are automatically defined in the project's namespace.
+        scope = Rake.application.current_scope
+        Rake.application.instance_variable_set :@scope, name.split(':')
+        super
+      ensure
+        Rake.application.instance_variable_set :@scope, scope
+      end
+    end
+
   private
 
     # Call all callbacks for a particular state, e.g. :before_define, :after_define.
@@ -582,7 +582,7 @@
   #     before_define do |project|
   #       # Define the loc task for this particular project.
   #       define_task 'loc' do |task|
-  #         lines = task.prerequisites.map { |path| Dir["#{path}/**/*"] }.flatten.uniq.
+  #         lines = task.prerequisites.map { |path| Dir['#{path}/**/*'] }.flatten.uniq.
   #           inject(0) { |total, file| total + File.readlines(file).count }
   #         puts "Project #{project.name} has #{lines} lines of code"
   #       end
@@ -683,17 +683,17 @@
   # related to the project.
   #
   # For example:
-  #   define "foo", :version=>"1.0" do
+  #   define 'foo', :version=>'1.0' do
   #
-  #     define "bar" do
-  #       compile.with "org.apache.axis2:axis2:jar:1.1"
+  #     define 'bar' do
+  #       compile.with 'org.apache.axis2:axis2:jar:1.1'
   #     end
   #   end
   #
-  #   puts project("foo").version
-  #   => "1.0"
-  #   puts project("foo:bar").compile.classpath.map(&:to_spec)
-  #   => "org.apache.axis2:axis2:jar:1.1"
+  #   puts project('foo').version
+  #   => '1.0'
+  #   puts project('foo:bar').compile.classpath.map(&:to_spec)
+  #   => 'org.apache.axis2:axis2:jar:1.1'
   #   % buildr build
   #   => Compiling 14 source files in foo:bar
   def define(name, properties = nil, &block) #:yields:project
@@ -706,9 +706,9 @@
   # Returns a project definition.
   #
   # When called from outside a project definition, must reference the project by its
-  # full name, e.g. "foo:bar" to access the sub-project "bar" in "foo". When called
-  # from inside a project, relative names are sufficient, e.g. <code>project("foo").project("bar")</code>
-  # will find the sub-project "bar" in "foo".
+  # full name, e.g. 'foo:bar' to access the sub-project 'bar' in 'foo'. When called
+  # from inside a project, relative names are sufficient, e.g. <code>project('foo').project('bar')</code>
+  # will find the sub-project 'bar' in 'foo'.
   #
   # You cannot reference a project before the project is defined. When working with
   # sub-projects, the project definition is stored by calling #define, and evaluated
@@ -720,21 +720,21 @@
   # or packages created by that project).
   #
   # For example:
-  #   define "myapp" do
-  #     self.version = "1.1"
+  #   define 'myapp' do
+  #     self.version = '1.1'
   #
-  #     define "webapp" do
+  #     define 'webapp' do
   #       # webapp is defined first, but beans is evaluated first
-  #       compile.with project("beans")
+  #       compile.with project('beans')
   #       package :war
   #     end
   #
-  #     define "beans" do
+  #     define 'beans' do
   #       package :jar
   #     end
   #   end
   #
-  #   puts project("myapp:beans").version
+  #   puts project('myapp:beans').version
   def project(*args)
     Project.project *args
   end
@@ -752,20 +752,22 @@
   # Be advised of circular dependencies.
   #
   # For example:
-  #   files = projects.map { |prj| FileList[prj.path_to("src/**/*.java") }.flatten
+  #   files = projects.map { |prj| FileList[prj.path_to('src/**/*.java') }.flatten
   #   puts "There are #{files.size} source files in #{projects.size} projects"
   #
-  #   puts projects("myapp:beans", "myapp:webapp").map(&:name)
+  #   puts projects('myapp:beans', 'myapp:webapp').map(&:name)
   # Same as:
-  #   puts project("myapp").projects.map(&:name)
+  #   puts project('myapp').projects.map(&:name)
   def projects(*args)
     Project.projects *args
   end
 
   # Forces all the projects to be evaluated before executing any other task.
   # If we don't do that, we don't get to have tasks available when running Rake.
-  task "buildr:initialize" do
-    projects
+  namespace 'buildr' do
+    task 'initialize' do
+      projects
+    end
   end
 
 end

Modified: incubator/buildr/trunk/lib/java/compile.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/compile.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/compile.rb (original)
+++ incubator/buildr/trunk/lib/java/compile.rb Fri Dec 21 01:28:05 2007
@@ -211,12 +211,9 @@
         return classpath.any? { |path| application[path].timestamp > oldest }
       end
 
-      def prerequisites() #:nodoc:
-        super + classpath + sources
-      end
-
-      def invoke_prerequisites() #:nodoc:
-        prerequisites.each { |n| application[n, @scope].invoke }
+      def invoke_prerequisites(args, chain) #:nodoc:
+        @prerequisites |= classpath + sources
+        super
       end
 
       # Returns the files to compile. This list is derived from the list of sources,
@@ -241,79 +238,6 @@
     end
 
  
-    # The resources task is executed by the compile task to copy resource files over
-    # to the target directory. You can enhance this task in the normal way, but mostly
-    # you will use the task's filter.
-    #
-    # For example:
-    #   resources.filter.using "Copyright"=>"Acme Inc, 2007"
-    class ResourcesTask < Rake::Task
-
-      # Returns the filter used to copy resources over. See Buildr::Filter.
-      attr_reader :filter
-
-      def initialize(*args) #:nodoc:
-        super
-        @filter = Buildr::Filter.new
-        enhance { filter.run unless filter.sources.empty? }
-      end
-
-      # :call-seq:
-      #   include(*files) => self
-      #
-      # Includes the specified files in the filter and returns self.
-      def include(*files)
-        filter.include *files
-        self
-      end
-
-      # :call-seq:
-      #   exclude(*files) => self
-      #
-      # Excludes the specified files in the filter and returns self.
-      def exclude(*files)
-        filter.exclude *files
-        self
-      end
-
-      # :call-seq:
-      #   from(*sources) => self
-      #
-      # Adds additional directories from which to copy resources.
-      #
-      # For example:
-      #   resources.from _("src/etc")
-      def from(*sources)
-        filter.from *sources
-        self
-      end
-
-      # *Deprecated* Use #sources instead.
-      def source()
-        warn_deprecated "Please use sources instead."
-        filter.source
-      end
-
-      # Returns the list of source directories (each being a file task).
-      def sources()
-        filter.sources
-      end
-
-      # :call-seq:
-      #   target() => task
-      #
-      # Returns the filter's target directory as a file task.
-      def target()
-        filter.target
-      end
-
-      def prerequisites() #:nodoc:
-        super + filter.sources.flatten
-      end
-
-    end
-
-
     # A convenient task for creating Javadocs from the project's compile task. Minimizes all
     # the hard work to calling #from and #using.
     #
@@ -470,13 +394,13 @@
       before_define do |project|
         prepare = task("prepare")
         # Resources task is a filter.
-        resources = Java::ResourcesTask.define_task("resources")
+        resources = ResourcesTask.define_task("resources")
         project.path_to("src/main/resources").tap { |dir| resources.from dir if File.exist?(dir) }
         # Compile task requires prepare and performs resources, if anything compiled.
-        compile = Java::CompileTask.define_task("compile"=>[prepare, resources])
+        compile = Buildr::CompileTask.define_task("compile"=>[prepare, resources])
         project.path_to("src/main/java").tap { |dir| compile.from dir if File.exist?(dir) }
         compile.into project.path_to(:target, "classes")
-        resources.filter.into project.compile.target
+        resources.filter.into project.path_to(:target, "resources")
         Java::JavadocTask.define_task("javadoc"=>prepare).tap do |javadoc|
           javadoc.into project.path_to(:target, "javadoc")
           javadoc.using :windowtitle=>project.comment || project.name

Modified: incubator/buildr/trunk/lib/java/packaging.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/packaging.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/packaging.rb (original)
+++ incubator/buildr/trunk/lib/java/packaging.rb Fri Dec 21 01:28:05 2007
@@ -13,9 +13,6 @@
     # Methods added to Project to support packaging.
     module Packaging
 
-      include InheritedAttributes
-
-
       # Adds support for MANIFEST.MF and other META-INF files.
       module WithManifest #:nodoc:
 

Modified: incubator/buildr/trunk/lib/java/test.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/test.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/test.rb (original)
+++ incubator/buildr/trunk/lib/java/test.rb Fri Dec 21 01:28:05 2007
@@ -164,7 +164,7 @@
         enhance { run_tests }
       end
 
-      def execute() #:nodoc:
+      def execute(args) #:nodoc:
         setup.invoke
         begin
           super
@@ -591,7 +591,7 @@
       end
     end
 
-    def execute() #:nodoc:
+    def execute(args) #:nodoc:
       setup.invoke
       begin
         super
@@ -663,7 +663,7 @@
       # Anything that comes after local packaging (install, deploy) executes the integration tests,
       # which do not conflict with integration invoking the project's own packaging (package=>
       # integration=>foo:package is not circular, just confusing to debug.)
-      task "package" do |task|
+      task "package" do
         task("integration").invoke if Buildr.options.test && Rake.application.original_dir == Dir.pwd
       end
     end
@@ -674,13 +674,13 @@
       project.test.instance_eval { instance_variable_set :@project, project }
       #project.recursive_task("test")
       # Similar to the regular resources task but using different paths.
-      resources = Java::ResourcesTask.define_task("test:resources")
+      resources = ResourcesTask.define_task("test:resources")
       project.path_to("src/test/resources").tap { |dir| resources.from dir if File.exist?(dir) }
       # Similar to the regular compile task but using different paths.
       compile = Java::CompileTask.define_task("test:compile"=>[project.compile, task("test:prepare"), project.test.resources])
       project.path_to("src/test/java").tap { |dir| compile.from dir if File.exist?(dir) }
       compile.into project.path_to(:target, "test-classes")
-      resources.filter.into compile.target
+      resources.filter.into project.path_to(:target, "test-resources")
       project.test.enhance [compile]
       # Define the JUnit task here, otherwise we get a normal task.
       Java::JUnitTask.define_task("test:junit")

Modified: incubator/buildr/trunk/lib/tasks/concat.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/tasks/concat.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/tasks/concat.rb (original)
+++ incubator/buildr/trunk/lib/tasks/concat.rb Fri Dec 21 01:28:05 2007
@@ -28,8 +28,8 @@
   # For example:
   #   concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
   def concat(args)
-    file, deps = Rake.application.resolve_args(args)
-    ConcatTask.define_task File.expand_path(file)=>deps
+    file, arg_names, deps = Rake.application.resolve_args([args])
+    ConcatTask.define_task(File.expand_path(file)=>deps)
   end
 
 end

Modified: incubator/buildr/trunk/lib/tasks/zip.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/tasks/zip.rb?rev=606144&r1=606143&r2=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/tasks/zip.rb (original)
+++ incubator/buildr/trunk/lib/tasks/zip.rb Fri Dec 21 01:28:05 2007
@@ -345,7 +345,7 @@
       self
     end
 
-    def invoke_prerequisites() #:nodoc:
+    def invoke_prerequisites(args, chain) #:nodoc:
       @prepares.each { |prepare| prepare.call(self) }
       @prepares.clear
       @prerequisites |= @paths.collect { |name, path| path.sources }.flatten
@@ -467,7 +467,7 @@
 
     # Initialize with hash argument of the form target=>zip_file.
     def initialize(args)
-      @target, @zip_file = Rake.application.resolve_args(args)
+      @target, arg_names, @zip_file = Rake.application.resolve_args([args])
       @paths = {}
     end
 
@@ -647,7 +647,7 @@
   #   unzip("src"=>"test.zip").include("README", "LICENSE") 
   #   unzip("libs"=>"test.zip").from_path("libs")
   def unzip(args)
-    target, zip_file = Rake.application.resolve_args(args)
+    target, arg_names, zip_file = Rake.application.resolve_args([args])
     task = file(File.expand_path(target.to_s)=>zip_file)
     Unzip.new(task=>zip_file).tap do |setup|
       task.enhance { setup.extract }

Copied: incubator/buildr/trunk/spec/common_spec.rb (from r605377, incubator/buildr/trunk/test/common.rb)
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/common_spec.rb?p2=incubator/buildr/trunk/spec/common_spec.rb&p1=incubator/buildr/trunk/test/common.rb&r1=605377&r2=606144&rev=606144&view=diff
==============================================================================
--- incubator/buildr/trunk/test/common.rb (original)
+++ incubator/buildr/trunk/spec/common_spec.rb Fri Dec 21 01:28:05 2007
@@ -532,3 +532,41 @@
     props.split("\n").should include("name3=double\\\\hash")
   end
 end
+
+
+describe Buildr, 'profiles' do
+  before :each do
+    Rake.application.instance_eval { @rakefile = File.expand_path('buildfile') }
+  end
+
+  it 'should return empty hash if no profiles file' do
+    Buildr.profiles.should == {}
+  end
+
+  it 'should load profiles from YAML file' do
+    write 'profiles.yaml', <<-YAML
+dev:
+  foo: bar
+test:
+  bar: baz
+    YAML
+    Buildr.profiles.should == { 'dev'=> { 'foo'=>'bar' }, 'test'=>{ 'bar'=>'baz' } }
+  end
+end
+
+
+describe Buildr, 'profile' do
+  before :each do
+    Rake.application.instance_eval { @rakefile = File.expand_path('buildfile') }
+  end
+
+  it 'should return profile for current environment' do
+    Buildr.environment = 'qa'
+    Buildr.profiles['qa'] = { 'foo'=>'bar' }
+    Buildr.profile.should == { 'foo'=>'bar' }
+  end
+
+  it 'should return empty hash if no proflie available' do
+    Buildr.profile.should == {}
+  end
+end