Skip to content

Commit

Permalink
Add task to set the project package resolution strategy
Browse files Browse the repository at this point in the history
- Add generic task to modify the project manifest file
- Add plugin task to ensure there's a package manifest
  • Loading branch information
Azurelol committed Jan 6, 2023
1 parent 24f3832 commit 5d7a831
Show file tree
Hide file tree
Showing 18 changed files with 518 additions and 139 deletions.
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 resolution strategy #value #location"() {

when:
def query = runPropertyQuery(getter, setter)

then:
query.matches(value)

where:
value | location
ResolutionStrategy.highest | PropertyLocation.script
ResolutionStrategy.lowest | PropertyLocation.script
ResolutionStrategy.lowest | PropertyLocation.property
ResolutionStrategy.highestMinor | PropertyLocation.environment

setter = new PropertySetterWriter("setResolutionStrategy", "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 @@ -275,28 +275,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
Expand Up @@ -6,33 +6,48 @@ 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.UnityIntegrationSpec
import wooga.gradle.unity.UnityTaskIntegrationSpec

class AddUPMPackagesTaskIntegrationSpec extends UnityTaskIntegrationSpec<AddUPMPackages> {

class AddUPMPackagesTaskIntegrationSpec extends UnityTaskIntegrationSpec {

@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"
""")

when: "creating the project"
runTasksSuccessfully(createProjectTask)

//Test using the extension
and: "a setup AddUPMPackageTask"
appendToSubjectTask("""
createProject = "${projectPath}"
manifestPath = new File("${projectPath}/Packages/manifest.json")
buildTarget = "Android"
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 +69,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 = "schonerKatzen"
}
}


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,72 @@
package wooga.gradle.unity.tasks

import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import spock.lang.Unroll
import wooga.gradle.unity.UnityIntegrationSpec
import wooga.gradle.unity.UnityPluginTest
import wooga.gradle.unity.UnityTaskIntegrationSpec

class SetResolutionStrategyTaskIntegrationSpec extends UnityIntegrationSpec {

@Override
String getSubjectUnderTestTypeName() {
SetResolutionStrategy.class.name
}

@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"
}
}
71 changes: 64 additions & 7 deletions src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package wooga.gradle.unity

import com.wooga.gradle.PropertyLookup
import org.apache.maven.artifact.versioning.ArtifactVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
Expand All @@ -32,16 +33,20 @@ import wooga.gradle.unity.internal.InputFileTreeFactory
import wooga.gradle.unity.models.APICompatibilityLevel
import wooga.gradle.unity.models.DefaultUnityAuthentication
import wooga.gradle.unity.internal.DefaultUnityPluginExtension
import wooga.gradle.unity.models.ResolutionStrategy
import wooga.gradle.unity.models.TestPlatform
import wooga.gradle.unity.models.UnityCommandLineOption
import wooga.gradle.unity.tasks.Activate
import wooga.gradle.unity.tasks.AddUPMPackages
import wooga.gradle.unity.tasks.GenerateSolution
import wooga.gradle.unity.tasks.GenerateUpmPackage
import wooga.gradle.unity.tasks.ProjectManifestTask
import wooga.gradle.unity.tasks.SetResolutionStrategy
import wooga.gradle.unity.tasks.ReturnLicense
import wooga.gradle.unity.tasks.SetAPICompatibilityLevel
import wooga.gradle.unity.tasks.Test
import wooga.gradle.unity.tasks.Unity
import wooga.gradle.unity.utils.ProjectSettingsFile
import wooga.gradle.unity.utils.UnityVersionManager

