DependedOn Task Not Even Checked?


(Julia) #1

I have made a task called buildAssets, which takes a directory not located in main/resources, packs the assets, and spits them out into the resources directory. processResources task depends on this task.

Given these assets constitute a skin for a web app, a good build will always have some output (or previous output), not just a shell of a directory, but right now, the processResources task is seeing NO-SOURCE because the buildAssets task failed and there are no previously packed skin assets in its output folder, though the output folder still exists. Therefore, buildAssets isn’t being called at all (I don’t see it even showing up on the list of tasks checked) and processResources isn’t copying anything over to be put into the jar.

I tried changing the upToDateWhen for buildAssets outputs, but alas, if processResources doesn’t know that having nothing to copy is a bad thing, the build doesn’t want to even try to run buildAssets. I don’t see any kind of hooks to affect how input of the task computes into up to date checks.

I also suspect that processResources, in using the buildAssets task as from in its copyspec, is only caring if there is a directory, not that there are files in it.

Going to tinker around and see if I’m missing something, but this seems like a common scenario I’d expect to see solutions out there and haven’t really seen others coming across this issue. :confused: Any pointers would be appreciated.

withProject(p) {
	val buildutils by configurations.getting
	val processResources by tasks.getting(Copy::class)
	val main by sourceSets
	tasks {
		val buildAssets by creating(DefaultTask::class) {
			group = "build"
			description = "Build assets for jvm modules."

			inputs.property("dest", "$buildDir/generated-resources/main/assets")
			if (isAppProject() && isThatModule("${rootProject.name}-jvm"))
				inputs.files(skin()).skipWhenEmpty()
			inputs.files(main.resources.sourceDirectories).skipWhenEmpty()

			outputs.dir(inputs.properties["dest"]!!)
			doLast {
				inputs.files.files.forEach {
					javaexec {
						args = listOf("-target=assets", "-src=${it.canonicalPath}", "-dest=${inputs.properties["dest"]!!}")
						this.main = "com.acornui.build.BuildUtilKt"
						classpath = buildutils
					}
				}
			}
			dependsOn(buildutils)
		}

		processResources.dependsOn(buildAssets)
		processResources.from(buildAssets)
	}
}

Note: buildAssets tasks are being created during the configuration phase in a subprojects block of a normal build script. For more info, the enclosing property lambda is being delegated to extra properties (ExtraPropertiesExtension) in an applied script with shared build logic, then being pulled into scope within a normal buildscript (unapplied) in the subprojects block where it checks each subproject for whether it has a plugin applied by type. This technique works and has had no adverse effects on other, similar tasks.


(Julia) #2

I’m silly. I was running build and not run, so the lifecycle didn’t care to processResources as it should. It’s working!


(Stefan Oehme) #3

There is no “lifecycle” in Gradle. It shouldn’t matter what task you run, the result should always be correct. If you could provide a small example project showing the problematic behavior, it would be easier to help.


(Julia) #4

I mean the lifecycle task processResources wasn’t being run within the build lifecycle (terminology taken from https://docs.gradle.org/current/userguide/build_lifecycle.html), and that behavior was correct. It was user error as I was running the wrong task. The build task wasn’t going to trigger processResources.


(Stefan Oehme) #5

processResources is a Copy task, not a lifecycle task (a term not mentioned in the page you linked). Of course the build task should run processResources, processing resources is required to build your software after all. More importantly it shouldn’t be “no source” when running build but then suddenly work when running run, as you described above. That just means something in your configuration is broken.

I think there is some bigger misunderstanding here, so an example project would really help.


(Julia) #6

Alright I’ll try to get a minimal project together illustrating what I’m seeing as currently it’s rather complex. As you said, there might be something deeper that is amiss. Thank you. :slight_smile:


(Julia) #7

Okay. I setup a minimal project and was not seeing the same behavior. After comparing the projects, it dawned on me (waaaay too late), that the original affected project has a failing test in a module that the custom configuration module is transitively dependent on.

So what was happening was because I didn’t use the --continue flag, it wasn’t building the transitive module, nor the module the custom configuration was directly dependent on…hence, it never even got to the point of trying to processResources for the module the configuration is used in, bc as @st_oehme pointed out, the configuration was busted .

What tripped me up originally was I seeing was testProcessResources and some similarly named project processResources triggering with NO-SOURCE and mistook it for the wrong one, repeatedly. :frowning:

Running build with the --continue flag confirmed that buildAssets and processResources are behaving as expected/designed in the scenario I’m targeting.


(Stefan Oehme) #8

Glad to know everything works after all! Thanks for checking.