Skip to content

Commit

Permalink
Add task to set the project package resolution strategy (#171)
Browse files Browse the repository at this point in the history
## Description
Adds task to modify the project package resolution strategy, `setResolutionStrategy`, according to this:
(https://docs.unity3d.com/Manual/upm-manifestPrj.html#resolutionStrategy)

The task class derives from a base `ProjectManifestTask`, which is now shared with the existing `AddUpmPackages` task that was previously implemented. 

## Changes
* ![ADD] `setResolutionStrategy` plugin task
* ![IMPROVE] `AddUPMPackages` task base layout into a base task, `ProjectManifestTask`
  • Loading branch information
Azurelol authored Jan 17, 2023
1 parent e4b02a7 commit 2a72e9a
Show file tree
Hide file tree
Showing 21 changed files with 663 additions and 166 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ github {

dependencies {

api 'com.wooga.gradle:gradle-commons:[1.6.3,2['
api 'com.wooga.gradle:gradle-commons:[1.7.0,2['
implementation 'org.apache.maven:maven-artifact:3.8.5'
implementation "org.yaml:snakeyaml:1.30"
implementation 'net.wooga:unity-version-manager-jni:[1,2['
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ import com.wooga.gradle.PlatformUtils
import com.wooga.gradle.PropertyUtils
import com.wooga.gradle.test.PropertyLocation
import com.wooga.gradle.test.PropertyQueryTaskWriter
import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
import com.wooga.gradle.test.writers.PropertySetterWriter
import com.wooga.spock.extensions.unity.UnityPathResolution
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.tasks.Test
import wooga.gradle.unity.utils.ProjectSettingsFile
Expand Down Expand Up @@ -374,4 +377,42 @@ class UnityPluginIntegrationSpec extends UnityIntegrationSpec {
true | ["package": "ver"] | true
}

@Unroll
def "sets extension resolution strategy #value #location"() {

when:
def query = runPropertyQuery(getter, setter)

then:
query.matches(expected != _ ? expected : value)

where:
value | expected | location
ResolutionStrategy.lowest | _ | PropertyLocation.script
ResolutionStrategy.highest | _ | PropertyLocation.script
ResolutionStrategy.lowest | _ | PropertyLocation.property
ResolutionStrategy.highestMinor | _ | PropertyLocation.environment
"" | null | PropertyLocation.environment

setter = new PropertySetterWriter("unity", "resolutionStrategy")
.set(value, String)
.withKeyComposedFrom("unity")
.to(location)
getter = new PropertyGetterTaskWriter(setter)
}

@UnityPluginTestOptions(forceMockTaskRun = false)
@Unroll
def "task to ensure the project manifest is invoked before running #taskName"() {

when:
def result = runTasks(taskName)

then:
result.wasExecuted(ensureTaskName)

where:
taskName << ["setResolutionStrategy", "addUPMPackages"]
ensureTaskName = "ensureProjectManifest"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package wooga.gradle.unity

import com.wooga.gradle.PlatformUtils
import com.wooga.gradle.test.PropertyQueryTaskWriter
import com.wooga.gradle.test.TaskIntegrationSpec
import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
import com.wooga.gradle.test.writers.PropertySetterWriter
import org.gradle.api.logging.LogLevel
Expand All @@ -31,32 +32,14 @@ import java.lang.reflect.ParameterizedType
import java.nio.file.Files
import java.nio.file.StandardCopyOption

abstract class UnityTaskIntegrationSpec<T extends UnityTask> extends UnityIntegrationSpec {

Class<T> getSubjectUnderTestClass() {
if (!_sutClass) {
try {
this._sutClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
catch (Exception e) {
this._sutClass = (Class<T>) Unity
}
}
_sutClass
}
private Class<T> _sutClass

abstract class UnityTaskIntegrationSpec<T extends UnityTask> extends UnityIntegrationSpec
implements TaskIntegrationSpec<T>
{
@Override
String getSubjectUnderTestName() {
"${subjectUnderTestClass.simpleName.uncapitalize()}Test"
}

@Override
String getSubjectUnderTestTypeName() {
subjectUnderTestClass.getTypeName()
}

@Unroll
def "can set option '#property' (#value) with #method"() {
given: "a custom build task"
Expand Down Expand Up @@ -275,28 +258,23 @@ abstract class UnityTaskIntegrationSpec<T extends UnityTask> extends UnityIntegr
}

@Unroll
def "redirects unity log to stdout when redirectStdOut is set to true for #taskType"() {
given: "a custom build task"
def "redirects ? (#value) unity log to stdout when #propertyName is set to #value"() {

given: "the property is set"
appendToSubjectTask("""
logToStdout = false
${propertyName} = ${wrapValueBasedOnType(value, Boolean)}
""".stripIndent())

when:
def result = runTasks(subjectUnderTestName)

then:
def stdOut = GradleRunResult.taskLog(subjectUnderTestName, result.standardOutput)
!stdOut.contains(mockUnityStartupMessage)

when:
appendToSubjectTask("""
logToStdout = true
""".stripIndent())
result = runTasks(subjectUnderTestName)
value == stdOut.contains(mockUnityStartupMessage)

then:
def taskLog = GradleRunResult.taskLog(subjectUnderTestName, result.standardOutput)
taskLog.contains(mockUnityStartupMessage)
where:
propertyName = "logToStdout"
value << [true, false]
}

def "redirects unity log to stdout and custom logfile if provided"() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,71 @@
package wooga.gradle.unity.tasks


import com.wooga.gradle.test.queries.TestValue
import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
import com.wooga.gradle.test.writers.PropertySetterWriter
import com.wooga.spock.extensions.unity.UnityPathResolution
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import com.wooga.spock.extensions.uvm.UnityInstallation
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import net.wooga.uvm.Installation
import org.gradle.api.file.Directory
import spock.lang.Requires
import wooga.gradle.unity.UnityTaskIntegrationSpec
import spock.lang.Unroll

class AddUPMPackagesTaskIntegrationSpec extends ProjectManifestTaskSpec<AddUPMPackages> {

class AddUPMPackagesTaskIntegrationSpec extends UnityTaskIntegrationSpec<AddUPMPackages> {
@Unroll
def "can set property #propertyName with #type"() {
expect:
runPropertyQuery(getter, setter).matches(value)

where:
propertyName | type | value
// TODO: This property will be deprecated. Remove when possible.
"manifestPath" | File | TestValue.projectFile("foobar")

setter = new PropertySetterWriter(subjectUnderTestName, propertyName)
.set(value, type)
getter = new PropertyGetterTaskWriter(setter)
}

@Requires({ os.macOs })
@UnityPluginTestOptions(unityPath = UnityPathResolution.Default)
@UnityInstallation(version = "2019.4.19f1", cleanup = false)
def "creates unity manifest and adds package to it when running AddUPMTask task"(Installation unity) {

given: "an unity3D project"
def projectPath = "build/test_project"
def projectPath = "test_project"
environmentVariables.set("UNITY_PATH", unity.getExecutable().getPath())
buildFile << """
unity {
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
}
""".stripIndent()


and: "a task to create the project"
def createProjectTask = "projectMachen"
addTask(createProjectTask, CreateProject, true, """
buildTarget = "Android"
""")

//Test using the extension
and: "a setup AddUPMPackageTask"
appendToSubjectTask("""
createProject = "${projectPath}"
manifestPath = new File("${projectPath}/Packages/manifest.json")
buildTarget = "Android"
when: "creating the project"
runTasksSuccessfully(createProjectTask)

and: "a task to add the packages"
def addPackagesTask = "langsamerHund"
writeTask(addPackagesTask, AddUPMPackages, {
it.withLines("""
upmPackages.put("com.unity.testtools.codecoverage", "1.1.0")
upmPackages.put("com.unity.package", "anyString")
""".stripIndent()
)
""".stripIndent())
})

when: "add UPM packages"
runTasksSuccessfully(subjectUnderTestName)
then: "running the tasks"
runTasksSuccessfully(addPackagesTask)

then: "manifest file is generated"
def manifestFile = new File(new File(projectDir, projectPath), "Packages/manifest.json")
Expand All @@ -54,21 +87,24 @@ class AddUPMPackagesTaskIntegrationSpec extends UnityTaskIntegrationSpec<AddUPMP
def packages = ["com.unity.testtools.codecoverage": "1.1.0"]
manifestFile << JsonOutput.toJson(["dependencies": packages])

and: "a setup AddUPMPackageTask"
appendToSubjectTask("""
buildTarget = "Android"
manifestPath = new File("build/test_project/Packages/custom/manifest.json")
and: "configuration of the AddUPMPackageTask"
addTask(taskName, AddUPMPackages, true, """
manifestPath = new File(${wrapValueBasedOnType(manifestPath, String)})
upmPackages.put("com.unity.package", "anyString")
""".stripIndent()
)

when: "add UPM packages"
runTasksSuccessfully(subjectUnderTestName)
runTasksSuccessfully(taskName)

then: "manifest file contains added packages"
def dependencies = new JsonSlurper().parse(manifestFile)["dependencies"]
dependencies["com.unity.testtools.codecoverage"] == "1.1.0"
dependencies["com.unity.package"] == "anyString"

where:
taskName = "addPackagesTask"
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CreateProjectTaskIntegrationSpec extends UnityTaskIntegrationSpec<CreatePr
def projectPath = "Wooga.Foobar"
buildFile << """
unity {
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
}
""".stripIndent()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package wooga.gradle.unity.tasks

import com.wooga.gradle.test.TaskIntegrationSpec
import com.wooga.gradle.test.queries.TestValue
import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
import com.wooga.gradle.test.writers.PropertySetterWriter
import spock.lang.Unroll
import wooga.gradle.unity.UnityIntegrationSpec

abstract class ProjectManifestTaskSpec<T extends ProjectManifestTask>
extends UnityIntegrationSpec
implements TaskIntegrationSpec<T> {

@Override
String getSubjectUnderTestName() {
return "${super.getSubjectUnderTestName()}Test"
}

@Unroll
def "can set property #propertyName with #type"() {
expect:
runPropertyQuery(getter, setter).matches(value)

where:
propertyName | type | value
"projectManifestFile" | File | TestValue.projectFile("foobar")
"projectLockFile" | File | TestValue.projectFile("foobar")

setter = new PropertySetterWriter(subjectUnderTestName, propertyName)
.set(value, type)
getter = new PropertyGetterTaskWriter(setter)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package wooga.gradle.unity.tasks


import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
import com.wooga.gradle.test.writers.PropertySetterWriter
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import spock.lang.Unroll
import wooga.gradle.unity.models.ResolutionStrategy

class SetResolutionStrategyTaskIntegrationSpec extends ProjectManifestTaskSpec<SetResolutionStrategy> {

@Unroll
def "can set property #propertyName with #type"() {
expect:
runPropertyQuery(getter, setter).matches(value)

where:
propertyName | type | value
"resolutionStrategy" | String | ResolutionStrategy.lowest
"resolutionStrategy" | String | ResolutionStrategy.highest

setter = new PropertySetterWriter(subjectUnderTestName, propertyName)
.set(value, type)
getter = new PropertyGetterTaskWriter(setter)
}

@UnityPluginTestOptions(forceMockTaskRun = false)
def "skips when the resolution strategy is not set"() {

when:
def result = runTasks(subjectUnderTestName)

then:
result.wasSkipped(subjectUnderTestName)
}

@UnityPluginTestOptions(forceMockTaskRun = false)
@Unroll
def "#verb the resolution strategy #strategy"() {

given: "an unity project with the manifest file set"
def manifestPath = "build/test_project/Packages/manifest.json"
def manifestFile = new File(projectDir, manifestPath)
manifestFile.parentFile.mkdirs()
manifestFile.createNewFile()

and: "an existing manifest file"
def packages = ["com.unity.ugui": "1.0.0"]

Map<String, Object> manifestContents = [
"dependencies": packages
]
if (originalStrategy != _) {
manifestContents["resolutionStrategy"] = originalStrategy
}
manifestFile << JsonOutput.toJson(manifestContents)

and: "task configuration"
appendToSubjectTask("""
resolutionStrategy = ${wrapValueBasedOnType(strategy, String)}
projectManifestFile = ${wrapValueBasedOnType(manifestPath, File)}
""".stripIndent()
)

when:
runTasksSuccessfully(subjectUnderTestName)

then: "manifest file contains resolution strategy"
def actual = new JsonSlurper().parse(manifestFile)["resolutionStrategy"]
actual == strategy

where:
originalStrategy | strategy
"katzen" | "highestMinor"
_ | "highestMinor"
_ | "lowest"
"highest" | "highestPatch"

verb = originalStrategy != _ ? "overrides" : "sets"
}
}
Loading

0 comments on commit 2a72e9a

Please sign in to comment.