From d421a83e8d27c7227e3a1bdfdeb4c4dc903a19c2 Mon Sep 17 00:00:00 2001 From: Manfred Endres <2523575+Larusso@users.noreply.github.com> Date: Thu, 16 Feb 2023 12:29:02 +0100 Subject: [PATCH] Fix execution order of Unity tasks in sub modules (#133) Description =========== We have a new bug where some unity tasks get executed before the paket unity install tasks had any chance to be executed. This patch is addressing this by making sure that any task of type `wooga.gradle.unity.UnityTask` depends on * `paketUnityInstall` * `paketUnityUnwrapUPMPackages` Changes ======= * ![FIX] execution order of Unity tasks in sub modules --- .../ReleasePluginIntegrationSpec.groovy | 82 ++++++++++++------- .../wooga/gradle/release/ReleasePlugin.groovy | 26 +++++- 2 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/integrationTest/groovy/wooga/gradle/release/ReleasePluginIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/release/ReleasePluginIntegrationSpec.groovy index a876d06..fde7519 100644 --- a/src/integrationTest/groovy/wooga/gradle/release/ReleasePluginIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/release/ReleasePluginIntegrationSpec.groovy @@ -16,22 +16,22 @@ package wooga.gradle.release -import com.wooga.gradle.test.PropertyQueryTaskWriter +import com.wooga.gradle.test.executable.FakeExecutables import org.ajoberstar.grgit.Grgit -import org.gradle.api.Task -import org.gradle.api.specs.Spec import spock.lang.Ignore import spock.lang.Unroll -import wooga.gradle.github.publish.GithubPublishPlugin import wooga.gradle.paket.get.PaketGetPlugin import wooga.gradle.unity.UnityPlugin -class ReleasePluginIntegrationSpec extends IntegrationSpec { +class ReleasePluginIntegrationSpec extends com.wooga.gradle.test.IntegrationSpec { Grgit git File gitIgnore def setup() { + def fakeUnity = FakeExecutables.argsReflector(File.createTempFile("fake_unity", ".bat").path, 0) + + environmentVariables.set("UNITY_PATH", fakeUnity.executable.path) gitIgnore = createFile('.gitignore') gitIgnore << """ .gradle/ @@ -46,6 +46,26 @@ class ReleasePluginIntegrationSpec extends IntegrationSpec { createFile("paket.dependencies") } + def "verify paket unity install is called before any unity task is executed"() { + given: "some subprojects with net.wooga.unity applied" + + addSubproject("testSub", """ + apply plugin: 'net.wooga.unity' + """.stripIndent()) + + and: "a buildfile with release plugin applied" + buildFile << """ + ${applyPlugin(ReleasePlugin)} + """.stripIndent() + + when: + def result = runTasks('ensureProjectManifest') + + then: + result.standardOutput.indexOf("> Task :paketUnityInstall") < result.standardOutput.indexOf("> Task :testSub:ensureProjectManifest") + result.standardOutput.indexOf("> Task :paketUnityUnwrapUPMPackages") < result.standardOutput.indexOf("> Task :testSub:ensureProjectManifest") + } + // @Unroll("verify dependency setup to #testType unity sub-projects") // def "verify dependency setup to unity sub-projects"() { // given: "some subprojects with net.wooga.unity applied" @@ -200,21 +220,21 @@ class ReleasePluginIntegrationSpec extends IntegrationSpec { aSubDir2.mkdirs() def filesToDelete = [ - createFile("file.cs.meta", assetsDir), - createFile("file.json.meta", assetsDir), - createFile(".meta", assetsDir), - createFile("test.cs", assetsDir), - createFile("test.json", assetsDir), - createFile("test.cs", aSubDir), - createFile("test.json", aSubDir), + createFile("file.cs.meta", assetsDir), + createFile("file.json.meta", assetsDir), + createFile(".meta", assetsDir), + createFile("test.cs", assetsDir), + createFile("test.json", assetsDir), + createFile("test.cs", aSubDir), + createFile("test.json", aSubDir), ] def filesToKeep = [ - createFile("test.dll.meta", assetsDir), - createFile("file.cs.meta", aSubDir2), - createFile("file.json.meta", aSubDir2), - createFile(".meta", aSubDir2), - createFile("test.dll.meta", aSubDir), + createFile("test.dll.meta", assetsDir), + createFile("file.cs.meta", aSubDir2), + createFile("file.json.meta", aSubDir2), + createFile(".meta", aSubDir2), + createFile("test.dll.meta", aSubDir), ] and: "a buildfile with release plugin applied" @@ -263,20 +283,20 @@ class ReleasePluginIntegrationSpec extends IntegrationSpec { def filesToDelete = [] def filesToKeep = [ - createFile("test.meta", assetsDir), - createFile(".meta", assetsDir), - createFile("test.meta", aSubDir), - createFile(".meta", aSubDir), - createFile("test.dll.meta", assetsDir), - createFile("test.cs", assetsDir), - createFile("test.json", assetsDir), - createFile("test.cs", aSubDir), - createFile("test.json", aSubDir), - createFile("test.so.meta", assetsDir), - createFile("test.dll.meta", aSubDir), - createFile("test.so.meta", aSubDir), - createFile("test.meta", unitySub), - createFile(".meta", unitySub)] + createFile("test.meta", assetsDir), + createFile(".meta", assetsDir), + createFile("test.meta", aSubDir), + createFile(".meta", aSubDir), + createFile("test.dll.meta", assetsDir), + createFile("test.cs", assetsDir), + createFile("test.json", assetsDir), + createFile("test.cs", aSubDir), + createFile("test.json", aSubDir), + createFile("test.so.meta", assetsDir), + createFile("test.dll.meta", aSubDir), + createFile("test.so.meta", aSubDir), + createFile("test.meta", unitySub), + createFile(".meta", unitySub)] and: "a buildfile with release plugin applied" buildFile << """ diff --git a/src/main/groovy/wooga/gradle/release/ReleasePlugin.groovy b/src/main/groovy/wooga/gradle/release/ReleasePlugin.groovy index ce11df1..16d4a10 100644 --- a/src/main/groovy/wooga/gradle/release/ReleasePlugin.groovy +++ b/src/main/groovy/wooga/gradle/release/ReleasePlugin.groovy @@ -337,10 +337,12 @@ class ReleasePlugin implements Plugin { */ protected static void configureUnityPackageIfPresent(Project project, AtlasReleasePluginExtension extension) { DependencyHandler dependencies = project.dependencies - project.subprojects { sub -> + def rootPaketUnityInstall = project.rootProject.tasks[PaketUnityPlugin.INSTALL_TASK_NAME] + def rootPaketUnwrapUPM = project.rootProject.tasks[PaketUnityPlugin.UNWRAP_UPM_TASK_NAME] + project.subprojects { Project sub -> sub.pluginManager.withPlugin("net.wooga.unity", new Action() { @Override - void execute(AppliedPlugin appliedPlugin) { + void execute(AppliedPlugin unityPlugin) { logger.info("subproject {} has unity plugin.", sub.name) logger.info("configure dependencies {}", sub.path) logger.info("create cleanMetaFiles task") @@ -360,6 +362,26 @@ class ReleasePlugin implements Plugin { paketPack.dependsOn cleanTask } }) + + /** + * The release plugin has no real internal knowledge or dependency to the unity plugin. + * We had cases where the release plugin was not being used along a unity project so + * I'm very careful to keep this seperated as much as possible. + * + * To be able to pull the class with just the class name we have to make sure to provide + * the correct class loader instance. Since we know that the unity plugin got applied, + * otherwise this block would not be executed we pull the plugin class from gradle and from there + * the classloader for that class. The unity task class should be in the same classloader. + */ + try { + ClassLoader unityLoader = sub.plugins.getPlugin(unityPlugin.id).class.classLoader + Class unityTaskClass = Class.forName("wooga.gradle.unity.UnityTask", true, unityLoader) as Class + sub.tasks.withType(unityTaskClass).configureEach { + it.dependsOn(rootPaketUnityInstall, rootPaketUnwrapUPM) + } + } catch(Exception ignored) { + logger.warn("plugin 'net.wooga.unity' added, but class 'wooga.gradle.unity.UnityTask' can't be found") + } } }) }