Execute command line svnversion and store revision number in manifest on release

I am attempting to configure mutliple project jar manifests from the root project. This manifest should contain some dynamic information such as the svn revision number, date time when performing a release. I have an exec task to retrieve the svn revision number and redirected the output to a project property.

I have tried multiple approaches but I seem to be unable to retrieve the property to add to the manifest. The issue I’m having seems to be related to the phases.

The exec task is setup in the configuration phase and the project extra property is assigned in a doLast. However the jar task work appears to be done at the configuration phase and therefore can’t access the variable.

I’ve added a sample gist what I am trying to do here:

Thanks for the help.

Using one task to configure another is generally an anti-pattern. It seems like you are using the exec task only to get the convenience of the exec task functionality, but not because you would ever use it as a task in and of itself. I would use project.exec and roll it all into the configuration of the jar task instead:

jar {
   gradle.taskGraph.whenReady{ taskGraph ->
   if (taskGraph.hasTask(release)) {
     def svnversion = new ByteArrayOutputStream()
    project.exec {
     commandLine 'svnversion'
     standardOutput = svnversion
    }
    manifest {
     attributes(
     "Implementation-Version": version,
     "Implementation-Date": new java.util.Date().toString(),
     "SVN-Revision":svnversion.toString()
           )
      }
    } else {
    manifest {
     attributes(
      "Implementation-Version": version
      )
    }
   }
  }
  }

Thanks for the reply. I was trying to extract the logic out into a seperate task because I wanted it to execute only once. The jar task is wrapped in a configuration block that is applied to all subprojects, I think this would mean the svnversion command will be executed for every project not just once. I am trying to avoid this.

If there is no way to avoid this I can add the code as you suggest because the operation is not that expensive.

I think you can still have it exec only once. taskGraph.whenReady is associated with the gradle instance which is the same for all projects. By rearranging your config, something like the following should work:

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.hasTask(release)) {
        def svnversion = new ByteArrayOutputStream()
        project.exec {
            commandLine 'svnversion'
            standardOutput = svnversion
        }
          configure(subprojects.findAll { it.name != 'somename' }) {
            jar {
                manifest {
                    attributes(
                            "Implementation-Version": version,
                            "Implementation-Date": new java.util.Date().toString(),
                            "SVN-Revision": svnversion.toString()
                    )
                }
            }
        }
    } else {
        configure(subprojects.findAll { it.name != 'somename' }) {
            jar {
                manifest {
                    attributes(
                            "Implementation-Version": version
                    )
                }
            }
        }
    }
}