Add an @Output Annotation for task outputs


(René Groeschke) #1

I would like to have an @Output annotation for marking output properties in my custom tasks.

My use case is a custom task I wrote, that tags the current revision of my working svn copy and I would like to add some kind of remote check if the tag already exists in the svn repo. What do you think guys?


(Adam Murdoch) #2

I’m not entirely sure what an @Output property might mean. Can you give an example of how this property would look on your custom task (some pseudo-code, perhaps)?

I can see a couple of options of how this might work:

  • A property that returns a boolean indicating whether some output is present/up-to-date. We would execute the task if any such method returns false. This is more-or-less just a convenience for outputs.upToDateWhen().
  • A property that returns some representation of what the task would produce if it were executed. We would compare that against the serialised value from last time the task executed, and execute the task if they are different.

(René Groeschke) #3

I am working on a “tag” task, that allows me to tag my working svn copy if the build was successful (meaning of my depending tasks are executed correctly).

The implementation is based on SvnKit. As an output of this “tag” task I would like to have an object, that gives me information about the revision of the tag, the author, commit message, etc. On my specific use case I would like to create an output object, that is based on SvnKits SVNDirEntry class: http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/SVNDirEntry.html

A snippet to get this SvnDirEntry object of an tag would look roughly like this:

ISVNAuthenticationManager authManager =
                  new BasicAuthenticationManager( userName , userPassword );
clientManager = SVNClientManager.newInstance(null, authManager);
SVNWCClient wcClient = clientManager.getWCClient();
SVNInfo doInfo = wcClient.doInfo(getProject().file("."),
                  SVNRevision.WORKING);
sourceURL = doInfo.getURL();
sourceRevision = doInfo.getRevision();
SVNLogClient infoClient = clientManager.getLogClient();
SVNURL rootURL = getRootURL(sourceURL);
SVNURL tagURL = calculateDestURL(sourceURL);
   infoClient.doList(tagURL, SVNRevision.HEAD, SVNRevision.HEAD, false, SVNDepth.EMPTY, 0, new ISVNDirEntryHandler(){
     public void handleDirEntry(SVNDirEntry entry)
                                                throws SVNException {
         tagInfo = entry;
// tagInfo is the property
                                    // I want to store/leverage
                                    // for up-to-date checks
     }
 });

(Adam Murdoch) #4

What would Gradle do with the value of this property? Compare it against the value from last time the task was executed?

Haven’t you more or less done the work of the task already, by figuring out this value? Perhaps it would be better for this task to simply execute, and set Task.didWork = false if the tag already existed. ie. what value does checking this value actually give you?


(René Groeschke) #5

I’ll try the didWork = false approach and let you know if I hit any issues with this. In another scenario, we had a quite similar problem while maintaining our test databases:

To check the version of a database instance, I execute a query on the database to get the installed version. When executing our scripts again, it would be cool to have information about the setup of the remote database. Of course I can mark the task as out of date when the db scripts have changed. But in particular cases, this isn’t enough. (e.g. when sharing database vms in different project branches). So having a build in precheck mechanism would be nice here. Something like

Task setupDB(){
   String schemaVersion
   pre{
       schemaVersion = run.query.against remote db
   }
        doFirst{
        ...
        ...
        ...
        // execute long running installation scripts
        ...
        ...
        // set the property at the end of the task execution
        //
         schemaVersion = //take from script or
                                     //take from remote query again
   }
}

(Luke Daley) #6

Rene,

How did you go with this? Can we close this off? Or would you like to explore the idea of the @Output annotation further?


(René Groeschke) #7

In our database integration scripts described above, we currently store the version information of a of an instance (triggered by a query) in a file. This workaround is needed, since gradle doesn’t support me here for storing these information.

When running our integration scripts and finding an instance that has the current version installed, is what I would call “up-to-date”.

Anyway. Using task.didWork feels okay for the tagging example above, but it doesn’t feel natural for our schema installation / up-to-date check described. What do you guys think?


(Luke Daley) #8

In our database integration scripts described above, we currently store the version information of a of an instance (triggered by a query) in a file. This workaround is needed, since gradle doesn’t support me here for storing these information.

Right, Gradle doesn’t provide any kind of persistent storage.

When running our integration scripts and finding an instance that has the current version installed, is what I would call “up-to-date”.

It’s close, but not the same. Something still has to do some work to know what the intended version is, and the actual version. If you want to model this in one task as opposed to 3 (fetch the intended version, fetch the actual version, perform migrations) then “skipped” is semantically closer.

Anyway. Using task.didWork feels okay for the tagging example above, but it doesn’t feel natural for our schema installation / up-to-date check described. What do you guys think?

For my money it’s more correct.

If you do want to use up-to-date checking though, you could model the intended version and actual version as @Input’s to the migration task.