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 2008/01/08 08:22:42 UTC

svn commit: r609893 - in /incubator/buildr/trunk: lib/core/compile.rb lib/core/project.rb lib/core/test.rb lib/java/compilers.rb spec/compile_spec.rb spec/java_compilers.rb spec/packaging_spec.rb

Author: assaf
Date: Mon Jan  7 23:22:41 2008
New Revision: 609893

URL: http://svn.apache.org/viewvc?rev=609893&view=rev
Log:
Finalized compiler API (for the n-th time)

Modified:
    incubator/buildr/trunk/lib/core/compile.rb
    incubator/buildr/trunk/lib/core/project.rb
    incubator/buildr/trunk/lib/core/test.rb
    incubator/buildr/trunk/lib/java/compilers.rb
    incubator/buildr/trunk/spec/compile_spec.rb
    incubator/buildr/trunk/spec/java_compilers.rb
    incubator/buildr/trunk/spec/packaging_spec.rb

Modified: incubator/buildr/trunk/lib/core/compile.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/compile.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/compile.rb (original)
+++ incubator/buildr/trunk/lib/core/compile.rb Mon Jan  7 23:22:41 2008
@@ -16,15 +16,7 @@
 
       # Select a compiler by its name.
       def select(name)
-        @compilers[name.to_sym] or raise ArgumentError, "No #{name} compiler available. Did you install it?"
-      end
-
-      # Identify which compiler applies based on one of two arguments:
-      # * :sources -- List of source directories, attempts to find applicable files there (e.g. Java source files).
-      # * :source -- The source directory (src/main, src/test), from which it will look up a particular source
-      #     directory (e.g. src/main/java).
-      def identify(from)
-        @compilers.values.detect { |compiler| compiler.identify?(from) }
+        @compilers[name.to_sym]
       end
 
       # Adds a compiler to the list of supported compiler.
@@ -32,8 +24,7 @@
       # For example:
       #   Buildr::Compiler.add Buildr::Javac
       def add(compiler)
-        compiler = compiler.new if Class === compiler
-        @compilers[compiler.name.to_sym] = compiler
+        @compilers[compiler.to_sym] = compiler
       end
 
       # Returns a list of available compilers.
@@ -50,45 +41,93 @@
     # (see Javac as an example).
     class Base #:nodoc:
 
