How to add a task in Gradle to run at build time


#1

I would like to add some build time info to that gets deployed to the RoboRio so our team can see what version of the software we have installed and are running. I got the idea from team 2721 (thanks South Eugene Robotics!) and was following their example. However, the example they posted has a lot more changes to the build.gradle file than are related to this feature, indeed they are using Kotlin, and that isn’t a step I want to take.

I added a task to write the build time to a file in $projectdir/src/main/deploy/buildtime.txt. However, I don’t know how to add the task as a dependency to the build target so the task gets run when the code is built. Does anyone know how to to that?


#2

It depends a little on how you are defining your task, but a basic task in your build.gradle can specify a dependency on another task like so:

task foo {
    dependsOn: build // or deploy, etc
    doLast {
         println “My task”
    }
}

#3

We are doing the same this year. It’s not exactly… concise… nor would I sign up to say it’s “best practice”… but it does do what you’d like, I think. We pull a bunch of info about build computer, username, time, etc., as well as info about the state of the git repo at time of build.

First, make sure you have grgit added as dependencies:

plugins {
    id "java"
    id "edu.wpi.first.GradleRIO" version "2019.2.1"
    id "org.ajoberstar.grgit" version "3.0.0"
}

Define a function to generate the Build meta-data file:


///////////////////////////////////////////////////////////////////////////////////////////////////
// Build Meta-data file generation
///////////////////////////////////////////////////////////////////////////////////////////////////
task genMetaData(){
    doLast{

        String filecontents = ""
        String build_uname = ""
        String build_host = ""
        String build_time = ""
        String git_sha1 = ""
        String git_branch = ""
        String git_wd_clean = ""
        String git_tag_list = ""

        //Get the user's name. Shouldn't throw errors, just "null" if 
        // it can't figure out who you are.
        build_uname = System.getProperty("user.name")

        //Get the closest thing to PC name we can find in Groovy, the
        // local machine's Hostname. This could definietly throw exceptions
        // if you've got a weird system or something.
        try{
            build_host = java.net.InetAddress.getLocalHost().getHostName()
        } catch (all) {
            build_host = "unknown"
        }

        //Build time in totally-not-ISO format
        build_time = new java.text.SimpleDateFormat("MM-dd-yyyy hh:mm:ssa").format(new Date())

        // Get currently checked-out SHA1
        try{
            git_sha1 = Grgit.open(currentDir: file('.')).head().id
        } catch (all) {
            git_sha1 = "unknown"
        }

        // Get currently checked-out branch friendly name
        try{
            git_branch = Grgit.open(currentDir: file('.')).branch.current().name
        } catch (all) {
            git_branch = "unknown"
        }

        // Get friendly names of the tags on this commit (if any)
        try{
            def repo = Grgit.open(currentDir: file('.'))
            def head = repo.head()
            def tag_list = repo.tag.list().findAll{it.commit == head}
            if(tag_list.size() > 0){
                for(tag_obj in tag_list){
                    git_tag_list += tag_obj.getName()+","
                }
                
            } else {
                git_tag_list = "none"
            }

        } catch (Exception e) {
            System.out.println(e)
            git_tag_list = "unknown"
        }

        // Get clean/dirty status of working directory
        try{
            git_wd_clean = Grgit.open(currentDir: file('.')).status().isClean()
        } catch (all) {
            git_wd_clean = "unknown"
        }

        // Build file contents and write to disk
        filecontents += "<html><body>\n"
        filecontents += "<table>\n"
        filecontents += "<head><link rel=\"stylesheet\" href=\"main.css\"></head>\n"
        filecontents += "<tr><td>Build Username     </td><td> ${build_uname}  </td></tr>\n"
        filecontents += "<tr><td>Build Host PC      </td><td> ${build_host}   </td></tr>\n"
        filecontents += "<tr><td>Build Time         </td><td> ${build_time}   </td></tr>\n"
        filecontents += "<tr><td>Git Tags           </td><td> ${git_tag_list} </td></tr>\n"
        filecontents += "<tr><td>Git Branch         </td><td> ${git_branch}   </td></tr>\n"
        filecontents += "<tr><td>Git SHA1           </td><td> ${git_sha1}     </td></tr>\n"
        filecontents += "<tr><td>Working Dir Clean? </td><td> ${git_wd_clean} </td></tr>\n"
        filecontents += "</table>\n" 
        filecontents += "</body></html>\n"

        new File(BUILD_INFO_FILE).text = filecontents
    }
}

Add the file generation to the standard build (we just put these lines at the end of our file):

// Add the file generation task to the standard build
build.dependsOn genMetaData
simulateExternalJava.dependsOn genMetaData

We chose HTML, but you can change the filecontents += portion to be whatever you like.


#4

Thanks, gerthworm. The line “build.dependsOn” is exactly what I was missing.

Bryan_Herbst, my system choked on “dependsOn: build”, I don’t know why. I got:

build.gradle’: 65: Statement labels may not be used in build scripts.
In case you tried to configure a property named ‘dependsOn’, replace ‘:’ with ‘=’ or ’ ', otherwise it will not have the desired effect.
@ line 65, column 16.
dependsOn: build


What method is called right after you deploy code to the robot?