From c296c82bb0d0e8da5026d078e81c2168c5dfb384 Mon Sep 17 00:00:00 2001 From: Joaquim Alvino de Mesquita Neto Date: Thu, 11 Apr 2024 13:48:56 +0200 Subject: [PATCH 1/4] generateSolution supports unity >= 2022 --- ...GenerateSolutionTaskIntegrationSpec.groovy | 22 ++++++++++++++++++- .../unity/tasks/GenerateSolution.groovy | 7 +++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy index 8e2ee5fc..403a9c83 100644 --- a/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy @@ -38,7 +38,7 @@ class GenerateSolutionTaskIntegrationSpec extends UnityTaskIntegrationSpec= 2019.2 + executeMethod = "Packages.Rider.Editor.RiderScriptEditor.SyncSolution" + } } } From 66961363da60b7140005fd1271bd03d12e10639d Mon Sep 17 00:00:00 2001 From: Joaquim Alvino de Mesquita Neto Date: Fri, 12 Apr 2024 15:19:26 +0200 Subject: [PATCH 2/4] generate solution now runs custom unity script 'DefaultSolutionGenerator', new task type RunCSScript --- ...GenerateSolutionTaskIntegrationSpec.groovy | 20 +++-- .../wooga/gradle/unity/UnityPlugin.groovy | 7 +- .../unity/tasks/GenerateSolution.groovy | 56 ++++++++++++-- .../gradle/unity/tasks/RunCSScript.groovy | 76 +++++++++++++++++++ .../resources/DefaultSolutionGenerator.cs | 47 ++++++++++++ 5 files changed, 191 insertions(+), 15 deletions(-) create mode 100644 src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy create mode 100644 src/main/resources/DefaultSolutionGenerator.cs diff --git a/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy index 403a9c83..add02d4d 100644 --- a/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/unity/tasks/GenerateSolutionTaskIntegrationSpec.groovy @@ -41,7 +41,11 @@ class GenerateSolutionTaskIntegrationSpec extends UnityTaskIntegrationSpec { task.group = GROUP task.projectManifestFile.convention(extension.projectManifestFile) task.upmPackages.putAll(extension.upmPackages) + //needed in order to be able to generate solutions + task.upmPackages.put("com.unity.ide.rider", "3.0.28") task.upmPackages.putAll(extension.enableTestCodeCoverage.map { it ? ["com.unity.testtools.codecoverage": "1.1.0"] : [:] }) @@ -406,9 +408,12 @@ class UnityPlugin implements Plugin { project.tasks.withType(Test).configureEach { testTask -> testTask.dependsOn(addUPMPackagesTask) } + project.tasks.withType(GenerateSolution).configureEach {genSolutionTask -> + genSolutionTask.dependsOn(addUPMPackagesTask) + } addUPMPackagesTask.configure { task -> task.onlyIf { - def upmPackageCount = task.upmPackages.forUseAtConfigurationTime().getOrElse([:]).size() + def upmPackageCount = task.upmPackages.getOrElse([:]).size() upmPackageCount > 0 } } diff --git a/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy b/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy index f0810e0f..f1f758d7 100644 --- a/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy +++ b/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy @@ -1,16 +1,58 @@ package wooga.gradle.unity.tasks -import wooga.gradle.unity.UnityTask +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.Optional + +class GenerateSolution extends RunCSScript { + private final DirectoryProperty assetsDir = objects.directoryProperty() + + @InputDirectory + @Optional + DirectoryProperty getAssetsDir() { + return assetsDir + } + + void setAssetsDir(Provider assetsDir) { + this.assetsDir.set(assetsDir) + } + + void setAssetsDir(Directory assetsDir) { + this.assetsDir.set(assetsDir) + } + + void setAssetsDir(File assetsDir) { + this.assetsDir.set(assetsDir) + } + + -class GenerateSolution extends UnityTask { GenerateSolution() { outputs.upToDateWhen { false } - if(unityVersion.majorVersion < 2022) { - executeMethod = "UnityEditor.SyncVS.SyncSolution" - } else { - //The rider package ships with unity >= 2019.2 - executeMethod = "Packages.Rider.Editor.RiderScriptEditor.SyncSolution" + + // Not the usual approach we take. Usually we would like to put the default in the plugin conventions and such, but this + // task seems to be designed to be independent from plugin configuration, so we still apply plugin configuration, + // but we set __sensible defaults__. + // This runs before the config block in the plugin, so it can and will be overwritten by plugin configuration when the plugin is applied as well + this.assetsDir.convention(this.projectDirectory.dir("Assets").map {it.asFile.mkdirs();return it}) + + def defaultScript = this.assetsDir + .map { it.file("SolutionGenerator.cs") } + .map { script -> + script.asFile.text = GenerateSolution.classLoader.getResourceAsStream("DefaultSolutionGenerator.cs").text + script.asFile.deleteOnExit() + return script } + this.sourceCsScript.convention(defaultScript) + this.destCsScript.convention(this.sourceCsScript) + this.executeMethod.set(project.provider { + unityVersion.majorVersion >= 2022? + "Wooga.UnityPlugin.DefaultSolutionGenerator.GenerateSolution" : + "UnityEditor.SyncVS.SyncSolution" + }) + } } diff --git a/src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy b/src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy new file mode 100644 index 00000000..5381f9e1 --- /dev/null +++ b/src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy @@ -0,0 +1,76 @@ +package wooga.gradle.unity.tasks + +import org.gradle.api.file.RegularFile +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import wooga.gradle.unity.UnityTask + +import java.nio.file.Files + +class RunCSScript extends UnityTask { + + private final RegularFileProperty sourceCsScript = objects.fileProperty() + + @InputFile + RegularFileProperty getSourceCsScript() { + return sourceCsScript + } + + void setSourceCsScript(Provider sourceCsScript) { + this.sourceCsScript.set(sourceCsScript) + } + + void setSourceCsScript(RegularFile sourceCsScript) { + this.sourceCsScript.set(sourceCsScript) + } + + void setSourceCsScript(File sourceCsScript) { + this.sourceCsScript.set(sourceCsScript) + } + + private final RegularFileProperty destCsScript = objects.fileProperty() + + @InputFile + RegularFileProperty getDestCsScript() { + return destCsScript + } + + void setDestCsScript(Provider destCsScript) { + this.destCsScript.set(destCsScript) + } + + void setDestCsScript(RegularFile destCsScript) { + this.destCsScript.set(destCsScript) + } + + void setDestCsScript(File destCsScript) { + this.destCsScript.set(destCsScript) + } + + @Override //this input is mandatory for this task, so overriding the previous annotation. + @Input + Property getExecuteMethod() { + return super.getExecuteMethod() + } + + RunCSScript() { +// finalizedBy(project.tasks.register("_${this.name}_cleanup") { +// onlyIf { +// destCsScript.present && destCsScript.get().asFile.file +// } +// doLast { generatorScript.get().asFile.delete() } +// }) + } + + @Override + protected void preExecute() { + Files.copy(sourceCsScript.get().asFile.toPath(), destCsScript.get().asFile.toPath()) + destCsScript.asFile.get().deleteOnExit() +// if(!executeMethod.present) { +// throw new IllegalArgumentException("'executeMethod' property should be present to run ") +// } + } +} diff --git a/src/main/resources/DefaultSolutionGenerator.cs b/src/main/resources/DefaultSolutionGenerator.cs new file mode 100644 index 00000000..00bd4d33 --- /dev/null +++ b/src/main/resources/DefaultSolutionGenerator.cs @@ -0,0 +1,47 @@ +//from https://forum.unity.com/threads/any-way-to-tell-unity-to-generate-the-sln-file-via-script-or-command-line.392314/ +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using Unity.CodeEditor; +using System.Reflection; + +// The recommended way to create the VisualStudio SLN from the command line is a call +// Unity.exe -executeMethod "UnityEditor.SyncVS.SyncSolution" +// +// Unfortunately, as of Unity 2021.3.21f1 the built-in UnityEditor.SyncVS.SyncSolution internally calls +// Unity.CodeEditor.CodeEditor.Editor.CurrentCodeEditor.SyncAll() where CurrentCodeEditor depends on the user preferences +// which may not actually be set to VS on a CI machine. +// (see https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/CodeEditor/SyncVS.cs) +// +// This routine provides an re-implementation that avoids reliability on the preference setting +// Unity.exe -executeMethod "UnityEditor.SyncVS.SyncSolution" +namespace Wooga.UnityPlugin { + public static class DefaultSolutionGenerator + { + public static void GenerateSolution() + { + // Ensure that the mono islands are up-to-date + AssetDatabase.Refresh(); + + List externalCodeEditors; + + // externalCodeEditors = Unity.CodeEditor.Editor.m_ExternalCodeEditors; + // ... unfortunately this is private without any means of access. Use reflection to get the value ... + externalCodeEditors = CodeEditor.Editor.GetType().GetField("m_ExternalCodeEditors", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(CodeEditor.Editor) as List; + + foreach (var externalEditor in externalCodeEditors) + { + var typeName = externalEditor.GetType().Name; + switch (typeName) + { + case "VisualStudioEditor": + case "RiderScriptEditor": + Debug.Log($"Generating solution with {typeName}"); + externalEditor.SyncAll(); + return; + } + } + Debug.LogError("no VisualStudioEditor (com.unity.ide.visualstudio) or RiderScriptEditor (com.unity.ide.rider) registered, can't generate solution"); + } + } +} From c3f12df6d5ab017152662fda2d9600edf57564bb Mon Sep 17 00:00:00 2001 From: Joaquim Alvino de Mesquita Neto Date: Tue, 16 Apr 2024 11:28:38 +0200 Subject: [PATCH 3/4] improved onlyIf and tests for addUpmPackage --- .../unity/UnityPluginIntegrationSpec.groovy | 36 ++++++++++++------- .../unity/tasks/ProjectManifestTask.groovy | 29 +++++++++------ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy index a3862e55..07cf26e2 100644 --- a/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy @@ -28,6 +28,7 @@ import com.wooga.spock.extensions.unity.UnityPluginTestOptions import spock.lang.Unroll import wooga.gradle.unity.models.ResolutionStrategy import wooga.gradle.unity.models.UnityCommandLineOption +import wooga.gradle.unity.models.UnityProjectManifest import wooga.gradle.unity.tasks.Test import wooga.gradle.unity.utils.ProjectSettingsFile @@ -139,7 +140,7 @@ class UnityPluginIntegrationSpec extends UnityIntegrationSpec { } @UnityPluginTestOptions(unityPath = UnityPathResolution.None, addPluginTestDefaults = false, - disableAutoActivateAndLicense = false) + disableAutoActivateAndLicense = false) @Unroll def "extension property :#property returns '#testValue' if #reason"() { given: "an applied plugin" @@ -353,8 +354,15 @@ class UnityPluginIntegrationSpec extends UnityIntegrationSpec { } @Unroll - def "runs addUPMPackages task if there are packages to add"() { + def "runs addUPMPackages task"() { given: + new File(projectDir, manifestFile).with { + delete() + if (hasManifest) { + parentFile.mkdirs() + text = new UnityProjectManifest([:]).serialize() + } + } buildFile << """ unity { enableTestCodeCoverage = ${testCoverageEnabled} @@ -366,15 +374,19 @@ class UnityPluginIntegrationSpec extends UnityIntegrationSpec { then: shouldRun ? - result.wasExecuted("addUPMPackages") : - result.standardOutput.contains("Task :addUPMPackages SKIPPED") + result.wasExecuted("addUPMPackages") : + result.standardOutput.contains("Task :addUPMPackages SKIPPED") where: - testCoverageEnabled | packagesToInstall | shouldRun - false | [:] | false - false | ["package": "ver"] | true - true | [:] | true - true | ["package": "ver"] | true + hasManifest | testCoverageEnabled | packagesToInstall | shouldRun + false | false | [:] | false + true | false | [:] | true + true | false | ["package": "ver"] | true + false | false | ["package": "ver"] | true + true | true | [:] | true + true | true | ["package": "ver"] | true + false | true | ["package": "ver"] | true + manifestFile = "Packages/manifest.json" } @Unroll @@ -395,9 +407,9 @@ class UnityPluginIntegrationSpec extends UnityIntegrationSpec { "" | null | PropertyLocation.environment setter = new PropertySetterWriter("unity", "resolutionStrategy") - .set(value, String) - .withKeyComposedFrom("unity") - .to(location) + .set(value, String) + .withKeyComposedFrom("unity") + .to(location) getter = new PropertyGetterTaskWriter(setter) } diff --git a/src/main/groovy/wooga/gradle/unity/tasks/ProjectManifestTask.groovy b/src/main/groovy/wooga/gradle/unity/tasks/ProjectManifestTask.groovy index 9d5788e1..7539f8ff 100644 --- a/src/main/groovy/wooga/gradle/unity/tasks/ProjectManifestTask.groovy +++ b/src/main/groovy/wooga/gradle/unity/tasks/ProjectManifestTask.groovy @@ -14,20 +14,27 @@ abstract class ProjectManifestTask extends DefaultTask implements abstract void modifyProjectManifest(UnityProjectManifest manifest) + ProjectManifestTask() { + onlyIf { + def manifestFile = projectManifestFile.asFile.getOrNull() + def condition = manifestFile && manifestFile.exists() + if(!condition) { + project.logger.warn("${manifestFile.name} not found, skipping UPM packages install") + } + return condition + } + } + @TaskAction void execute() { def manifestFile = projectManifestFile.asFile.getOrNull() - if (manifestFile && manifestFile.exists()) { - // Deserialize - def manifest = UnityProjectManifest.deserialize(manifestFile) - // Modify - modifyProjectManifest(manifest) - // Serialize - def serialization = manifest.serialize() - manifestFile.write(serialization) - } else { - project.logger.warn("${manifestFileName} not found, skipping UPM packages install: ${upmPackages.get()}") - } + // Deserialize + def manifest = UnityProjectManifest.deserialize(manifestFile) + // Modify + modifyProjectManifest(manifest) + // Serialize + def serialization = manifest.serialize() + manifestFile.write(serialization) } } From 50f4b3558087a2fec8eb7324abf848b8bf47d9cb Mon Sep 17 00:00:00 2001 From: Joaquim Alvino de Mesquita Neto Date: Mon, 22 Apr 2024 16:41:21 +0200 Subject: [PATCH 4/4] some renames, irons out the Add UPM packages tasks --- .../unity/UnityPluginIntegrationSpec.groovy | 22 +++++ .../wooga/gradle/unity/UnityPlugin.groovy | 40 +++++---- .../unity/models/UnityProjectManifest.groovy | 8 +- .../gradle/unity/tasks/AddUPMPackages.groovy | 6 ++ .../unity/tasks/ExecuteCsharpScript.groovy | 81 ++++++++++++++++++ .../unity/tasks/GenerateSolution.groovy | 9 +- .../gradle/unity/tasks/RunCSScript.groovy | 82 ------------------- .../unity/traits/AddUnityPackagesSpec.groovy | 21 ++++- 8 files changed, 161 insertions(+), 108 deletions(-) create mode 100644 src/main/groovy/wooga/gradle/unity/tasks/ExecuteCsharpScript.groovy delete mode 100644 src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy diff --git a/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy index 7bbde0e4..a8e3430b 100644 --- a/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/unity/UnityPluginIntegrationSpec.groovy @@ -457,6 +457,28 @@ class UnityPluginIntegrationSpec extends UnityIntegrationSpec { result.wasExecuted("generateSolution") } + @UnityPluginTestOptions(forceMockTaskRun = false, disableAutoActivateAndLicense = false) + def "add IDE UPM package when running generateSolution task"() { + given: + def manifestFile = new File(projectDir, "Packages/manifest.json").with { + parentFile.mkdirs() + text = new UnityProjectManifest([:]).serialize() + return it + } + + when: + def result = runTasksSuccessfully("generateSolution") + then: + result.wasExecuted("addIdeUPMPackage") + result.wasExecuted("generateSolution") + def deps = UnityProjectManifest.deserialize(manifestFile).getDependencies() + deps[expectedPackageName] == expectedPackageVersion + + where: + expectedPackageName = "com.unity.ide.rider" + expectedPackageVersion = "3.0.28" + } + @Unroll def "runs addUPMPackages task"() { given: diff --git a/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy b/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy index d6d0eafb..6e11304a 100644 --- a/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy +++ b/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy @@ -89,6 +89,7 @@ class UnityPlugin implements Plugin { generateSolution(GenerateSolution), ensureProjectManifest(Unity), addUPMPackages(AddUPMPackages), + addIdeUPMPackage(AddUPMPackages), setResolutionStrategy(SetResolutionStrategy) private final Class taskClass @@ -243,7 +244,7 @@ class UnityPlugin implements Plugin { addTestTasks(project, extension) addSetAPICompatibilityLevelTasks(project, extension) addGenerateSolutionTask(project) - addAddUPMPackagesTask(project, extension) + addAddUPMPackageTasks(project, extension) addActivateAndReturnLicenseTasks(project, extension) } @@ -413,28 +414,37 @@ class UnityPlugin implements Plugin { } } - private static void addAddUPMPackagesTask(Project project, final UnityPluginExtension extension) { - def addUPMPackagesTask = project.tasks.register(Tasks.addUPMPackages.toString(), AddUPMPackages) { task -> - task.group = GROUP + private static void addAddUPMPackageTasks(Project project, final UnityPluginExtension extension) { + project.tasks.withType(AddUPMPackages).configureEach { task -> + onlyIf { + def upmPackageCount = task.upmPackages.getOrElse([:]).size() + + task.conventionUpmPackages.getOrElse([:]).size() + if(upmPackageCount == 0) { + logger.info("No UPM packages to install, skipping") + } + return upmPackageCount > 0 + } task.projectManifestFile.convention(extension.projectManifestFile) - task.upmPackages.putAll(extension.upmPackages) - //needed in order to be able to generate solutions - task.upmPackages.put("com.unity.ide.rider", "3.0.28") - task.upmPackages.putAll(extension.enableTestCodeCoverage.map { + } + + def addUPMPackagesTask = project.tasks.register(Tasks.addUPMPackages.toString(), AddUPMPackages) { it -> + it.group = GROUP + it.upmPackages.putAll(extension.upmPackages) + //needed in order to have coverage reports + //TODO: breaking change, detach this similar to addIdeUpmPackage and GenerateSolution + it.conventionUpmPackages.putAll(extension.enableTestCodeCoverage.map { it ? ["com.unity.testtools.codecoverage": "1.1.0"] : [:] }) } project.tasks.withType(Test).configureEach { testTask -> testTask.dependsOn(addUPMPackagesTask) } - project.tasks.withType(GenerateSolution).configureEach {genSolutionTask -> - genSolutionTask.dependsOn(addUPMPackagesTask) + + def addIdeUPMPackage = project.tasks.register(Tasks.addIdeUPMPackage.toString(), AddUPMPackages) { + it.conventionUpmPackages.putAll(["com.unity.ide.rider": "3.0.28"]) } - addUPMPackagesTask.configure { task -> - task.onlyIf { - def upmPackageCount = task.upmPackages.getOrElse([:]).size() - upmPackageCount > 0 - } + project.tasks.withType(GenerateSolution).configureEach {genSolutionTask -> + genSolutionTask.dependsOn(addIdeUPMPackage) } } diff --git a/src/main/groovy/wooga/gradle/unity/models/UnityProjectManifest.groovy b/src/main/groovy/wooga/gradle/unity/models/UnityProjectManifest.groovy index 463c6137..52236153 100644 --- a/src/main/groovy/wooga/gradle/unity/models/UnityProjectManifest.groovy +++ b/src/main/groovy/wooga/gradle/unity/models/UnityProjectManifest.groovy @@ -51,14 +51,14 @@ class UnityProjectManifest extends HashMap implements GroovyInte Map getDependencies() { if (!containsKey(dependenciesKey)) { - this[dependenciesKey] = [:] + setDependencies([:]) } (Map)this[dependenciesKey] } void setDependencies(Map map) { - this[dependenciesKey] = map + this.put(dependenciesKey, map) } void addDependencies(Map map) { @@ -68,6 +68,10 @@ class UnityProjectManifest extends HashMap implements GroovyInte void addDependency(String key, Object value) { getDependencies()[key] = value } + + Object getDependencyVersion(String key) { + return getDependencies()[key] + } } diff --git a/src/main/groovy/wooga/gradle/unity/tasks/AddUPMPackages.groovy b/src/main/groovy/wooga/gradle/unity/tasks/AddUPMPackages.groovy index d3333e9d..a776819b 100644 --- a/src/main/groovy/wooga/gradle/unity/tasks/AddUPMPackages.groovy +++ b/src/main/groovy/wooga/gradle/unity/tasks/AddUPMPackages.groovy @@ -45,6 +45,12 @@ class AddUPMPackages extends ProjectManifestTask @Override void modifyProjectManifest(UnityProjectManifest manifest) { + conventionUpmPackages.getOrElse([:]).each { + if(!manifest.getDependencyVersion(it.key)) { + manifest.addDependency(it.key, it.value) + } + } manifest.addDependencies(upmPackages.get()) + } } diff --git a/src/main/groovy/wooga/gradle/unity/tasks/ExecuteCsharpScript.groovy b/src/main/groovy/wooga/gradle/unity/tasks/ExecuteCsharpScript.groovy new file mode 100644 index 00000000..a41c3dbd --- /dev/null +++ b/src/main/groovy/wooga/gradle/unity/tasks/ExecuteCsharpScript.groovy @@ -0,0 +1,81 @@ +package wooga.gradle.unity.tasks + +import org.gradle.api.file.RegularFile +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import wooga.gradle.unity.UnityTask + +import java.nio.file.Files + +/** + * Copies a script from {@code sourceScript} into a temporary {@code destinationScript} then executes Unity with {@code executeMethod} + */ +class ExecuteCsharpScript extends UnityTask { + + private final RegularFileProperty sourceScript = objects.fileProperty() + + @InputFile + RegularFileProperty getSourceScript() { + return sourceScript + } + + void setSourceScript(Provider sourceCsScript) { + this.sourceScript.set(sourceCsScript) + } + + void setSourceScript(RegularFile sourceCsScript) { + this.sourceScript.set(sourceCsScript) + } + + void setSourceScript(File sourceCsScript) { + this.sourceScript.set(sourceCsScript) + } + + private final RegularFileProperty destinationScript = objects.fileProperty() + + @InputFile + RegularFileProperty getDestinationScript() { + return destinationScript + } + + void setDestinationScript(Provider destCsScript) { + this.destinationScript.set(destCsScript) + } + + void setDestinationScript(RegularFile destCsScript) { + this.destinationScript.set(destCsScript) + } + + void setDestinationScript(File destCsScript) { + this.destinationScript.set(destCsScript) + } + + @Override //this input is mandatory for this task, so overriding the previous annotation. + @Input + Property getExecuteMethod() { + return super.getExecuteMethod() + } + + ExecuteCsharpScript() { + finalizedBy(project.tasks.register("_${this.name}_cleanup") { + onlyIf { + destinationScript.present && destinationScript.get().asFile.file + } + doLast { + def baseFile = destinationScript.get().asFile + def metafile = new File(baseFile.absolutePath + ".meta") + baseFile.delete() + metafile.delete() + } + }) + } + + @Override + protected void preExecute() { + Files.copy(sourceScript.get().asFile.toPath(), destinationScript.get().asFile.toPath()) + destinationScript.asFile.get().deleteOnExit() + } +} diff --git a/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy b/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy index f1f758d7..c5b939e9 100644 --- a/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy +++ b/src/main/groovy/wooga/gradle/unity/tasks/GenerateSolution.groovy @@ -6,7 +6,7 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.Optional -class GenerateSolution extends RunCSScript { +class GenerateSolution extends ExecuteCsharpScript { private final DirectoryProperty assetsDir = objects.directoryProperty() @InputDirectory @@ -27,9 +27,6 @@ class GenerateSolution extends RunCSScript { this.assetsDir.set(assetsDir) } - - - GenerateSolution() { outputs.upToDateWhen { false } @@ -46,8 +43,8 @@ class GenerateSolution extends RunCSScript { script.asFile.deleteOnExit() return script } - this.sourceCsScript.convention(defaultScript) - this.destCsScript.convention(this.sourceCsScript) + this.sourceScript.convention(defaultScript) + this.destinationScript.convention(this.sourceScript) this.executeMethod.set(project.provider { unityVersion.majorVersion >= 2022? "Wooga.UnityPlugin.DefaultSolutionGenerator.GenerateSolution" : diff --git a/src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy b/src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy deleted file mode 100644 index da92b617..00000000 --- a/src/main/groovy/wooga/gradle/unity/tasks/RunCSScript.groovy +++ /dev/null @@ -1,82 +0,0 @@ -package wooga.gradle.unity.tasks - -import org.gradle.api.file.RegularFile -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile -import wooga.gradle.unity.UnityTask - -import java.nio.file.Files - -class RunCSScript extends UnityTask { - - private final RegularFileProperty sourceCsScript = objects.fileProperty() - - @InputFile - RegularFileProperty getSourceCsScript() { - return sourceCsScript - } - - void setSourceCsScript(Provider sourceCsScript) { - this.sourceCsScript.set(sourceCsScript) - } - - void setSourceCsScript(RegularFile sourceCsScript) { - this.sourceCsScript.set(sourceCsScript) - } - - void setSourceCsScript(File sourceCsScript) { - this.sourceCsScript.set(sourceCsScript) - } - - private final RegularFileProperty destCsScript = objects.fileProperty() - - @InputFile - RegularFileProperty getDestCsScript() { - return destCsScript - } - - void setDestCsScript(Provider destCsScript) { - this.destCsScript.set(destCsScript) - } - - void setDestCsScript(RegularFile destCsScript) { - this.destCsScript.set(destCsScript) - } - - void setDestCsScript(File destCsScript) { - this.destCsScript.set(destCsScript) - } - - @Override //this input is mandatory for this task, so overriding the previous annotation. - @Input - Property getExecuteMethod() { - return super.getExecuteMethod() - } - - RunCSScript() { - finalizedBy(project.tasks.register("_${this.name}_cleanup") { - onlyIf { - destCsScript.present && destCsScript.get().asFile.file - } - doLast { - def baseFile = destCsScript.get().asFile - def metafile = new File(baseFile.absolutePath + ".meta") - baseFile.delete() - metafile.delete() - - } - }) - } - - @Override - protected void preExecute() { - Files.copy(sourceCsScript.get().asFile.toPath(), destCsScript.get().asFile.toPath()) - destCsScript.asFile.get().deleteOnExit() -// if(!executeMethod.present) { -// throw new IllegalArgumentException("'executeMethod' property should be present to run ") -// } - } -} diff --git a/src/main/groovy/wooga/gradle/unity/traits/AddUnityPackagesSpec.groovy b/src/main/groovy/wooga/gradle/unity/traits/AddUnityPackagesSpec.groovy index 6423d10c..5f9608ac 100644 --- a/src/main/groovy/wooga/gradle/unity/traits/AddUnityPackagesSpec.groovy +++ b/src/main/groovy/wooga/gradle/unity/traits/AddUnityPackagesSpec.groovy @@ -2,11 +2,8 @@ package wooga.gradle.unity.traits import com.wooga.gradle.BaseSpec import org.gradle.api.provider.MapProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional -import wooga.gradle.unity.models.ResolutionStrategy trait AddUnityPackagesSpec extends BaseSpec { @@ -28,5 +25,23 @@ trait AddUnityPackagesSpec extends BaseSpec { void setUpmPackages(Map values) { upmPackages.set(values) } + + @Input + @Optional + MapProperty getConventionUpmPackages() { + conventionUpmPackages + } + + private final MapProperty conventionUpmPackages = objects.mapProperty(String, String) + + void setConventionUpmPackages(MapProperty values) { + conventionUpmPackages.set(values) + } + + void setConventionUpmPackages(Map values) { + conventionUpmPackages.set(values) + } + + }