-      def initialize(args = {})
-        args[:name] ||= self.class.name.split('::').last.downcase.to_sym
-        args[:language] ||= args[:name]
-        args[:source_path] ||= args[:language].to_s
-        args[:source_ext] ||= ".#{args[:language]}"
-        args.each { |name, value| instance_variable_set "@#{name}", value }
-      end
-
-      # Compiler name (e.g. :javac).
-      attr_reader :name
-      # Compiled language (e.g. :java).
-      attr_reader :language
-      # Common path for source files (e.g. 'java').
-      attr_reader :source_path
-      # Extension for source files (e.g. '.java').
-      attr_reader :source_ext
-      # Common path for target files (e.g. 'classes').
-      attr_reader :target_path
-      # Extension for target files (e.g. '.class').
-      attr_reader :target_ext
-      # The default packaging type (e.g. :jar).
-      attr_reader :packaging
-
-      # Used by Compiler.identify to determine if this compiler applies to the current project.
-      # The default implementation looks for either the supplied source directories, or the
-      # #source_path directory, depending on arguments, for files with #source_ext extension.
-      def identify?(from)
-        paths = from[:sources] || Array(File.join(from[:source], source_path))
-        !Dir[*paths.map { |path| File.join(path, "**/*#{source_ext}") }].empty?
-      end
-
-      # Once selected, this method is called to configured the task for this compiler.
-      # You can extend this to set up common source directories, the target directory,
-      # default compiler options, etc.  The default implementation adds the source directory
-      # from {source}/{source_path} and sets the target directory to {target}/{target_path}
-      # if not already set.
-      def configure(task, source, target)
-        task.from File.join(source, source_path) if task.sources.empty? && File.exist?(File.join(source, source_path))
-        task.into File.join(target, target_path) unless task.target
+      class << self
+
+        # The compiler's identifier (e.g. :javac).  Inferred from the class name.
+        def to_sym
+          @symbol
+        end
+
+        # The compiled language (e.g. :java).
+        attr_reader :language
+        # Source directories to use if none were specified (e.g. 'java').  Defaults to #language.
+        attr_reader :sources
+        # Extension for source files (e.g. 'java').  Defaults to language.
+        attr_reader :source_ext
+        # The target path (e.g. 'classes')
+        attr_reader :target
+        # Extension for target files (e.g. 'class').
+        attr_reader :target_ext
+        # The default packaging type (e.g. :jar).
+        attr_reader :packaging
+        # Options to inherit from parent task.  Defaults to value of OPTIONS constant.
+        attr_reader :inherit_options
+
+        # Returns true if this compiler applies to any source code found in the listed source
+        # directories.  For example, Javac returns true if any of the source directories contains
+        # a .java file.  The default implementation looks to see if there are any files in the
+        # specified path with the extension #source_ext.
+        def applies_to?(paths)
+          paths.any? { |path| !Dir["#{path}/**/*.#{source_ext}"].empty? }
+        end
+
+        # Implementations can use this method to specify various compiler attributes.
+        # For example:
+        #   specify :language=>:java, :target=>'classes', :target_ext=>'class', :packaging=>:jar
+        def specify(attrs)
+          attrs[:symbol] ||= name.split('::').last.downcase.to_sym
+          attrs[:sources] ||= attrs[:language].to_s
+          attrs[:source_ext] ||= attrs[:language].to_s
+          attrs[:inherit_options] ||= const_get('OPTIONS').clone rescue []
+          attrs.each { |name, value| instance_variable_set("@#{name}", value) }
+        end
+
+      end
+
+      # Construct a new compiler with the specified options.  Note that options may
+      # changed before the compiler is run.
+      def initialize(options)
+        @options = options
+      end
+
+      # Options for this compiler.
+      attr_reader :options
+
+      # Determines if the compiler needs to run by checking if the target files exist,
+      # and if any source files or dependencies are newer than corresponding target files.
+      def needed?(sources, target, dependencies)
+        map = compile_map(sources, target)
+        return false if map.empty?
+        return true unless File.exist?(target.to_s)
+        return true if map.any? { |source, target| !File.exist?(target) || File.stat(source).mtime > File.stat(target).mtime }
+        oldest = map.map { |source, target| File.stat(target).mtime }.min
+        return dependencies.any? { |path| file(path).timestamp > oldest }
+      end
+
+      # Compile all files lists in sources (files and directories) into target using the
+      # specified dependencies.
+      def compile(sources, target, dependencies)
+        raise 'Not implemented'
+      end
+
+    private
+
+      # Use this to complain about CompileTask options not supported by this compiler.
+      #
+      # For example:
+      #   def compile(files, task)
+      #     check_options task, OPTIONS
+      #     . . .
+      #   end
+      def check_options(options, *supported)
+        unsupported = options.to_hash.keys - supported.flatten
+        raise ArgumentError, "No such option: #{unsupported.join(' ')}" unless unsupported.empty?
+      end
+
+      # Expands a list of source directories/files into a list of files that have the #source_ext extension.
+      def files_from_sources(sources)
+        sources.map { |source| File.directory?(source) ? FileList["#{source}/**/*.#{self.class.source_ext}"] : source }.
+          flatten.reject { |file| File.directory?(file) }.uniq
       end
 
       # The compile map is a hash that associates source files with target files based
@@ -97,47 +136,19 @@
       # The default method maps all files in the source directories with #source_ext into
       # paths in the target directory with #target_ext (e.g. 'source/foo.java'=>'target/foo.class').
       def compile_map(sources, target)
