Skip to content

Commit

Permalink
Fix space in upm package replacement [ATLAS-1206] (#177)
Browse files Browse the repository at this point in the history
## Description

The regex to execute value substition for the `package.json` file
assumes spaces around the properties.

I removed the whole line patching logic with a two step copy setup.
The task first copies the package.json to a temp directory in the build
dir
and adjustst the content according to the set properties.
The main package copy spec will draw the content from two locations

1. the main package dir
2. the temp directory where only the adjusted package.json is located

During copy only the package.json file form the temp dir will be taken
into account.
The solution at hand is sadly not the best to continue going forward.
But I wanted a simple fix now and deal with a proper solution (parsing
the whole json instead of doing line matching).

The changes are quite big because I wanted to implement another set of
parameters on top which I removed again. But I already refactored the
test setup to make the setup less verbose (still quite verbose).

I also bound the version from the `package.json` file as the default
value for the archive version.

## Changes

* ![FIX] space recognision in upm package replacement regex
* ![IMPROVE] test setup for upm pack spec
* ![IMPROVE] default version for upm pack from `package.json`

[NEW]:      https://resources.atlas.wooga.com/icons/icon_new.svg "New"
[ADD]:      https://resources.atlas.wooga.com/icons/icon_add.svg "Add"
[IMPROVE]: https://resources.atlas.wooga.com/icons/icon_improve.svg
"Improve"
[CHANGE]: https://resources.atlas.wooga.com/icons/icon_change.svg
"Change"
[FIX]:      https://resources.atlas.wooga.com/icons/icon_fix.svg "Fix"
[UPDATE]: https://resources.atlas.wooga.com/icons/icon_update.svg
"Update"

[BREAK]: https://resources.atlas.wooga.com/icons/icon_break.svg "Remove"
[REMOVE]: https://resources.atlas.wooga.com/icons/icon_remove.svg
"Remove"
[IOS]:      https://resources.atlas.wooga.com/icons/icon_iOS.svg "iOS"
[ANDROID]: https://resources.atlas.wooga.com/icons/icon_android.svg
"Android"
[WEBGL]: https://resources.atlas.wooga.com/icons/icon_webGL.svg "WebGL"
[GRADLE]: https://resources.atlas.wooga.com/icons/icon_gradle.svg
"GRADLE"
[UNITY]: https://resources.atlas.wooga.com/icons/icon_unity.svg "Unity"
[LINUX]: https://resources.atlas.wooga.com/icons/icon_linux.svg "Linux"
[WIN]: https://resources.atlas.wooga.com/icons/icon_windows.svg
"Windows"
[MACOS]:    https://resources.atlas.wooga.com/icons/icon_iOS.svg "macOS"
  • Loading branch information
Larusso authored Apr 26, 2023
1 parent 3ecc66f commit 94db98b
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package wooga.gradle.unity.tasks

import com.wooga.gradle.io.FileUtils

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.JsonSlurper
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
Expand All @@ -16,99 +18,194 @@ import wooga.gradle.utils.DirectoryComparer

class GenerateUpmPackageTaskIntegrationSpec extends UnityIntegrationSpec {

@Override
String getSubjectUnderTestName() {
"generateUpmPackage"
}

String subjectUnderTestTypeName = GenerateUpmPackage.class.name

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

where:
propertyName | type | value
"packageDirectory" | "File" | osPath("/path/to/package/dir")
"packageDirectory" | "Provider<Directory>" | osPath("/path/to/package/dir")
"packageName" | "String" | "testPackageA"
"packageName" | "Provider<String>" | "testPackageB"

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

@Requires({ os.macOs })
@UnityPluginTestOptions(unityPath = UnityPathResolution.Default)
@UnityInstallation(version = "2019.4.38f1", cleanup = false)
def "generates unity package"(Installation unity) {
@UnityInstallation(version = "2022.1.15f1", cleanup = false)
def "generates unity package"(
String packageDisplayName,
String unityProjectPath,
String distributionsDirName,
String packageDirectory,
String packageName,
String packageVersion,
String expectedPackageFileName,
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: "future package file"
def packageFile = new File(distributionsDir, expectedPackageFileName)
assert !packageFile.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)})
}
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())
def setupProjectTask = setupUpmTestProject(unityProjectPath, packageDisplayName, packageName)

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}
and: "configure task to generate the upm package"
appendToSubjectTask("""\
packageDirectory.set(${wrapValueBasedOnType(packageDirectory, Directory)})
packageName = ${wrapValueBasedOnType(packageName, String)}
archiveVersion.set(${wrapValueBasedOnType(packageVersion, String)})
dependsOn ${setupProjectTask}
""".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)
def result = runTasksSuccessfully(subjectUnderTestName)

then:
result.success
distributionsDir.exists()
packageFile.exists()

def packageManifestUnpackDir = unpackPackage(packageFile)
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 json = new JsonSlurper().parse(packageManifestFile)
json["name"] == packageName
json["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(projectDir, packageDirectory)
def comparer = new DirectoryComparer(packageSourceDir, unpackedPackageDir)
comparer.ignoreFile(GenerateUpmPackage.packageManifestFileName)
comparer.ignoreTimestamps()
def comparison = comparer.compare()
assert comparison.valid: comparison.toString()

where:
packageDisplayName = "Foobar"
unityProjectPath = "Wooga.${packageDisplayName}"
distributionsDirName = "build/distributions"
packageDirectory = unityProjectPath + "/Assets/Wooga/Foobar"
packageName = "com.wooga.foobar"
packageVersion = "0.0.1"
expectedPackageFileName = "${packageName}-${packageVersion}.tgz"

and: "the injected unity installation"
unity = null
}

