Why is my custom task never considered as up-to-date?

I have a custom task with an @InputFile annotated property and as far as I can tell this should be used to determine if the task is up-to-date or not. However when I run the task it is never considered UP-TO-DATE even when the input file is unchanged.

From other examples I have seen this seems to be all that’s needed, but I’m probably missing something…

import javax.script.ScriptEngine
import javax.script.ScriptEngineManager
  import org.gradle.api.*
import org.gradle.api.tasks.*
  class SassCompilerTask extends DefaultTask {
      @InputFile
    File inputFile
      @OutputFile
    public File outputFile
      public File cacheLocation
      String driverScript = '''
        require 'rubygems'
        require 'sass'
          $mappings.each do |src, dst|
            engine = Sass::Engine.for_file(src, {:cache_location => $cacheLocation})
            css = engine.render
            File.open(dst, 'w') {|f| f.write(css) }
            puts "#{src} -> #{dst}"
        end
    '''
      @TaskAction
    def compileSass() {
        def mappings = new TreeMap()
        outputFile.parentFile.mkdirs()
        mappings.put(inputFile.path, outputFile.path)
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("jruby")
        engine.put("cacheLocation", cacheLocation.path)
        engine.put("mappings", mappings)
        engine.eval(driverScript)
    }
}
task sass(type: SassCompilerTask) {
    inputFile = file('src/main/webapp/sass/app.scss')
    outputFile = new File(project.buildDir, 'sass-css/app.css')
    cacheLocation = new File(project.buildDir, 'sass-cache')
}

The ‘public’ modifier might cause ‘@OutputFile’ to go unnoticed because no (annotated) accessors will get generated. Try omitting the modifier (better anyway).

That works thanks!