+        source_ext = self.class.source_ext
+        target_ext = self.class.target_ext
         sources.inject({}) do |map, source|
           if File.directory?(source)
             base = Pathname.new(source)
-            FileList["#{source}/**/*#{source_ext}"].reject { |file| File.directory?(file) }.
+            FileList["#{source}/**/*.#{source_ext}"].reject { |file| File.directory?(file) }.
               each { |file| map[file] = File.join(target, Pathname.new(file).relative_path_from(base).to_s.ext(target_ext)) }
           else
             map[source] = File.join(target, File.basename(source).ext(target_ext))
           end
           map
         end
-      end
-
-    private
-
-      # Use this to copy options used by this compiler from the parent, for example,
-      # if this task is 'foo:bar:compile', copy options set in the parent task 'foo:compile'.
-      #
-      # For example:
-      #   def configure(task, source, target)
-      #     super
-      #     update_options_from_parent! task, OPTIONS
-      #     . . .
-      #   end
-      def update_options_from_parent!(task, supported)
-        parent = Project.task_in_parent_project(task.name)
-        if parent.respond_to?(:options)
-          missing = supported.flatten - task.options.to_hash.keys
-          missing.each { |option| task.options[option] = parent.options[option] }
-        end
-      end
 
-      # Use this to complain about CompileTask options not supported by this compiler.
-      #
-      # For example:
-      #   def compile(files, task)
-      #     check_options task, OPTIONS
-      #     . . .
-      #   end
-      def check_options(task, supported)
-        unsupported = task.options.to_hash.keys - supported.flatten
-        raise ArgumentError, "No such option: #{unsupported.join(' ')}" unless unsupported.empty?
       end
 
     end
@@ -173,21 +184,18 @@
 
     def initialize(*args) #:nodoc:
       super
-      parent = Project.task_in_parent_project(name)
+      @parent_task = Project.parent_task(name)
       @options = OpenObject.new
-      @sources = []
-      @dependencies = []
+      @sources = FileList[]
+      @dependencies = FileList[]
 
       enhance do |task|
         unless sources.empty?
           raise 'No compiler selected and can\'t determine which compiler to use' unless compiler
           raise 'No target directory specified' unless target
           mkpath target.to_s, :verbose=>false
-          files = compile_map.keys
-          unless files.empty?
-            puts "Compiling #{files.size} source files in #{task.name}" if verbose
-            @compiler.compile(files, task)
-          end
+          puts "Compiling #{task.name}" if verbose
+          @compiler.compile(sources.map(&:to_s), target.to_s, dependencies.map(&:to_s))
           # 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
@@ -279,18 +287,21 @@
     # based on existing source directories (e.g. src/main/java), or by requesting
     # a specific compiler (see #using).
     def compiler
-      self.compiler = Compiler.identify(:sources=>sources) unless sources.empty? || @compiler
-      @compiler && @compiler.name
+      unless @compiler
+        candidate = Compiler.compilers.detect { |cls| cls.applies_to?(sources) }
+        self.compiler = candidate if candidate
+      end
+      @compiler && @compiler.class.to_sym
     end
 
     # Returns the compiled language, if known.  See also #compiler.
     def language
-      compiler && @compiler.language
+      compiler && @compiler.class.language
     end
 
     # Returns the default packaging type for this compiler, if known.
     def packaging
-      compiler && @compiler.packaging
+      compiler && @compiler.class.packaging
     end
 
     def timestamp #:nodoc:
@@ -301,47 +312,46 @@
 
   protected
 
+    attr_reader :project
+
     # Selects which compiler to use.