@Requires({ os.macOs })
@UnityPluginTestOptions(unityPath = UnityPathResolution.Default)
@UnityInstallation(version = "2019.4.38f1", cleanup = false)
def "uses package name and version from package.json when not specified"(
String packageDisplayName,
String unityProjectPath,
String distributionsDirName,
String packageDirectory,
String packageName,
String packageVersion,
String expectedPackageFileName,
Installation unity
) {

def packageManifestUnpackDir = new File(projectDir, "build/unpack")
packageManifestUnpackDir.exists()
given: "a pre installed unity editor"
environmentVariables.set("UNITY_PATH", unity.getExecutable().getPath())

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

and: "future package file"
def packageFile = new File(distributionsDir, expectedPackageFileName)
assert !packageFile.exists()

and: "configuration of the extension"
buildFile << """\
unity {
projectDirectory.set(${wrapValueBasedOnType(unityProjectPath, Directory)})
}
""".stripIndent()

def setupProjectTask = setupUpmTestProject(unityProjectPath, packageDisplayName, packageName, packageVersion)

and: "configure task to generate the upm package"
appendToSubjectTask("""\
packageDirectory.set(${wrapValueBasedOnType(packageDirectory, Directory)})
dependsOn ${setupProjectTask}
""".stripIndent())

when:
def result = runTasksSuccessfully(subjectUnderTestName)

then:
result.success
distributionsDir.exists()
packageFile.exists()

def packageManifestUnpackDir = unpackPackage(packageFile)
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}\"")
def json = new JsonSlurper().parse(packageManifestFile)
json["name"] == packageName
json["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 packageSourceDir = new File(projectDir, packageDirectory)
def comparer = new DirectoryComparer(packageSourceDir, unpackedPackageDir)
comparer.ignoreFile(GenerateUpmPackage.packageManifestFileName)
comparer.ignoreTimestamps()
def comparison = comparer.compare()
assert comparison.valid: comparison.toString()

where:
packageDisplayName = "Foobar"
unityProjectPath = "Wooga.${packageDisplayName}"
distributionsDirName = "build/distributions"
packageDirectory = unityProjectPath + "/Assets/Wooga/Foobar"
packageName = "com.wooga.foobar-baz"
packageVersion = "1.1.1"
expectedPackageFileName = "${packageName}-${packageVersion}.tgz"

and: "the injected unity installation"
unity = null
}

@Unroll
Expand All @@ -119,7 +216,7 @@ class GenerateUpmPackageTaskIntegrationSpec extends UnityIntegrationSpec {
directory(projectPath)
buildFile << """
unity {
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
projectDirectory.set(${wrapValueBasedOnType(projectPath, Directory)})
}
""".stripIndent()

Expand Down Expand Up @@ -154,10 +251,38 @@ class GenerateUpmPackageTaskIntegrationSpec extends UnityIntegrationSpec {
where:
packageName | packageVersion | predicate
"com.wooga.foobar" | "0.0.1" | GenerateUpmPackage.Message.packageDirectoryNotSet
"com.wooga.foobar" | "0.0.1" | GenerateUpmPackage.Message.versionNotSet
"com.wooga.foobar" | "0.0.1" | GenerateUpmPackage.Message.packageNameNotSet
reason = predicate.message
}

private static File unpackPackage(File packageFile) {
def packageManifestUnpackDir = File.createTempDir(packageFile.name, "_unpack")
def ant = new AntBuilder()
ant.untar(src: packageFile.path, dest: packageManifestUnpackDir.path, compression: "gzip")
packageManifestUnpackDir
}

private String setupUpmTestProject(String unityProjectPath, String packageDisplayName, String packageName, String packageVersion = "0.0.0") {
def createProjectTaskName = "createProject"
def createProjectTask = addTask(createProjectTaskName, CreateProject.class.name, false, "")

def addFilesTaskName = "addPackageFiles"
def addFilesTask = addTask(addFilesTaskName, SetupProjectLayoutTestTask.class.name, false, """\
unityProjectDirectoryName = ${wrapValueBasedOnType(unityProjectPath, "String")}
packageDisplayName = ${wrapValueBasedOnType(packageDisplayName, "String")}
packageName = ${wrapValueBasedOnType(packageName, "String")}
initialPackageVersion = ${wrapValueBasedOnType(packageVersion, "String")}
dependsOn ${createProjectTask}
""".stripIndent())

def generateMetaFilesTaskName = "generateMetafiles"
def generateMetaFilesTask = addTask(generateMetaFilesTaskName, Unity.class.name, false, """\
dependsOn ${addFilesTask}
""".stripIndent())

def setupProjectTask = addTask("setupUnityProject", "org.gradle.api.DefaultTask", false, """\
dependsOn ${createProjectTask}, ${addFilesTask}, ${generateMetaFilesTask}
""")
setupProjectTask
}
}
Loading

0 comments on commit 94db98b

Please sign in to comment.