Gradle task when running the simulator

A couple of years ago I implemented some gradle tasks to write things like build time and build host and deploy time and deploy host to files on the RoboRio. I had some dependencies that read:

build.dependsOn versionTxt
tasks.getByName(‘versionTxt’).dependsOn(ensureResources)
tasks.getByName(‘deploy’).dependsOn(deployHost)
tasks.getByName(‘simulateExternalJava’).dependsOn(deployHost)

The deployHost task looks like this:

deployHost() {

String deployDir = "$projectDir/src/main/deploy"
println "Running deployHost in ${deployDir}"
doFirst {
    println "Running deployHost doFirst in ${deployDir}"

    new File("$deployDir/deployhost.txt").text = "Empty"
    new File("$deployDir/deploytime.txt").text = "Empty"
}
doLast {
    String deploy_host = ""
    try {
        deploy_host = java.net.InetAddress.getLocalHost().getHostName()
    } catch (all) {
        deploy_host = "unknown"
    }
    println "Running deployHost doLast n ${deployDir}"

    new File("$deployDir/deployhost.txt").text = deploy_host
    new File("$deployDir/deploytime.txt").text = 
        new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date())
}

}

Anytime I do anything (build, simulate, deploy), I get this at the beginning:

Configure project:
Running versionTxt
Running deployHost in c:\Users\username\Documents\FRCProjects\RapidReact2022/src/main/deploy

and then the normal output. I don’t see the doFirst and doLast messages unless I actually run the Deploy Robot Code command from the WPI commands. Then I also see:

Task :deployHost
Running deployHost doFirst […]
Running deployHost doLast […]

I have almost no understanding of how Gradle works. Why do the commands in the deployHost task run in that configure stage, but not the doFirst and doLast blocks, and why do they run in the deploy stage.

One other thing, the simulateExternalJava taks no longer seems to exist, even though it is still in the docs. I tried changing it to “simulateJava” which does exist. Maybe that isn’t what I need and that is the problem?

Disclaimer: Not a gradle expert by any means.

I think the problem has something to do with the groovy DSL syntax and the way code in build.gradle is run at configuration time vs task runtime.

The code that always runs always runs because it is in the configuration time code space, whereas the doLast, etc macros are run at task runtime.

If all you want is to add a file with compile time info wpilib has an easy document on that.

It can be adapted to put whatever you want in the files

Gradle has 2 stages of running. Configuration and Execution. Configuration runs first, and is used to build the task graph, and then execution runs the tasks.

When you declare a task in gradle, everything directly inside the block is run during the configuration stage, its not actually getting executed.

Each task has something it executes, that depends on what type of task you declare. That code is ran during execution. doFirst blocks run before that code, and doLast blocks run after that code.

SimulateExternalJava was changed to SimulateExternalJavaDebug and SimulateExternalJavaRelease. This was done to make it easier for editors to switch modes (Although this was not done in VS Code for 2022). So your best option is to make both of those tasks depend on your task (for simulation purposes). The gradle tasks docs page is out of date, and needs to be updated.

Also, you shouldn’t be making the deploy task depend on something directly. There are many individual deploy tasks, and deploy is just a marker for the end of the deploy graph. You actually want to make the deploy directory deploy task depend on your generation task. You do that with the following code (Which is also linked in the Git code above).

deploy.targets.roborio.artifacts.frcStaticFileDeploy.dependsOn(deployHost)

Huh. Not saying this isn’t a coincidence, but the code in the documentation is remarkably similar to the code I published in a public repository in Jan. 2020. A couple of other teams picked it up, so even if the code wasn’t mine, I might be the source of the idea. Of course, the main difference is that the code in the docs were written by someone who knew what they were doing, as opposed to mine, which was mostly bludgeoned into existence.

Okay, so I currently have a task with the following structure

task name() {
Code executed at config time
doFirst {
Code executed when task is run, at the beginning
}
doLast {
Code executed when the task is run, at the end
}
}

So how do you designate code to be run after the doFirst code and before the doLast code, i.e. the regular task code?

Also, I had some files go into the resources directory and some into the deploy directory. I forget why right now, but I think it was because the resources directory gets put into the jar file and I wanted how the files were built to be discoverable even if you only had the jar file. Am I correct, does the resources directory get into the jar file?

I don’t think I want everything to run at config time, since that would mean the deploy task would update when the files are deployed, even if they were built earlier. Is there a way to specify a task to be run after another task has successfully completed?

One more thing, I tried the target you gave:
“deploy.targets.roborio.artifacts.frcStaticFileDeploy.dependsOn(deployHost)”
and it gave me an error:

Could not get unknown property ‘roborio’ for RemoteTarget container of type org.gradle.api.internal.DefaultPolymorphicDomainObjectContainer.

Is there anyway to find these things in the Github Repository?

You create a custom task type. But its not worth doing, just treat doLast as your execution block. It will work the exact same way.

Yes, resources directory goes into the jar, so you need to make the generateResources task depend on your task.

You can’t explicitly mark a task to be ran after another task. You can make tasks depend on other tasks, and if you know 2 tasks depend on each other in the graph, you can insert a task between them using dependsOn. One thing to note is that tasks only run if something in the task graph depends on it. Tasks will be skipped if there are no dependencies on the task.

What does your deploy block look like. That code example depends on it looking exactly the same as the standard templates. If anything has been renamed, it won’t work. And that sample must be placed after the deploy block.

I had all of my stuff in a separate file called splash.gradle, and I was using “apply” to bring it into the build.gradle. I just had to move the apply after the deploy block and then it worked.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.