-    def compiler=(compiler) #:nodoc:
-      return self unless compiler
-      compiler = Compiler.select(compiler) unless Compiler::Base === compiler
-      unless @compiler == compiler
-        raise "#{@compiler} compiler already selected for this project" if @compiler
-        @compiler = compiler
-        @compiler.configure(self, @associate[:source], @associate[:target])
-      end
+    def compiler=(name) #:nodoc:
+      raise "#{compiler} compiler already selected for this project" if @compiler
+      cls = Compiler.select(name) or raise ArgumentError, "No #{name} compiler available. Did you install it?"
+      cls.inherit_options.reject { |name| options.has_key?(name) }.
+        each { |name| options[name] = @parent_task.options[name] } if @parent_task.respond_to?(:options)
+      @compiler = cls.new(options)
+      from Array(cls.sources).map { |path| @project.path_to(:source, @usage, path) }.
+        select { |path| File.exist?(path) } if sources.empty?
+      into @project.path_to(:target, @usage, cls.target) unless target
       self
     end
 
-    def associate(source, target) #:nodoc:
-      @associate = { :source=>source, :target=>target }
-      self.compiler = Compiler.identify(:source=>source)
+    # Associates this task with project and particular usage (:main, :test).
+    def associate_with(project, usage) #:nodoc:
+      @project, @usage = project, usage
+      # Try to guess if we have a compiler to match source files.
+      candidate = Compiler.compilers.detect { |cls|
+        cls.applies_to?(Array(cls.sources).map { |path| @project.path_to(:source, @usage, path) }) }
+      self.compiler = candidate if candidate
     end
 
   private
 
     def needed? #:nodoc:
-      return false if Array(sources).empty?
+      return false if sources.empty?
       # Fail during invoke.
       return true unless @compiler && target
-      # No need to check further.
-      return false if compile_map.empty?
-      return true unless File.exist?(target.to_s)
-      return true if compile_map.any? { |source, target| !File.exist?(target) || File.stat(source).mtime > File.stat(target).mtime }
-      oldest = compile_map.map { |source, target| File.stat(target).mtime }.min
-      return dependencies.any? { |path| application[path].timestamp > oldest }
+      return @compiler.needed?(sources.map(&:to_s), target.to_s, dependencies.map(&:to_s))
     end
 
     def invoke_prerequisites(args, chain) #:nodoc:
-      @prerequisites |= dependencies + Array(sources)
+      @sources = Array(@sources).map(&:to_s).uniq
+      @dependencies = FileList[@dependencies.uniq]
+      @prerequisites |= @dependencies + @sources
       super
     end
 
-    # Creates and caches the compile map.
-    def compile_map #:nodoc:
-      @compile_map ||= @compiler.compile_map(@sources = Array(@sources).map(&:to_s).uniq, target.to_s)
-    end
-
   end
 
 
@@ -429,7 +439,7 @@
       resources.filter.using Buildr.profile
 
       compile = CompileTask.define_task('compile'=>resources)
-      compile.send :associate, project.path_to(:source, :main), project.path_to(:target, :main)
+      compile.send :associate_with, project, :main
       project.recursive_task('compile')
     end
 

Modified: incubator/buildr/trunk/lib/core/project.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/project.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/project.rb (original)
+++ incubator/buildr/trunk/lib/core/project.rb Mon Jan  7 23:22:41 2008
@@ -354,12 +354,11 @@
       end
 
       # :call-seq:
-      #   task_in_parent_project(task_name) => task_name or nil
+      #   parent_task(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) #:nodoc:
+      # Returns a parent task, basically a task in a higher namespace.  For example, the parent
+      # of 'foo:test:compile' is 'foo:compile' and the parent of 'foo:compile' is 'compile'.
+      def parent_task(task_name) #:nodoc:
         namespace = task_name.split(':')
         last_name = namespace.pop
         namespace.pop

Modified: incubator/buildr/trunk/lib/core/test.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/test.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/test.rb (original)
+++ incubator/buildr/trunk/lib/core/test.rb Mon Jan  7 23:22:41 2008
@@ -134,8 +134,8 @@
       @dependencies = []
       @include = []
       @exclude = []
