Skip to content
This repository was archived by the owner on Feb 20, 2025. It is now read-only.

Commit d3f830d

Browse files
authored
Add a virtual method for customizing the exception message for unity task (#200)
## Description Add a method that can be overridden in the `UnityTask` for customizing the exception message. ## Changes * ![ADD] `UnityTask.composeExceptionMessage,` virtual method for customizing the exception message when the task fails. [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"
1 parent 2e803b3 commit d3f830d

File tree

7 files changed

+116
-18
lines changed

7 files changed

+116
-18
lines changed

src/integrationTest/groovy/com/wooga/spock/extensions/unity/DefaultUnityPluginTestOptions.groovy

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class DefaultUnityPluginTestOptions implements UnityPluginTestOptions {
2727
Boolean addMockTask = true
2828
Boolean forceMockTaskRun = true
2929
Boolean clearMockTaskActions = false
30+
Boolean writeMockExecutable = true
3031

3132
boolean applyPlugin() {
3233
applyPlugin
@@ -36,6 +37,11 @@ class DefaultUnityPluginTestOptions implements UnityPluginTestOptions {
3637
unityPath
3738
}
3839

40+
@Override
41+
boolean writeMockExecutable() {
42+
writeMockExecutable
43+
}
44+
3945
boolean addPluginTestDefaults() {
4046
addPluginTestDefaults
4147
}

src/integrationTest/groovy/com/wooga/spock/extensions/unity/UnityPluginTestOptions.groovy

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import java.lang.annotation.Target
4141

4242
UnityPathResolution unityPath() default UnityPathResolution.Mock
4343

44+
boolean writeMockExecutable() default true
45+
4446
boolean addPluginTestDefaults() default true
4547

4648
boolean disableAutoActivateAndLicense() default true

src/integrationTest/groovy/wooga/gradle/unity/UnityIntegrationSpec.groovy

+24-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ package wooga.gradle.unity
1919

2020
import com.wooga.gradle.PlatformUtils
2121
import com.wooga.gradle.test.IntegrationSpec
22-
import com.wooga.gradle.test.executable.FakeExecutables
22+
import com.wooga.gradle.test.mock.MockExecutable
2323
import com.wooga.spock.extensions.unity.DefaultUnityPluginTestOptions
2424
import com.wooga.spock.extensions.unity.UnityPathResolution
2525
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
26+
import groovy.transform.stc.ClosureParams
27+
import groovy.transform.stc.FromString
2628
import wooga.gradle.unity.tasks.Unity
2729
import wooga.gradle.unity.utils.ProjectSettingsFile
2830

@@ -100,8 +102,9 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {
100102

101103
switch (options.unityPath()) {
102104
case UnityPathResolution.Mock:
103-
mockUnityFile = createMockUnity()
104-
addUnityPathToExtension(mockUnityFile.path)
105+
if (options.writeMockExecutable()) {
106+
writeMockExecutable()
107+
}
105108
break
106109

107110
case UnityPathResolution.Default:
@@ -132,6 +135,24 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {
132135
projectSettingsFile
133136
}
134137

138+
/**
139+
* Writes the mock executable with a predetermined location
140+
*/
141+
protected void writeMockExecutable(@ClosureParams(value = FromString, options = "com.wooga.gradle.test.mock.MockExecutable")
142+
Closure<MockExecutable> configure = null) {
143+
// Create and configure the file to be written
144+
def mockUnity = new MockExecutable("fakeUnity.bat")
145+
mockUnity.withText(mockUnityStartupMessage)
146+
if (configure != null) {
147+
configure(mockUnity)
148+
}
149+
// Write the file
150+
mockUnityFile = mockUnity.toDirectory(unityMainDirectory)
151+
// Write its location onto the unity extension
152+
addUnityPathToExtension(mockUnityFile.path)
153+
}
154+
155+
// TODO: Refactor away
135156
protected File createMockUnity(String extraLog = null, int exitValue=0) {
136157
def mockUnityFile = createFile("fakeUnity.bat", unityMainDirectory).with {
137158
delete()
@@ -165,7 +186,6 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {
165186
""".readLines().collect{it.stripIndent().trim() }.findAll {!it.empty}.join("\n")
166187
}
167188
return mockUnityFile
168-
169189
}
170190

171191
void setLicenseDirectory() {

src/integrationTest/groovy/wooga/gradle/unity/UnityTaskIntegrationSpec.groovy

+2-3
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ import com.wooga.gradle.PlatformUtils
2121
import com.wooga.gradle.test.PropertyQueryTaskWriter
2222
import com.wooga.gradle.test.TaskIntegrationSpec
2323
import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
24-
import com.wooga.gradle.test.writers.PropertySetterWriter
2524
import org.gradle.api.logging.LogLevel
2625
import spock.lang.Unroll
2726
import wooga.gradle.unity.testutils.GradleRunResult
2827
import wooga.gradle.unity.models.UnityCommandLineOption
29-
import wooga.gradle.unity.tasks.Unity
3028

31-
import java.lang.reflect.ParameterizedType
3229
import java.nio.file.Files
3330
import java.nio.file.StandardCopyOption
3431
import java.time.Duration
@@ -352,8 +349,10 @@ abstract class UnityTaskIntegrationSpec<T extends UnityTask> extends UnityIntegr
352349
@Unroll
353350
def "unity #message #maxRetries times with #retryWait wait times when line in log matches #retryRegexes"() {
354351
given:
352+
355353
def fakeUnity = createMockUnity(unityLog, 1)
356354
addUnityPathToExtension(fakeUnity.absolutePath)
355+
357356
buildFile << """
358357
$subjectUnderTestName {
359358
maxRetries = ${wrapValue(maxRetries, Integer)}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package wooga.gradle.unity.tasks
2+
3+
4+
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
5+
import groovy.json.StringEscapeUtils
6+
import wooga.gradle.unity.UnityTaskIntegrationSpec
7+
8+
import java.util.regex.Matcher
9+
import java.util.regex.Pattern
10+
11+
class FailingTask extends Unity {
12+
13+
static Pattern pattern = Pattern.compile("<BUILD ERRORS>(?<summary>(.*\\s*)*)</BUILD ERRORS>")
14+
15+
// Escape for ^<, ^>
16+
public static String expectedErrorMessage = """[BuildEngine] Collected errors during build process:
17+
<BUILD ERRORS>
18+
[Error] FOO Wooga.UnifiedBuildSystem.Tests.Editor.BuildEngineTest+FailingBuildSteps:FailInElaborateWays (at Packages/com.wooga.unified-build-system/Tests/Editor/BuildEngine/BuildRequestOutputTest.cs:32)
19+
[Error] BAR Wooga.UnifiedBuildSystem.Tests.Editor.BuildEngineTest+FailingBuildSteps:FailInElaborateWays (at Packages/com.wooga.unified-build-system/Tests/Editor/BuildEngine/BuildRequestOutputTest.cs:32)
20+
[Exception] Exception: Boom! Wooga.UnifiedBuildSystem.Editor.BuildTask`1[[Wooga.UnifiedBuildSystem.Editor.BuildTaskArguments, Wooga.Build.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]:Execute (at Packages/com.wooga.build/Editor/Tasks/BuildTask.cs:73)
21+
[Error] Failed to execute task 'FailInElaborateWays' Wooga.UnifiedBuildSystem.Editor.BuildEngine+State:SetBuildFailure (at Packages/com.wooga.unified-build-system/Editor/BuildEngine/BuildEngine.cs:89)
22+
</BUILD ERRORS>""".stripIndent()
23+
24+
static String buildErrorStartMarker = "<BUILD ERRORS>"
25+
static String buildErrorEndMarker = "</BUILD ERRORS>"
26+
27+
@Override
28+
protected String composeExceptionMessage(String stdout, String stderr) {
29+
Matcher matcher = pattern.matcher(stderr)
30+
if (matcher.find()){
31+
var summary = matcher.group(0)
32+
return summary
33+
}
34+
return ""
35+
}
36+
}
37+
38+
class FailTaskIntegrationSpec extends UnityTaskIntegrationSpec<FailingTask>{
39+
40+
static String echoError(String message) {
41+
"""echo "${StringEscapeUtils.escapeJava(message).replace("`", "\\`") }" 1>&2 """
42+
}
43+
44+
@UnityPluginTestOptions(writeMockExecutable = false)
45+
def "throws composited exception message"() {
46+
47+
given:
48+
writeMockExecutable({
49+
it.text += "\n${FailingTask.expectedErrorMessage.readLines().collect{echoError(it) }.join("\n")}"
50+
it.printEnvironment = false
51+
it.exitValue = 666
52+
})
53+
54+
when:
55+
def result = runTasksWithFailure(subjectUnderTestName)
56+
57+
then:
58+
result.wasExecuted(subjectUnderTestName)
59+
result.standardError.contains(FailingTask.buildErrorStartMarker)
60+
result.standardError.contains(FailingTask.buildErrorEndMarker)
61+
}
62+
}

src/integrationTest/groovy/wooga/gradle/unity/testutils/GradleRunResult.groovy

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package wooga.gradle.unity.testutils
22

3+
import com.wooga.gradle.test.mock.MockExecutable
34
import org.gradle.internal.impldep.org.apache.commons.lang.StringUtils
45

56
class GradleRunResult {
@@ -46,23 +47,23 @@ class GradleRunResult {
4647
}
4748

4849
private static ArrayList<String> loadArgs(String stdOutput) {
49-
def argumentsStartToken = "[ARGUMENTS]:"
50+
def argumentsStartToken = MockExecutable.ARGUMENTS_START_MARKER
5051
def lastExecutionOffset = stdOutput.lastIndexOf(argumentsStartToken)
5152
if(lastExecutionOffset < 0) {
5253
System.out.println(stdOutput)
5354
throw new IllegalArgumentException("couldn't find arguments list in stdout")
5455
}
5556
def lastExecTailString = stdOutput.substring(lastExecutionOffset)
56-
def argsString = substringBetween(lastExecTailString, argumentsStartToken, "[LOG]").
57+
def argsString = substringBetween(lastExecTailString, argumentsStartToken, MockExecutable.ARGUMENTS_END_MARKER).
5758
replace(argumentsStartToken, "")
5859
def parts = argsString.split(" ").
5960
findAll {!StringUtils.isEmpty(it) }.collect{ it.trim() }
6061
return parts
6162
}
6263

6364
private static Map<String, String> loadEnvs(String stdOutput) {
64-
String environmentStartToken = "[ENVIRONMENT]:"
65-
def argsString = substringBetween(stdOutput, environmentStartToken, "[ARGUMENTS]").
65+
String environmentStartToken = MockExecutable.ENVIRONMENT_START_MARKER
66+
def argsString = substringBetween(stdOutput, environmentStartToken, MockExecutable.ENVIRONMENT_END_MARKER).
6667
replace(environmentStartToken, "")
6768
def parts = argsString.split(System.lineSeparator()).
6869
findAll {!StringUtils.isEmpty(it) }.collect{ it.trim() }

src/main/groovy/wooga/gradle/unity/UnityTask.groovy

+15-7
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,27 @@ abstract class UnityTask extends DefaultTask
9898
})
9999

100100
if (execResult.exitValue != 0) {
101-
String message = ""
102-
// Only write out the message if not already set to --info
103-
if (!logger.infoEnabled) {
104-
def stdout = logFile.text
105-
def stderr = lastStderrStream? new String(lastStderrStream.toByteArray()) : ""
106-
message = stderr ? stderr : stdout
107-
}
101+
def stdout = logFile.text
102+
def stderr = lastStderrStream ? new String(lastStderrStream.toByteArray()) : ""
103+
String message = composeExceptionMessage(stdout, stderr)
108104
throw new UnityExecutionException("Failed during execution of the Unity process with arguments:\n${_arguments}\n${message}")
109105
}
110106

111107
postExecute(execResult)
112108
}
113109

110+
/**
111+
* Composes the message to be included in an exception thrown when the task fails
112+
* Override this in your custom task in order to improve reporting.
113+
*/
114+
protected String composeExceptionMessage(String stdout, String stderr) {
115+
String message = ""
116+
if (!logger.infoEnabled) {
117+
message = stderr ? stderr : stdout
118+
}
119+
return message
120+
}
121+
114122
/**
115123
* Invoked before the task executes the Unity process
116124
*/

0 commit comments

Comments
 (0)