Skip to content

Commit 5538f99

Browse files
committed
Only write dependency-graph on build success
Implementation uses "RunWork" build operation on Gradle 8.+, and "buildFinished" on older versions. Fixes #115
1 parent 0576a40 commit 5538f99

File tree

5 files changed

+85
-10
lines changed

5 files changed

+85
-10
lines changed

plugin-test/src/test/groovy/org/gradle/github/dependencygraph/BaseExtractorTest.groovy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ abstract class BaseExtractorTest extends Specification {
9999
return result
100100
}
101101

102+
protected BuildResult runAndFail() {
103+
return runAndFail("ForceDependencyResolutionPlugin_resolveAllDependencies")
104+
}
105+
106+
protected BuildResult runAndFail(String... names) {
107+
executer.withTasks(names)
108+
result = getExecuter().runWithFailure()
109+
return result
110+
}
111+
102112
@CompileDynamic
103113
protected void applyDependencyGraphPlugin() {
104114
File pluginJar = TEST_CONFIG.asFile("extractorPlugin.jar.path")

plugin-test/src/test/groovy/org/gradle/github/dependencygraph/DependencyExtractorConfigTest.groovy

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,17 @@ class DependencyExtractorConfigTest extends BaseExtractorTest {
5252
assert job.id == environmentVars.jobId
5353
}
5454

55+
def "fails gracefully if configuration values not set"() {
56+
when:
57+
def envVars = environmentVars.asEnvironmentMap()
58+
envVars.remove("GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR")
59+
executer.withEnvironmentVars(envVars)
60+
def result = executer.runWithFailure()
61+
62+
then:
63+
result.output.contains("> The configuration parameter 'GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR' must be set")
64+
}
65+
5566
@IgnoreIf({
5667
// There is an issue where BuildService is closed too early in Gradle 8.0,
5768
// resulting in empty dependency graph.
@@ -88,14 +99,38 @@ class DependencyExtractorConfigTest extends BaseExtractorTest {
8899
!dependencyGraphFile.exists()
89100
}
90101

91-
def "fails gracefully if configuration values not set"() {
102+
def "does not generate dependency-graph on configuration failure"() {
103+
given:
104+
buildFile << """
105+
throw new RuntimeException("Failure during configuration")
106+
"""
107+
92108
when:
93-
def envVars = environmentVars.asEnvironmentMap()
94-
envVars.remove("GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR")
95-
executer.withEnvironmentVars(envVars)
96-
def result = executer.runWithFailure()
109+
def buildResult = runAndFail()
97110

98111
then:
99-
result.output.contains("> The configuration parameter 'GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR' must be set")
112+
buildResult.output.contains("Gradle Build did not complete successfully: Dependency Graph file will not be generated.")
113+
!dependencyGraphFile.exists()
114+
}
115+
116+
def "does not generate dependency-graph on task failure"() {
117+
given:
118+
buildFile << """
119+
tasks.register("taskThatSucceeds") {
120+
doLast {}
121+
}
122+
tasks.register("taskThatFails") {
123+
doLast {
124+
throw new RuntimeException("Failure in task")
125+
}
126+
}
127+
"""
128+
129+
when:
130+
def buildResult = runAndFail("taskThatSucceeds", "taskThatFails")
131+
132+
then:
133+
buildResult.output.contains("Gradle Build did not complete successfully: Dependency Graph file will not be generated.")
134+
!dependencyGraphFile.exists()
100135
}
101136
}

plugin/src/main/kotlin/org/gradle/dependencygraph/AbstractDependencyExtractorPlugin.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ abstract class AbstractDependencyExtractorPlugin : Plugin<Gradle> {
8989
extractorServiceProvider: Provider<out DependencyExtractor>
9090
) {
9191
gradle.buildFinished {
92-
extractorServiceProvider.get().close()
93-
gradle.buildOperationListenerManager
94-
.removeListener(extractorServiceProvider.get())
92+
val extractorService = extractorServiceProvider.get()
93+
extractorService.handleBuildCompletion(it.failure)
94+
extractorService.close()
95+
gradle.buildOperationListenerManager.removeListener(extractorService)
9596
}
9697
}
9798
}

plugin/src/main/kotlin/org/gradle/dependencygraph/extractor/DependencyExtractor.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import org.gradle.api.logging.Logging
1010
import org.gradle.dependencygraph.DependencyGraphRenderer
1111
import org.gradle.dependencygraph.model.*
1212
import org.gradle.dependencygraph.model.DependencyScope.*
13-
import org.gradle.dependencygraph.util.*
13+
import org.gradle.dependencygraph.util.PluginParameters
1414
import org.gradle.initialization.EvaluateSettingsBuildOperationType
1515
import org.gradle.initialization.LoadProjectsBuildOperationType
1616
import org.gradle.internal.exceptions.DefaultMultiCauseException
@@ -38,6 +38,8 @@ abstract class DependencyExtractor :
3838
private val pluginParameters = PluginParameters()
3939

4040
private var settingsEvaluated = false
41+
private var buildCompleted = false
42+
private var buildFailed = false
4143

4244
private val resolvedConfigurations = Collections.synchronizedList(mutableListOf<ResolvedConfiguration>())
4345

@@ -70,6 +72,7 @@ abstract class DependencyExtractor :
7072
}
7173

7274
override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
75+
7376
handleBuildOperationType<
7477
ResolveConfigurationDependenciesBuildOperationType.Details,
7578
ResolveConfigurationDependenciesBuildOperationType.Result
@@ -341,6 +344,13 @@ abstract class DependencyExtractor :
341344
)
342345
}
343346

347+
fun handleBuildCompletion(failure: Throwable?) {
348+
buildCompleted = true
349+
if (failure != null) {
350+
buildFailed = true
351+
}
352+
}
353+
344354
override fun close() {
345355
if (thrownExceptions.isNotEmpty()) {
346356
throw DefaultMultiCauseException(
@@ -358,6 +368,13 @@ abstract class DependencyExtractor :
358368
)
359369
return
360370
}
371+
// Do not write an incomplete graph when build didn't complete successfully
372+
if (!buildCompleted || buildFailed) {
373+
LOGGER.lifecycle(
374+
"Gradle Build did not complete successfully: Dependency Graph file will not be generated."
375+
)
376+
return
377+
}
361378
try {
362379
writeDependencyGraph()
363380
} catch (e: RuntimeException) {

plugin/src/main/kotlin/org/gradle/dependencygraph/extractor/DependencyExtractorBuildService.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package org.gradle.dependencygraph.extractor
33
import org.gradle.api.provider.Property
44
import org.gradle.api.services.BuildService
55
import org.gradle.api.services.BuildServiceParameters
6+
import org.gradle.internal.operations.BuildOperationCategory
7+
import org.gradle.internal.operations.BuildOperationDescriptor
8+
import org.gradle.internal.operations.OperationFinishEvent
69

710
abstract class DependencyExtractorBuildService :
811
DependencyExtractor(),
@@ -16,4 +19,13 @@ abstract class DependencyExtractorBuildService :
1619
override fun getRendererClassName(): String {
1720
return parameters.rendererClassName.get()
1821
}
22+
23+
override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
24+
super.finished(buildOperation, finishEvent)
25+
26+
// Track build completion without 'buildFinished'
27+
if (buildOperation.metadata == BuildOperationCategory.RUN_WORK) {
28+
handleBuildCompletion(finishEvent.failure)
29+
}
30+
}
1931
}

0 commit comments

Comments
 (0)