-      parent = Project.task_in_parent_project(name)
-      @options = parent && parent.respond_to?(:options) ? parent.options.clone : DEFAULT_OPTIONS.clone
+      @parent_task = Project.parent_task(name)
+      @options = @parent_task.respond_to?(:options) ? @parent_task.options.clone : DEFAULT_OPTIONS.clone
       enhance { run_tests }
       select :junit
     end
@@ -353,6 +353,10 @@
 
     attr_reader :project
 
+    def associate_with(project)
+      @project = project
+    end
+
     def select(name)
       @framework = TestFramework.select(name)
     end
@@ -467,8 +471,8 @@
     
     before_define do |project|
       # Define a recursive test task, and pass it a reference to the project so it can discover all other tasks.
-      TestTask.define_task('test')
-      project.test.instance_eval { instance_variable_set :@project, project }
+      test = TestTask.define_task('test')
+      test.send :associate_with, project
 
       # Similar to the regular resources task but using different paths.
       resources = ResourcesTask.define_task('test:resources')
@@ -476,12 +480,12 @@
       resources.filter.into project.path_to(:target, :test, :resources)
 
       # Similar to the regular compile task but using different paths.
-      compile = CompileTask.define_task('test:compile'=>[project.compile, project.test.resources])
-      compile.send :associate, project.path_to(:src, :test), project.path_to(:target, :test)
-      project.test.enhance [compile]
+      compile = CompileTask.define_task('test:compile'=>[project.compile, resources])
+      compile.send :associate_with, project, :test
+      test.enhance [compile]
 
       # Define these tasks once, otherwise we may get a namespace error.
-      project.test.setup ; project.test.teardown
+      test.setup ; test.teardown
     end
 
     after_define do |project|

Modified: incubator/buildr/trunk/lib/java/compilers.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/compilers.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/compilers.rb (original)
+++ incubator/buildr/trunk/lib/java/compilers.rb Mon Jan  7 23:22:41 2008
@@ -22,48 +22,67 @@
     # * :lint        -- Lint option is one of true, false (default), name (e.g. 'cast') or array.
     # * :other       -- Array of options passed to the compiler (e.g. '-implicit:none')
     class Javac < Base
-      
+
       OPTIONS = [:warnings, :debug, :deprecation, :source, :target, :lint, :other]
 
-      def initialize #:nodoc:
-        super :language=>:java, :target_path=>'classes', :target_ext=>'.class', :packaging=>:jar
-      end
+      specify :language=>:java, :target=>'classes', :target_ext=>'class', :packaging=>:jar
 
-      def configure(task, source, target) #:nodoc:
+      def initialize(options) #:nodoc:
         super
-        update_options_from_parent! task, OPTIONS
-        task.options.warnings ||= verbose
-        task.options.deprecation ||= false
-        task.options.lint ||= false
-        task.options.debug ||= Buildr.options.debug
+        { :warnings=>verbose, :deprecation=>false, :lint=>false, :debug=>Buildr.options.debug }.
+          each { |name, value| options[name] = value unless options.has_key?(name) }
       end
 
-      def compile(files, task) #:nodoc:
-        check_options task, OPTIONS
-        ::Buildr::Java.javac files, :sourcepath=>task.sources.select { |source| File.directory?(source) },
-          :classpath=>task.dependencies, :output=>task.target, :javac_args=>javac_args_from(task.options)
+      def compile(sources, target, dependencies) #:nodoc:
+        check_options options, OPTIONS
+        cmd_args = []
+        cmd_args << "-cp" << dependencies.join(File::PATH_SEPARATOR) unless dependencies.empty?
+        source_paths = sources.select { |source| File.directory?(source) }
+        cmd_args << "-sourcepath" << source_paths.join(File::PATH_SEPARATOR) unless source_paths.empty?
+        cmd_args << "-d" << target
+        cmd_args += javac_args
+        cmd_args += files_from_sources(sources)
+        unless Rake.application.options.dryrun
+          puts (["javac"] + cmd_args).join(" ") if Rake.application.options.trace
+          cmd_args = cmd_args.to_java_array(::Java.java.lang.String) if Java.jruby?
+          Java.import('com.sun.tools.javac.Main').compile(cmd_args) == 0 or fail "Failed to compile, see errors above"
+        end
       end
 
     private
 
