Skip to content

Commit

Permalink
Define task to generate UPM packages (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
Azurelol authored May 10, 2022
1 parent 9003ab4 commit 6775144
Show file tree
Hide file tree
Showing 13 changed files with 638 additions and 6 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ github {
}

dependencies {
implementation 'com.wooga.gradle:gradle-commons:[1,2['

api 'com.wooga.gradle:gradle-commons:[1,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
16 changes: 15 additions & 1 deletion src/integrationTest/groovy/wooga/gradle/IntegrationSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package wooga.gradle

import com.wooga.gradle.PlatformUtils
import nebula.test.functional.ExecutionResult
import org.apache.commons.io.FileUtils
import org.junit.Rule
import org.junit.contrib.java.lang.system.EnvironmentVariables
import org.junit.contrib.java.lang.system.ProvideSystemProperty
Expand Down Expand Up @@ -46,7 +47,17 @@ class IntegrationSpec extends nebula.test.IntegrationSpec {
}

Boolean fileExists(String... path) {
fileExists(path.join("/"))
fileExists(path.join(File.separator))
// TODO: Use this instead, but doesnt have the same behavior on macos as windows?
//FileUtils.getFile(path).exists()
}

def file(String... path) {
file(path.join(File.separator), projectDir)
}

def directory(String... path) {
directory(path.join(File.separator), projectDir)
}

Boolean outputContains(ExecutionResult result, String message) {
Expand Down Expand Up @@ -113,6 +124,9 @@ class IntegrationSpec extends nebula.test.IntegrationSpec {
value = "[" + rawValue.collect { k, v -> "${wrapValueBasedOnType(k, k.getClass(), fallback)} : ${wrapValueBasedOnType(v, v.getClass(), fallback)}" }.join(", ") + "]"
value = value == "[]" ? "[:]" : value
break
case "Directory":
value = "project.layout.projectDirectory.dir(${wrapValueBasedOnType(rawValue, String, fallback)})"
break
default:
value = (fallback) ? fallback.call(type) : rawValue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,29 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {
addTask(name, typeName, force, lines)
}

void addTask(String name, String typeName, Boolean force, String... lines) {
// TODO: Consider adding to gradle-commons-test
/**
* @return The name of the variable of type TaskProvider
*/
def addTask(String name, String typeName, Boolean force, String... lines) {
lines = lines ?: []
String variableName = "${name}Task"
buildFile << """
task (${name}, type: ${typeName}) {
def ${variableName} = tasks.register(\"${name}\"${typeName != null ? ", ${typeName}": ""}) {
${force ? "onlyIf = {true}\n" : ""}${lines.join('\n')}
}
""".stripIndent()
variableName
}

// TODO: Consider adding to gradle-commons-test
/**
* Set a task dependency where A depends on B
*/
void setTaskDependency(String a, String b) {
buildFile << """
${a} dependsOn ${b}
"""
}

void appendToPluginExtension(String... lines) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class AddUPMPackagesTaskIntegrationSpec extends UnityTaskIntegrationSpec<AddUPMP
def projectPath = "build/test_project"
environmentVariables.set("UNITY_PATH", unity.getExecutable().getPath())


//Test using the extension
and: "a setup AddUPMPackageTask"
appendToSubjectTask("""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package wooga.gradle.unity.tasks

import com.wooga.spock.extensions.unity.UnityPathResolution
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import com.wooga.spock.extensions.uvm.UnityInstallation
import net.wooga.uvm.Installation
import org.apache.commons.io.FileUtils
import org.gradle.api.file.Directory
import spock.lang.Requires
import wooga.gradle.unity.UnityTaskIntegrationSpec

import static org.apache.commons.io.FileUtils.getFile

class CreateProjectTaskIntegrationSpec extends UnityTaskIntegrationSpec<CreateProject> {

@Requires({ os.macOs })
@UnityPluginTestOptions(unityPath = UnityPathResolution.Default)
@UnityInstallation(version = "2019.4.38f1", cleanup = false)
def "creates unity project"(Installation unity) {

given: "a pre installed unity editor"
environmentVariables.set("UNITY_PATH", unity.getExecutable().getPath())

and: "configuration of the extension"
def projectPath = "Wooga.Foobar"
buildFile << """
unity {
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
}
""".stripIndent()

when:
def result = runTasksSuccessfully(subjectUnderTestName)

then:
result.success
getFile(projectDir, projectPath, "Assets").exists()
getFile(projectDir, projectPath, "ProjectSettings").exists()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package wooga.gradle.unity.tasks

import com.wooga.spock.extensions.unity.UnityPathResolution
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import com.wooga.spock.extensions.uvm.UnityInstallation
import net.wooga.uvm.Installation
import org.gradle.api.file.Directory
import org.gradle.api.tasks.Copy
import spock.lang.Requires
import spock.lang.Unroll
import wooga.gradle.unity.UnityIntegrationSpec
import wooga.gradle.unity.testutils.SetupProjectLayoutTestTask
import wooga.gradle.unity.utils.PackageManifestBuilder
import wooga.gradle.utils.DirectoryComparer

class GenerateUpmPackageTaskIntegrationSpec extends UnityIntegrationSpec {

@Requires({ os.macOs })
@UnityPluginTestOptions(unityPath = UnityPathResolution.Default)
@UnityInstallation(version = "2019.4.38f1", cleanup = false)
def "generates unity package"(Installation unity) {

given: "a pre installed unity editor"
environmentVariables.set("UNITY_PATH", unity.getExecutable().getPath())

and: "future directory expectations"
def distributionsDirName = "build/distributions"
def distributionsDir = new File(projectDir, distributionsDirName)
assert !distributionsDir.exists()

and: "configuration of the extension"
def unityProjectPath = SetupProjectLayoutTestTask.unityProjectDirectoryName
def packageDirRel = unityProjectPath + "/Assets/Wooga/Foobar"
def expectedProjectDir = new File(projectDir, unityProjectPath)
buildFile << """
unity {
projectDirectory.set(${wrapValueBasedOnType(unityProjectPath, Directory)})
}
""".stripIndent()

and: "a set of values for the package"
def packageName = "com.wooga.foobar"
def packageVersion = "0.0.1"
def expectedPackageFileName = "${packageName}-${packageVersion}.tgz"

and: "a task to create the project"
def createProjectTaskName = "createProject"
def createProjectTask = addTask("createProject", CreateProject.class.name, false, "")

and: "a task to add additional files to the project 2"
def addFilesTaskName = "addPackageFiles"
def addFilesTask = addTask(addFilesTaskName, SetupProjectLayoutTestTask.class.name, false, """
dependsOn ${createProjectTask}
""".stripIndent())

and: "a task to generate meta files"
def generateMetaFilesTaskName = "metatron"
def generateMetaFilesTask = addTask(generateMetaFilesTaskName, Unity.class.name, false, """
dependsOn ${addFilesTask}
""".stripIndent())

and: "a task to generate the upm package"
def generateUpmPackageTaskName = "upmPack"
addTask(generateUpmPackageTaskName, GenerateUpmPackage.class.name, false, """
packageDirectory.set(${wrapValueBasedOnType(packageDirRel, Directory)})
packageName = ${wrapValueBasedOnType(packageName, String)}
archiveVersion.set(${wrapValueBasedOnType(packageVersion, String)})
dependsOn ${generateMetaFilesTask}
""".stripIndent())

and: "a task to extract the upm package so we can compare, okay?"
def extractUpmPackageName = "upmUnpack"
def packageFileRelPath = "${distributionsDirName}/${expectedPackageFileName}"
addTask(extractUpmPackageName, Copy.class.name, false, """
from tarTree(\"${packageFileRelPath}\")
into layout.buildDirectory.dir(${wrapValueBasedOnType("unpack", String)})
""".stripIndent())

when:
def result = runTasksSuccessfully(createProjectTaskName, generateUpmPackageTaskName, addFilesTaskName, extractUpmPackageName)

then:
result.success
distributionsDir.exists()

def packageManifestUnpackDir = new File(projectDir, "build/unpack")
packageManifestUnpackDir.exists()

def packageFile = new File(distributionsDir, expectedPackageFileName)
packageFile.exists()

def unpackedPackageDir = new File(packageManifestUnpackDir, "package")
unpackedPackageDir.exists()

// Check the contents of the package manifest
def packageManifestFile = new File(unpackedPackageDir, GenerateUpmPackage.packageManifestFileName)
packageManifestFile.exists()

def packageJson = packageManifestFile.text
packageJson.contains("\"name\" : \"${packageName}\"")
packageJson.contains("\"version\" : \"${packageVersion}\"")

// Compare the contents of both unpacked and package source directories
// NOTE: We don't compare the manifests since we are patching it during the packaging
def packageSourceDir = new File(expectedProjectDir, "Assets/Wooga/Foobar")
def comparer = new DirectoryComparer(packageSourceDir, unpackedPackageDir)
comparer.ignoreFile(GenerateUpmPackage.packageManifestFileName)
comparer.ignoreTimestamps()
def comparison = comparer.compare()
assert comparison.valid: comparison.toString()
}

@Unroll
def "fails to generate package if '#reason'"() {

given: "configuration of the extension"
def projectPath = "Wooga.Foobar"
directory(projectPath)
buildFile << """
unity {
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
}
""".stripIndent()

// Add package files
file(projectPath, "README.MD")
def manifestFile = file(projectPath, GenerateUpmPackage.packageManifestFileName)
manifestFile.write(new PackageManifestBuilder().build())

and:
def generateUpmPackageTaskName = "upmPack"
List<String> taskStatements = new ArrayList<String>()
if (failure != GenerateUpmPackage.Failure.packageDirectoryNotSet) {
taskStatements.add("packageDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})")
}
if (failure != GenerateUpmPackage.Failure.versionNotSet) {
taskStatements.add("archiveVersion.set(${wrapValueBasedOnType(packageVersion, String)})")
}
if (failure != GenerateUpmPackage.Failure.packageNameNotSet) {
taskStatements.add("packageName = ${wrapValueBasedOnType(packageName, String)}")
}

addTask(generateUpmPackageTaskName, GenerateUpmPackage.class.name, false, taskStatements.join("\n"))

when:
def result = runTasks(generateUpmPackageTaskName)

then:
result.failure || result.wasSkipped(generateUpmPackageTaskName)
outputContains(result, reason)

where:
packageName | packageVersion | failure
"com.wooga.foobar" | "0.0.1" | GenerateUpmPackage.Failure.packageDirectoryNotSet
"com.wooga.foobar" | "0.0.1" | GenerateUpmPackage.Failure.versionNotSet
"com.wooga.foobar" | "0.0.1" | GenerateUpmPackage.Failure.packageNameNotSet
reason = failure.message
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.wooga.gradle.PlatformUtils
import spock.lang.Unroll

import wooga.gradle.unity.UnityIntegrationSpec
import wooga.gradle.unity.UnityTaskIntegrationSpec
import wooga.gradle.unity.models.APICompatibilityLevel
import wooga.gradle.unity.utils.ProjectSettingsFile

Expand Down Expand Up @@ -140,3 +141,4 @@ class SetAPICompLevelTaskIntegrationSpec extends UnityIntegrationSpec {
expectedAPICompatibilityLevel = APICompatibilityLevel.defaultLevel
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package wooga.gradle.unity.testutils

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import wooga.gradle.unity.utils.PackageManifestBuilder

/**
* Sets up the project file structure as expected by Unity's package manager
*/
class SetupProjectLayoutTestTask extends DefaultTask {

public static String packageName = "Foobar"
public static String unityProjectDirectoryName = "Wooga.${packageName}"

@TaskAction
void exec() {
File unityProjectDir = new File(project.projectDir, unityProjectDirectoryName)

File assetsDir = new File(unityProjectDir, "Assets")

def packageDir = new File(assetsDir.path, "Wooga/${packageName}")
packageDir.mkdirs()

def packageJson = new File(packageDir.path, "package.json")
packageJson.write(new PackageManifestBuilder("com.wooga.${packageName.toLowerCase()}", "0.0.0").build())

def readme = new File(packageDir.path, "README.MD")
readme.write("Here lies package ${packageName}")

def license = new File(packageDir.path, "LICENSE.MD")
license.write("Be good to each other")

def runtimeDirectory = new File(packageDir.path, "Runtime")
runtimeDirectory.mkdir()
def runtimeSource = new File(runtimeDirectory.path, "${packageName}.cs")
runtimeSource.write("""
using System;
public class ${packageName} {
}
""")

def editorDirectory = new File(packageDir.path, "Editor")
editorDirectory.mkdir()
def editorSource = new File(editorDirectory.path, "${packageName}Editor.cs")
editorSource.write("""
using System;
public class ${packageName}Editor {
}
""")
}
}
Loading

0 comments on commit 6775144

Please sign in to comment.