/**
* A {@link org.gradle.api.Plugin} which provides tasks to run unity batch-mode commands.
Expand Down Expand Up @@ -79,7 +84,9 @@ class UnityPlugin implements Plugin<Project> {
setAPICompatibilityLevel(APICompatibilityLevel),
unsetAPICompatibilityLevel(APICompatibilityLevel),
generateSolution(GenerateSolution),
addUPMPackages(AddUPMPackages)
ensureProjectManifest(Unity),
addUPMPackages(AddUPMPackages),
setResolutionStrategy(SetResolutionStrategy)

private final Class taskClass

Expand Down Expand Up @@ -138,6 +145,13 @@ class UnityPlugin implements Plugin<Project> {
return new ProjectSettingsFile(file)
}))

// Packages
extension.packagesDir.convention(extension.projectDirectory.dir("Packages"))
extension.projectManifestFile.convention(extension.packagesDir.file(ProjectManifestTask.manifestFileName))
//extension.projectManifestFile.convention(project.layout.projectDirectory.file("Packages/manifest.json"))
extension.projectLockFile.convention(extension.packagesDir.file(ProjectManifestTask.lockFileName))
extension.resolutionStrategy.convention(UnityPluginConventions.resolutionStrategy.getEnumValueProvider(project, ResolutionStrategy))

// Command line options
extension.enableTestCodeCoverage.convention(UnityPluginConventions.enableTestCodeCoverage.getBooleanValueProvider(project))
}
Expand Down Expand Up @@ -382,10 +396,9 @@ class UnityPlugin implements Plugin<Project> {
}

private static void addAddUPMPackagesTask(Project project, final UnityPluginExtension extension) {
def manifestFile = project.layout.projectDirectory.file("Packages/manifest.json")
def addUPMPackagesTask = project.tasks.register(Tasks.addUPMPackages.toString(), AddUPMPackages) { task ->
task.group = GROUP
task.manifestPath.convention(manifestFile)
task.projectManifestFile.convention(extension.projectManifestFile)
task.upmPackages.putAll(extension.upmPackages)
task.upmPackages.putAll(extension.enableTestCodeCoverage.map {
it ? ["com.unity.testtools.codecoverage": "1.1.0"] : [:]
Expand All @@ -403,9 +416,53 @@ class UnityPlugin implements Plugin<Project> {
}

private static void configurePackageTasks(UnityPluginExtension extension, final Project project) {
// TODO: Perhaps hook the task to generate meta files
project.tasks.withType(GenerateUpmPackage).configureEach({ t ->
})

// Only execute for >= 2018.3
def upmIsSupported = new Spec<Task>() {
@Override
boolean isSatisfiedBy(Task o) {
def deducedUnityVersion = getUnityVersion(extension, project)
Boolean supported = deducedUnityVersion.majorVersion > 2018 ||
(deducedUnityVersion.majorVersion == 2018 && deducedUnityVersion.minorVersion > 3)
if (!supported) {
project.logger.warn("The unity version (${deducedUnityVersion.majorVersion}.${deducedUnityVersion.minorVersion}) " +
"does not support UPM packages, skipping")
}
supported
}
}

// This task will ensure there's an unity project manifest if none are present
// It will be depended on by other tasks that need to modify the manifest
def ensureProjectManifest = project.tasks.register(Tasks.ensureProjectManifest.toString(), Unity) { t ->
t.setCacheServerEnableUpload(false)
t.batchMode.set(true)
t.onlyIf(new Spec<Unity>() {
@Override
boolean isSatisfiedBy(Unity task) {
!extension.projectManifestFile.get().asFile.exists()
}
})
}

// Make sure the tasks that depend on a project manifest have it
project.tasks.withType(ProjectManifestTask).configureEach { t ->
t.dependsOn(ensureProjectManifest)
t.projectManifestFile.convention(extension.projectManifestFile)
t.projectLockFile.convention(extension.projectLockFile)
t.onlyIf upmIsSupported
}

// Create a task to set the resolution strategy
project.tasks.register(Tasks.setResolutionStrategy.toString(), SetResolutionStrategy) {
it.description = "Sets the project package resolution strategy"
it.resolutionStrategy.convention(extension.resolutionStrategy)
}
}

protected static ArtifactVersion getUnityVersion(UnityPluginExtension extension, Project project) {
File file = extension.unityPath.present ? extension.unityPath.get().asFile : null
UnityVersionManager.retrieveUnityVersion(file, UnityPluginConventions.defaultUnityTestVersion.getValue(project).toString())
}

}
Loading

0 comments on commit 5d7a831

Please sign in to comment.