-      def javac_args_from(options) #:nodoc:
+      def javac_args #:nodoc:
         args = []  
-        args << '-nowarn' unless options.warnings
+        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'
+        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  then args << "-Xlint:#{options[:lint].join(',')}"
+          when String then args << "-Xlint:#{options[:lint]}"
+          when true   then args << '-Xlint'
         end
-        args + Array(options.other)
+        args + Array(options[:other])
       end
 
     end
 
+
+    # Scalac compiler:
+    #   compile.using(:scalac)
+    # Used by default if .scala files are found in the src/main/scala directory (or src/test/scala)
+    # and sets the target directory to target/classes (or target/test/classes).
+    #
+    # Accepts the following options:
+    class Scalac < Base
+
+      OPTIONS = []
+
+      specify :language=>:scala, :target=>'classes', :target_ext=>'class', :packaging=>:jar
+
+    end
   end
 
 
@@ -272,7 +291,10 @@
 
 end
 
-Buildr::Compiler.add Buildr::Compiler::Javac
+module Buildr::Compiler
+  add Javac
+  add Scalac
+end
 class Buildr::Project
   include Buildr::Javadoc
   include Buildr::Apt

Modified: incubator/buildr/trunk/spec/compile_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/compile_spec.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/compile_spec.rb (original)
+++ incubator/buildr/trunk/spec/compile_spec.rb Mon Jan  7 23:22:41 2008
@@ -34,7 +34,7 @@
 
   it 'should respond to from() and add sources' do
     compile_task.from sources, File.dirname(sources.first)
-    compile_task.sources.should eql(sources + [File.dirname(sources.first)])
+    compile_task.sources.should == sources + [File.dirname(sources.first)]
   end
 
   it 'should respond to with() and return self' do
@@ -44,7 +44,7 @@
   it 'should respond to with() and add classpath dependencies' do
     jars = (1..3).map { |i| "test#{i}.jar" }
     compile_task.with *jars
-    compile_task.classpath.should eql(artifacts(jars))
+    compile_task.classpath.should == artifacts(jars)
   end
 
   it 'should respond to into() and return self' do
@@ -67,7 +67,7 @@
   end
 
   it 'should attempt to identify compiler' do
-    Compiler.compilers.first.should_receive(:identify?).at_least(:once)
+    Compiler.compilers.first.should_receive(:applies_to?).at_least(:once)
     define('foo')
   end
 
@@ -93,7 +93,7 @@
 
   it 'should attempt to identify compiler if sources are specified' do
     define 'foo' do
-      Compiler.compilers.first.should_receive(:identify?)
+      Compiler.compilers.first.should_receive(:applies_to?)
       compile.from('sources').compiler
     end
   end
@@ -126,7 +126,7 @@
 
   it 'should be an array' do
     compile_task.sources += sources
-    compile_task.sources.should eql(sources)
+    compile_task.sources.should == sources
   end
 
   it 'should allow files' do
@@ -159,7 +159,7 @@
 
   it 'should be an array' do
     compile_task.dependencies += jars
-    compile_task.dependencies.should eql(jars)
+    compile_task.dependencies.should == jars
   end
 
   it 'should allow files' do
@@ -179,7 +179,7 @@
   it 'should allow projects' do
     define('bar', :version=>'1', :group=>'self') { package :jar }
     compile_task.with project('bar')
-    compile_task.dependencies.should eql(project('bar').packages)
+    compile_task.dependencies.should == project('bar').packages
   end
 
   it 'should be accessible as classpath' do
@@ -334,17 +334,24 @@
 
   it 'should touch target if anything compiled' do
     mkpath compile_task.target.to_s
