Output is always marked as "UP-TO-DATE"

Hi,

I have the following build script which is producing an output file. I’m trying to use outputs property of the task. Although I’m getting what I need (generate an output file), I’m trying to take advantage of the “UP-TO-DATE” feature. In my case, gradle ALWAYS tells me the task is UP-TO-DATE, regardless of whether or not the content of the file has changed. In fact, the content is always being updated as per the file’s modified time stamp. Here’s what I have:

import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
  buildscript {
 repositories {
  mavenCentral()
 }
    dependencies {
  classpath group: 'org.codehaus.groovy.modules.http-builder', name: 'http-builder', version: '0.7.1'
 }
    buildDir = "output"
}
  task getFeed {
 //declare output of this task
 ext.feed = file("$buildDir/scheduleFeed/feed.xml")
 if (!feed.isFile()) {
  feed.parentFile.mkdirs()
  feed.createNewFile()
 }
   outputs.file feed
    //build a URI
 def scheduleUrl = new URIBuilder(source).with {
  scheme = 'https'
  port = 443
  query = [calendarUuid: calID, startDate: lookupDateStart, endDate: lookupDateEnd, lang: lang]
  return it
 }.toString()
   //using HTTPBuilder, authenticate to the calendar.
 def http = new HTTPBuilder(scheduleUrl)
 http.auth.basic(calUser, calPwd)
 http.request(GET,TEXT) { req ->
   headers.'User-Agent' = 'Mozilla/5.0'
      response.success = { resp, xmlFeed ->
  assert resp.status == 200
  feed.text = xmlFeed.text
   }
        // called only for a 404 (not found) status code:
   response.'404' = { resp ->
  println 'Error: Schedule Not found'
   }
     }
}

What is it that I did wrong here? I’m following this guide form Gradle site and declared the outputs property. Is this because I’m getting data from an online source which is keep updating the file? In that case, Gradle shouldn’t tell me that it’s UP-TO-DATE, even if it’s the same content, right?

https://gradle.org/docs/current/userguide/more_about_tasks.html

Second question, my understanding is that this task will run during the configuration phase regardless of what task was targeted to run. Does this mean that it will ALWAYS update the xml file when other tasks are run? If I need to create another task that will use the output of this task, should I use task dependency or declare the 2nd task’s output like below:

task getData {
    inputs.files getFeeds.outputs.files
   ....
  }

Put the code the creates and writes to the ‘feed’ file inside of a ‘doLast { }’ closure.

Hi Casey,

Thanks for the suggestion. Unfortunately I’m still not able to get this to work. I made some changes (shown below) so that creating/writing to a file is taking place within doLast closure, but that seem to prevent the file being updated. If I delete the existing file, that it creates a new file and I don’t see up-to-date check, as expected. But if the previous file exist and it seems the action for updating the file doesn’t take place.

Have been going over this code several times, but can’t see what I’m missing here.

import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'org.codehaus.groovy.modules.http-builder', name: 'http-builder', version: '0.7.1'
    }
    buildDir = "output"
}
task getFeed {
    //declare output of this task
    ext.feed = file("$buildDir/scheduleFeed/feed.xml")
    outputs.file feed
    doLast{
    if (!feed.isFile()) {
        feed.parentFile.mkdirs()
        feed.createNewFile()
    }
          //build a URI
    def scheduleUrl = new URIBuilder(source).with {
        scheme = 'https'
        port = 443
        query = [calendarUuid: calID, startDate: lookupDateStart, endDate: lookupDateEnd, lang: lang]
        return it
    }.toString()
    //using HTTPBuilder, authenticate to the calendar.
    def http = new HTTPBuilder(scheduleUrl)
    http.auth.basic(calUser, calPwd)
    http.request(GET,TEXT) { req ->
      headers.'User-Agent' = 'Mozilla/5.0'
      response.success = { resp, xmlFeed ->
        assert resp.status == 200
        feed.text = xmlFeed.text
      }
       // called only for a 404 (not found) status code:
      response.'404' = { resp ->
        println 'Error: Schedule Not found'
      }
     }
  }
}