Skip to content

Commit

Permalink
Refactor plugin to be configuration aware
Browse files Browse the repository at this point in the history
Previously the dependencies were resolved in a detached configuration,
which had a few bad side effects. One is that the same dependency with
different versions would be resolved to the latest and be shown once.
The other is that the configuration's resolutionStrategy and compoent
rules were not honored.

Now every configuration is resolved (safely by cloning) and the report
an aggregate of the results. This lets us decide if we should auto
include all repositories found, which may sometimes cause misbehaviors.

This is a major refactoring to transition the code from a scripting
style to a Java style. This is mostly needed for code clarity, as the
former style made sense when the plugin was untyped. The contribution
to being type-safe was a nice addition, but made the code appear
awkward.

The ability to define custom resolution strategies allows filtering
the report to disallow release candidates or other exclusion policies.
  • Loading branch information
ben-manes committed Jun 24, 2015
1 parent dd110a5 commit 3392948
Show file tree
Hide file tree
Showing 11 changed files with 1,025 additions and 222 deletions.
37 changes: 32 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ this plugin provides a task to determine which dependencies have updates.

## Usage

This plugin is available from [Bintray's JCenter repository](http://jcenter.bintray.com/). You can add it to your build script using
the following configuration:
This plugin is available from [Bintray's JCenter repository](http://jcenter.bintray.com). You can
add it to your build script using the following configuration:

```groovy
apply plugin: 'com.github.ben-manes.versions'
Expand All @@ -17,12 +17,12 @@ buildscript {
}
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.10.1'
classpath 'com.github.ben-manes:gradle-versions-plugin:0.11'
// classpath 'org.codehaus.groovy:groovy-backports-compat23:2.3.5' // uncomment if you're using Gradle 1.x
}
}
```
The current version is known to work with Gradle versions up to 2.4.
The current version is known to work with Gradle versions up to 2.5-rc-1.

## Tasks

Expand All @@ -32,6 +32,8 @@ Displays a report of the project dependencies that are up-to-date, exceed the la
have upgrades, or failed to be resolved. When a dependency cannot be resolved the exception is
logged at the `info` level.

#### Revisions

The `revision` task property controls the resolution strategy of determining what constitutes the
latest version of a dependency. The following strategies are supported:

Expand All @@ -45,7 +47,31 @@ The strategy can be specified either on the task or as a system property for ad
gradle dependencyUpdates -Drevision=release
```

Another task property `outputFormatter` controls the report output format. The following values are supported:
The latest versions can be further filtered using [Component Selection Rules][component_selection_rules].
For example to disallow release candidates as upgradable versions a selection rule could be defined as:

```groovy
configurations {
all {
resolutionStrategy {
componentSelection {
all { ComponentSelection selection ->
boolean rejected = ['alpha', 'beta', 'rc'].any { qualifier ->
selection.candidate.version.contains(qualifier)
}
if (rejected) {
selection.reject("Release candidate")
}
}
}
}
}
}
```

#### Report format

The task property `outputFormatter` controls the report output format. The following values are supported:

* `"plain"`: format output file as plain text (default)
* `"json"`: format output file as json text
Expand Down Expand Up @@ -243,3 +269,4 @@ XML report
</response>
```

[component_selection_rules]: https://docs.gradle.org/current/userguide/dependency_management.html#component_selection_rules
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-rc-1-all.zip
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2012-2015 Ben Manes. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.benmanes.gradle.versions.updates

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import groovy.transform.TupleConstructor
import groovy.transform.TypeChecked
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ModuleVersionIdentifier
import org.gradle.api.artifacts.ModuleVersionSelector
import org.gradle.api.artifacts.ResolvedDependency

/**
* The dependency's coordinate.
*
* @author Ben Manes ([email protected])
*/
@TypeChecked
@EqualsAndHashCode
class Coordinate {
final String groupId
final String artifactId
final String version

public Coordinate(String groupId, String artifactId, String version) {
this.groupId = groupId ?: 'none'
this.artifactId = artifactId ?: 'none'
this.version = version ?: 'none'
}

public Key getKey() {
return new Key(groupId, artifactId)
}

@Override
public String toString() {
return groupId + ':' + artifactId + ':' + version
}

static Coordinate from(ModuleVersionSelector selector) {
return new Coordinate(selector.group, selector.name, selector.version)
}

static Coordinate from(Dependency dependency) {
return new Coordinate(dependency.group, dependency.name, dependency.version)
}

static Coordinate from(ModuleVersionIdentifier identifier) {
return new Coordinate(identifier.group, identifier.name, identifier.version)
}

@EqualsAndHashCode
static class Key {
final String groupId
final String artifactId

private Key(String groupId, String artifactId) {
this.groupId = groupId
this.artifactId = artifactId
}

@Override
public String toString() {
return groupId + ':' + artifactId
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2012-2015 Ben Manes. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.benmanes.gradle.versions.updates

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import groovy.transform.TypeChecked
import org.gradle.api.artifacts.UnresolvedDependency

/**
* The version status of a dependency.
* <p>
* The <tt>latestVersion</tt> is set if the dependency was successfully resolved, otherwise the
* <tt>unresolved</tt> contains the exception that caused the resolution to fail.
*
* @author Ben Manes ([email protected])
*/
@ToString
@TypeChecked
@EqualsAndHashCode
class DependencyStatus {
final UnresolvedDependency unresolved
final Coordinate coordinate
final String latestVersion

DependencyStatus(Coordinate coordinate, String latestVersion) {
this.latestVersion = latestVersion
this.coordinate = coordinate
}

DependencyStatus(Coordinate coordinate, UnresolvedDependency unresolved) {
this.coordinate = coordinate
this.unresolved = unresolved
this.latestVersion = 'none'
}

Coordinate getLatestCoordinate() {
return new Coordinate(coordinate?.groupId, coordinate?.artifactId, latestVersion)
}
}
Loading

1 comment on commit 3392948

@jochenberger
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed something else: For a project that has the jacoco plugin applied, 0.11.x started listing the org.jacoco:org.jacoco.agent:0.7.1.201405082137 and org.jacoco:org.jacoco.ant:0.7.1.201405082137 dependencies. Is this intentional?

Please sign in to comment.