-    File.utime(Time.now - 1, Time.now - 1, compile_task.target.to_s)
+    File.utime(Time.now - 10, Time.now - 10, compile_task.target.to_s)
     compile_task.from(sources).invoke
     File.stat(compile_task.target.to_s).mtime.should be_close(Time.now, 2)
   end
 
   it 'should not touch target if nothing compiled' do
     mkpath compile_task.target.to_s
-    File.utime(Time.now - 1, Time.now - 1, compile_task.target.to_s)
-    Java.should_receive(:javac).and_raise(RuntimeError)
-    compile_task.from(sources).invoke rescue nil
-    File.stat(compile_task.target.to_s).mtime.should be_close(Time.now, 2)
+    File.utime(Time.now - 10, Time.now - 10, compile_task.target.to_s)
+    compile_task.invoke
+    File.stat(compile_task.target.to_s).mtime.should be_close(Time.now - 10, 2)
+  end
+
+  it 'should not touch target if failed to compile' do
+    mkpath compile_task.target.to_s
+    File.utime(Time.now - 10, Time.now - 10, compile_task.target.to_s)
+    write 'failed.java', 'not a class'
+    suppress_stdout { compile_task.from('failed.java').invoke rescue nil }
+    File.stat(compile_task.target.to_s).mtime.should be_close(Time.now - 10, 2)
   end
 end
 

Modified: incubator/buildr/trunk/spec/java_compilers.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/java_compilers.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/java_compilers.rb (original)
+++ incubator/buildr/trunk/spec/java_compilers.rb Mon Jan  7 23:22:41 2008
@@ -49,7 +49,7 @@
   end
 
   def javac_args
-    Compiler::Javac.new.send(:javac_args_from, compile_task.options)
+    Compiler::Javac.new(compile_task.options).send(:javac_args)
   end
 
   it 'should set warnings option to false by default' do

Modified: incubator/buildr/trunk/spec/packaging_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/packaging_spec.rb?rev=609893&r1=609892&r2=609893&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/packaging_spec.rb (original)
+++ incubator/buildr/trunk/spec/packaging_spec.rb Mon Jan  7 23:22:41 2008
@@ -428,55 +428,6 @@
 end
 
 
-shared_examples_for 'packaging' do
-  it 'should create artifact of proper type' do
-    packaging = @packaging
-    package_type = @package_type || @packaging
-    define 'foo', :version=>'1.0' do
-      package(packaging).type.should eql(package_type) rescue exit!
-    end
-  end
-
-  it 'should create file with proper extension' do
-    packaging = @packaging
-    package_type = @package_type || @packaging
-    define 'foo', :version=>'1.0' do
-      package(packaging).to_s.should match(/.#{package_type}$/)
-    end
-  end
-
-  it 'should always return same task for the same package' do
-    packaging = @packaging
-    define 'foo', :version=>'1.0' do
-      package(packaging)
-      package(packaging, :id=>'other')
-    end
-    project('foo').packages.uniq.size.should eql(2)
-  end
-
-  it 'should complain if option not known' do
-    packaging = @packaging
-    define 'foo', :version=>'1.0' do
-      lambda { package(packaging, :unknown_option=>true) }.should raise_error(ArgumentError, /no such option/)
-    end
-  end
-
-  it 'should respond to with() and return self' do
-    packaging = @packaging
-    define 'foo', :version=>'1.0' do
-      package(packaging).with({}).should be(package(packaging))
-    end
-  end
-
-  it 'should respond to with() and complain if unknown option' do
-    packaging = @packaging
-    define 'foo', :version=>'1.0' do
-      lambda {  package(packaging).with(:unknown_option=>true) }.should raise_error(ArgumentError, /does not support the option/)
-    end
-  end
-end
-
-
 describe Packaging, 'zip' do
   it_should_behave_like 'packaging'
   before { @packaging = :zip }