Skip to content

Commit

Permalink
introduction of the 'checkBuildEnvironmentConstraints' parameter to e…
Browse files Browse the repository at this point in the history
…nable the checking of external constraints (#576)
  • Loading branch information
ErwanLeroux committed Dec 30, 2021
1 parent a51972b commit 3a6f716
Show file tree
Hide file tree
Showing 12 changed files with 5,157 additions and 10 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -279,10 +279,13 @@ If you use constraints, for example to define a BOM using the [`java-platform`](
plugin or to [manage](https://docs.gradle.org/current/userguide/dependency_constraints.html)
transitive dependency versions, you can enable checking of constraints by specifying the `checkConstraints`
attribute of the `dependencyUpdates` task.
If you want to check external constraints (defined in init scripts or by Gradle since 7.3.2) you can do so by specifying the `checkBuildEnvironmentConstraints`
attribute of the `dependencyUpdates` task.

```groovy
tasks.named("dependencyUpdates").configure {
checkConstraints = true
checkBuildEnvironmentConstraints = true
}
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -11,7 +11,7 @@ repositories {
}

group = 'com.github.ben-manes'
version = '0.39.0'
version = '0.40.0'

sourceCompatibility = JavaVersion.VERSION_1_8

Expand Down
Expand Up @@ -46,24 +46,33 @@ class DependencyUpdates {
boolean checkForGradleUpdate
String gradleReleaseChannel
boolean checkConstraints
boolean checkBuildEnvironmentConstraints

/** Evaluates the dependencies and returns a reporter. */
/** Evaluates the dependencies in two part,
* first the project dependencies and second the buildScript dependencies,
* to apply different options and returns a reporter. */
DependencyUpdatesReporter run() {
Map<Project, Set<Configuration>> projectConfigs = project.allprojects.collectEntries { proj ->
[proj, proj.configurations + (Set) proj.buildscript.configurations]
[proj, (Set) proj.configurations ]
}
Set<DependencyStatus> status = resolveProjects(projectConfigs)
Set<DependencyStatus> status = resolveProjects(projectConfigs, checkConstraints)

VersionMapping versions = new VersionMapping(project, status)
Map<Project, Set<Configuration>> buildscriptProjectConfigs = project.allprojects.collectEntries { proj ->
[proj, (Set) proj.buildscript.configurations ]
}
Set<DependencyStatus> buildscriptStatus = resolveProjects(buildscriptProjectConfigs, checkBuildEnvironmentConstraints)

def statuses = status + buildscriptStatus
VersionMapping versions = new VersionMapping(project, statuses)
Set<UnresolvedDependency> unresolved =
status.findAll { it.unresolved != null }.collect { it.unresolved } as Set
Map<Map<String, String>, String> projectUrls = status.findAll { it.projectUrl }.collectEntries {
statuses.findAll { it.unresolved != null }.collect { it.unresolved } as Set
Map<Map<String, String>, String> projectUrls = statuses.findAll { it.projectUrl }.collectEntries {
[[group: it.coordinate.groupId, name: it.coordinate.artifactId]: it.projectUrl]
}
return createReporter(versions, unresolved, projectUrls)
}

private Set<DependencyStatus> resolveProjects(Map<Project, Set<Configuration>> projectConfigs) {
private Set<DependencyStatus> resolveProjects(Map<Project, Set<Configuration>> projectConfigs, boolean checkConstraints) {
Set<DependencyStatus> resultStatusSet = []
for(Project currentProject : projectConfigs.keySet()) {
Resolver resolver = new Resolver(currentProject, resolutionStrategy, checkConstraints)
Expand Down
Expand Up @@ -59,6 +59,7 @@ class DependencyUpdatesTask extends DefaultTask {
boolean checkForGradleUpdate = true

boolean checkConstraints = false
boolean checkBuildEnvironmentConstraints = false

@Input
boolean getCheckForGradleUpdate() {
Expand All @@ -70,6 +71,11 @@ class DependencyUpdatesTask extends DefaultTask {
return checkConstraints
}

@Input
boolean getCheckBuildEnvironmentConstraints() {
return checkBuildEnvironmentConstraints
}

@Internal
Object outputFormatter = 'plain'

Expand All @@ -96,7 +102,7 @@ class DependencyUpdatesTask extends DefaultTask {

def evaluator = new DependencyUpdates(project, resolutionStrategyAction, revisionLevel(),
outputFormatterProp(), outputDirectory(), getReportfileName(), checkForGradleUpdate, gradleReleaseChannelLevel(),
checkConstraints)
checkConstraints, checkBuildEnvironmentConstraints)
DependencyUpdatesReporter reporter = evaluator.run()
reporter?.write()
}
Expand Down
Expand Up @@ -131,7 +131,7 @@ class Resolver {
copy.setCanBeResolved(true)
}

// Resolve using the latest version of explicitly declaired dependencies and retains Kotlin's
// Resolve using the latest version of explicitly declared dependencies and retains Kotlin's
// inherited stdlib dependencies from the super configurations. This is required for variant
// resolution, but the full set can break consumer capability matching.
Set<Dependency> inherited = configuration.allDependencies.findAll { dependency ->
Expand Down
Expand Up @@ -4,6 +4,7 @@ import org.gradle.testkit.runner.GradleRunner
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.Specification
import spock.lang.Unroll

import static org.gradle.testkit.runner.TaskOutcome.SUCCESS

Expand Down Expand Up @@ -131,4 +132,125 @@ final class ConstraintsSpec extends Specification {
result.output.contains('No dependencies found.')
result.task(':dependencyUpdates').outcome == SUCCESS
}

@Unroll
def 'Do not show updates for an gradle constraint (added in 7.3.2/6.9.2) with Gradle #gradleVersion'() {
given:
ExpandoMetaClass.disableGlobally()
def srdErrWriter = new StringWriter()
buildFile = testProjectDir.newFile('build.gradle.kts')
buildFile <<
"""
plugins {
java
id("com.github.ben-manes.versions")
}
tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask> {
checkConstraints = true
}
""".stripIndent()
when:
def result = GradleRunner.create()
.withGradleVersion(gradleVersion)
.withProjectDir(testProjectDir.root)
.withArguments('dependencyUpdates')
.forwardStdError(srdErrWriter)
.withPluginClasspath()
.build()
then:
!result.output.contains('org.apache.logging.log4j:log4j-core [2.16.0 -> ')
srdErrWriter.toString().empty
result.task(':dependencyUpdates').outcome == SUCCESS
where:
gradleVersion << [
'6.9.2',
'7.3.2',
'7.3.3'
]
}
def "Show updates for log4j-core even if the constraint added by gradle is ignored"() {
given:
def mavenRepoUrl = getClass().getResource('/maven/').toURI()
ExpandoMetaClass.disableGlobally()
def srdErrWriter = new StringWriter()
buildFile = testProjectDir.newFile('build.gradle.kts')
buildFile <<
"""
plugins {
java
id("com.github.ben-manes.versions")
}
repositories {
maven {
url = uri("${mavenRepoUrl}")
}
}
dependencies {
constraints {
implementation ("org.apache.logging.log4j:log4j-core:2.16.0")
}
}
tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask> {
checkConstraints = true
}
""".stripIndent()
when:
def result = GradleRunner.create()
.withGradleVersion('7.3.2')
.withProjectDir(testProjectDir.root)
.withArguments('dependencyUpdates')
.forwardStdError(srdErrWriter)
.withPluginClasspath()
.build()
then:
result.output.contains('org.apache.logging.log4j:log4j-core [2.16.0 -> ')
srdErrWriter.toString().empty
result.task(':dependencyUpdates').outcome == SUCCESS
}
def "Show updates for a dependencies constraint in init scripts"() {
given:
def mavenRepoUrl = getClass().getResource('/maven/').toURI()
ExpandoMetaClass.disableGlobally()
def srdErrWriter = new StringWriter()
buildFile = testProjectDir.newFile('build.gradle.kts')
buildFile <<
"""
plugins {
java
id("com.github.ben-manes.versions")
}
repositories {
maven {
url = uri("${mavenRepoUrl}")
}
}
tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask> {
checkBuildEnvironmentConstraints = true
}
""".stripIndent()
when:
def result = GradleRunner.create()
.withGradleVersion('7.3.2')
.withProjectDir(testProjectDir.root)
.withArguments('dependencyUpdates')
.forwardStdError(srdErrWriter)
.withPluginClasspath()
.build()
then:
result.output.contains('org.apache.logging.log4j:log4j-core [2.16.0 -> ')
srdErrWriter.toString().empty
result.task(':dependencyUpdates').outcome == SUCCESS
}
}

0 comments on commit 3a6f716

Please sign in to comment.