Skip to content

IntershopCommunicationsAG/versionrecommender-gradle-plugin

Repository files navigation

Version Recommender Plugin

Note
Version 2 of this plugin will only work with Gradle 4 and JDK 8.

Summary

With this plugin it is possible to maintain the version of dependencies in other sources. This plugin helps to handle the version of dependencies in large projects with a lot of multi projects consistent It allows to leave the version number empty in your project configuration. The following version recommendation providers are available:

  • Ivy file

  • Maven pom / bom file

  • Properties file

  • Static properties

Depending on the kind of version provider it is possible to run automatic updates on request. In addition this plugin provides an extension to create Ivy or BOM file filters.

Note
This plugin should always be applied to the root project.

Usage

To use the Version Recommender plugin provided by Intershop, include the following code snippet into the build script of your root project:

build.gradle
plugins {
    id 'com.intershop.gradle.versionrecommender' version '2.3.0'
}

versionRecommendation {
    provider {
        ivy('ivy_name', 'org.company:ivyfilter:1.0.0') {}
    }
    updateConfiguration {
        ivyPattern = '[organisation]/[module]/[revision]/[type]s/ivy-[revision].xml'

        defaultUpdateProvider = ['ivy_name']
    }
}

Tasks

The Version Recommender plugin adds the following tasks to the project:

Task name Type Description

setLocal[ProviderName]

setLocalVersion

This task adds 'LOCAL' to the version of an dependency configuration of a provider ’[ProviderName]'`. For a properties file provider all configured versions will be extended with 'LOCAL'.

setSnapshot[ProviderName]

setSnapshotVersion

Does the same as 'setLocal[ProviderName]' but with 'SNAPSHOT'.

set[ProviderName]

setVersion

This sets a version from a project property to the dependency of the provider ’[ProviderName]'`. The project property is: '[ProviderName]Version'.

update[ProviderName]

UpdateVersion

An update of the version of a dependency of provider ’[ProviderName]'` can be started with this task. The update functionality can be configured in the closure updateConfiguration.

store[ProviderName]

StoreUpdateVersion

Store the temporary changes to the configuration directory.

reset[ProviderName]

ResetVersion

The temporary changes will be removed.

update

Update

An update for configured providers can be started with this task. These providers can be configured with 'defaultUpdateProvider'.

setVersion

SetAllVersion

This task sets a version from a project property to a provider which is configured in 'defaultUpdateProvider'. If a project property '[ProviderName]Version' is configured, this setting is used. Do not store this configuration.

store

StoreUpdate

Temporary changes of configured providers will be stored in the configuration directory with this task. These providers can be configured with 'defaultUpdateProvider'.

reset

ResetAllVersion

This task removes all temporary changes of all providers.

All tasks are part of the package 'com.intershop.gradle.versionrecommender.tasks'.

The tasks are only available for filters with an dependency configuration or for the property filter configuration if the file is located in the project directory. Temporary version configuration will be stored in files in a working directory, which is per default located in the build directory of the root project. The file name of this configuration is '.[providerType][ProviderName].version', e.g., .ivyProviderName.version.

Save update changes to the source control system

If the tasks store or store[ProviderName] should save the changes also to the used version control system, it is necessary to set a project property scmCommit to true. This plugin supports Subversion with over http(s) with basic authentication and Git over http(s) with basic authenticationand and over ssh with an authentication with an private key. The required credentials must be provided. It is possible to specify project properties, system variables or Java system properties.

System variable or Java system property Project property Description

SCM_USERNAME

scmUserName

This is the username of a basic authentication for Subversion or Git over http(s).

SCM_PASSWORD

scmUserPasswd

This is the password of a basic authentication for Subversion or Git over http(s).

SCM_KEYFILE

scmKeyFile

This is the path to the keyfile of an authentication for Git over ssh.

SCM_KEYPASSPHRASE

scmKeyPassphrase

This is the optional passphrase for the keyfile of an authentication for Git over ssh.

Project Extension 'versionRecommendation'

This plugin adds an extension versionRecommendation to the root project. This extension contains the plugin configuration for the version recommendation and also for the update functionality.

Methods

Method Type Description

provider(Closure)

RecommendationProviderContainer

This method configures the container of all providers. The order of items depends on the order in the build configuration

updateConfiguration(Closure)

UpdateConfiguration

This method configures the update configuration.

Attributes

Property Type Default value Description

forceRecommenderVersion

boolean

false

If set to true, the version is always taken from the version recommendation. This will override configured versions in dependencies.

excludeProjectsbyName

List<String>

[]

This projects are excluded from the version recommendation configuration.

Provider configuration 'provider' (RecommendationProviderContainer)

Method Type Description

ivy(String, Object, Closure)

IvyRecommendationProvider

Adds an Ivy based recommendation provider

pom(String, Object, Closure)

MavenRecommendationProvider

Adds a Pom based recommendation provider

properties(String, Object, Closure)

PropertiesRecommendationProvider

Adds a properties file base recommendation provider

properties(String, Closure)

PropertiesRecommendationProvider

Adds a property configuration with a map

getVersion(String, String)

String

Returns a version from the provider list configuration or null

The first parameter is always the name of the provider. It is used for project properties and tasks.

The second parameter is the input of the provider. The following inputs are possible:

  • Dependency

    • This can be a Map, eg. [group: 'com.company', name: 'module', version: 'version'], or
      a String, e.g., com.company:module:version

    • It is possible to leave the version empty, so that the provider is not used per default. With 'set[ProviderName]' it is possible to enable this provider with a specific version.

    • The version can be adapted for this input configuration, with 'set[ProviderName]', 'setLocal[ProviderName]', 'setSnapshot[ProviderName]' and 'update[ProviderName]'.

  • URL

    • Configuration for direct access via URL.

    • The version for this configuration is not adaptable.

  • File

    • This is the configuration for a special file. This file should be part of the project.

    • If this is specified for a properties provider, the versions inside of the file are adaptable and selected properties can be excluded with a configuration if necessary.

Ivy Recommendation Provider

The Ivy recommendation provider uses an Ivy file to create a map with modules and versions. All dependency configurations are used and Ivy configurations are not considered. Of course it is possible to configure this provider also with an URL or with a file definition, but a dependency definition should be the most common configuration for this provider. The dependency configuration of the provider is also added to the version map of the provider.

build.gradle
versionRecommendation {
    provider {
        ivy('providerName', 'org.company:ivyfilter:1.0.0') {}
        ivy('providerName', [group: 'org.company', name: 'versions', version: '1.0.0']) {
            transitive = true
            overrideTransitiveDeps = false
            versionMap = [ 'com.company:componet1':'1.0.0' ]

            workingDir = new File(project.buildDir, 'providerWorkingDir')
            configDir = file('providerName')
        }
    }
}

This provider can be used with additional properties.

Attributes
Property Type Default value Description

transitive

boolean

false

If set to true, all dependencies from the Ivy file will be resolved transitive.

overrideTransitiveDeps

boolean

false

If set to true, the provider will override a previous version for a module if it finds a later version of that very module via a transitive dependency.

versionMap

Map<String, String>

[:]

The entries of this map will be added at the end of the existing map. This version map can also contain patterns for the key, e.g., 'com.company:*'.

workingDir

File

buildDir/versionRecommendation

This directory is used for temporary version files. The name of this file is '.ivy[ProviderName].version'. This version configuration will overwrite the build script and the configuration in the configuration directory.

configDir

File

projectDir

This directory is used for persistent version files. The name of this file is '.ivy[ProviderName].version'. This version configuration will overwrite the build script configuration.

Pom Recommendation Provider

The Maven recommendation provider uses a Maven Bom file to create a map with modules and versions. All dependency configurations are used and a scope is not considered. Of course it is possible to configure this provider also with an URL or with a file definition, but a dependency definition should be the most common configuration for this provider. All dependencies are resolved transitive and the dependency configuration of the provider is also added to the version map of the provider.

build.gradle
versionRecommendation {
    provider {
        pom('providerName', 'org.company:bomfilter:1.0.0') {}
        pom('providerName', [group: 'org.company', name: 'versions', version: '1.0.0']) {
            versionMap = [ 'com.company:componet1':'1.0.0' ]

            workingDir = new File(project.buildDir, 'providerWorkingDir')
            configDir = file('providerName')
        }
    }
}

This provider can be used with additional properties.

Attributes
Property Type Default value Description

versionMap

Map<String, String>

[:]

The entries of this map will be added on the end of the existing map. This version map can also contain patterns for the key, e.g., 'com.company:*'.

workingDir

File

buildDir/versionRecommendation

This directory is used for temporary version files. The name of this file is '.pom[ProviderName].version'. This version configuration will overwrite the build script and the configuration in the configuration directory.

configDir

File

projectDir

This directory is used for persistent version files. The name of this file is '.pom[ProviderName].version'. This version configuration will overwrite the build script configuration.

Properties Recommendation Provider

The properties recommendation provider uses a properties file to create a map with modules and versions. The format of this property file is special, because a colon is allowed in the keys. Furthermore, the format and the order of all entries will be preserved, if the file is changed by a task.

The input of this provider may also be an URL or dependency, but this input types are not supported by the tasks for version adaptions.

build.gradle
versionRecommendation {
    provider {
        properties('providerName', rootProject.file('version.properties')) {}
        properties('providerName', rootProject.file('3rdPartsVersion.properties')) {
            transitive = true
            overrideTransitiveDeps = false
            versionMap = [ 'com.company:componet1':'1.0.0' ]

            workingDir = new File(project.buildDir, 'providerWorkingDir')
        }
    }
}

It is also possible to specify static properties only with an properties provider configuration.

build.gradle
versionRecommendation {
    provider {
        properties('providerName') {
            versionMap = [ 'com.company:componet1':'1.0.0' ]
        }
    }
}

This provider can be used with additional properties.

Attributes
Property Type Default value Description

changeExcludes

List<String>

[]

The property keys that match to one of this items, are not changed by 'set[ProviderName]', 'setLocal[ProviderName]', 'setSnapshot[ProviderName]' and 'update[ProviderName]'.

versionMap

Map<String, String>

[:]

The entries of this map will be added at the end of the existing map. This version map can also contain patterns for the key, e.g., 'com.company:*'.

workingDir

File

buildDir/versionRecommendation

This directory is used for temporary property files. The name of this file is the configured one. This version configuration will overwrite the configuration in the configuration directory.

Update Configuration 'updateConfiguration' (UpdateConfiguration)

This configuration configures the update functionality.

Methods
Method Type Description

updateConfigItemContainer(Closure)

UpdateConfigurationItem

Configures an item configuration container

addConfigurationItem(UpdateConfigurationItem)

Adds an item to the configuration container

getUpdate(String, String, String)

String

Returns an updated version for a specified group, module name and the original version. The paramters are group, name, version. It returns null if no newer version was found.

Attributes
Property Type Default value Description

ivyPattern

String

''

An Ivy pattern for Ivy Repositories. See http://ant.apache.org/ivy/history/latest-milestone/concept.html. Without this pattern Ivy repositories will not be analyzed.

updateLogFile

File

buildDir/
versionRecommendation/
update/update.log

This file contains more detailed information.

defaultUpdateProvider

List<String>

[]

A list of providers which will be updated if the task 'update' runs.

defaultUpdate

String

HOTFIX

String representation of updatePos. This attribute is readable and writable. The following values are possible MAJOR, MINOR, PATCH, HOTFIX and NONE.

updatePos

UpdatePos

UpdatePos.HOTFIX

This attribute gives the value of defaultUpdate as UpdatePos if the string can be converted. This is the default position for update tasks.

Update Configuration Item(UpdateConfigurationItem)

The order of the items is controlled by the container and is the alphabetical order of the names. The configuration is assigned to the dependencies over the group and module name. It is possible to use patterns.

build.gradle
versionRecommendation {
    provider {... }
    updateConfiguration {
        ivyPattern = '[organisation]/[module]/[revision]/[type]s/ivy-[revision].xml'

        updateConfigItemContainer {
            updateJetty {
                org = 'org.eclipse.jetty'
                searchPattern = '\\.v\\d+'
            }
            updateGoogleAPI {
                org = 'com.google.apis'
                module = 'google-api-services-appsactivity'
                patternForNextVersion = '^(v1-rev)(\\d+)(-1\\.20\\.0)$'
                sortStringPos = 2
            }
        }
    }
}

The example configuration 'updateJetty' will be used to update all dependencies to the organization 'org.eclipse.jetty'. 'updateGoogleAPI' is used only for the update of 'com.google.apis:google-api-services-appsactivity'.

Attributes
Property Type Default value Description

org

String

''

The pattern for the organization or group If this attribute is empty this configuration matches in any case.

module

String

''

The pattern for the module name or artifact ID If this attribute is empty this configuration matches in any case.

version

String

''

This version is taken for the next update, if configured.

The following property is used for the update of extended sematic versions.
See https://github.com/IntershopCommunicationsAG/extended-version

update

String

'HOTFIX'

String representation of updatePos. This attribute is readable and writable. The following values are possible MAJOR, MINOR, PATCH, HOTFIX and NONE.

updatePos

UpdatePos

UpdatePos.HOTFIX

This attribute gives the value of update as UpdatePos if the string can be converted. This is the default position for the update task.

The next attributes are used to configure the semantic version with special extensions, e.g., 2.0.0.201206130900-r

searchPattern

String

''

Search pattern for the extension, e.g., '\\.\\d+-r'

versionPattern

String

searchPattern

If the extension of the current version is different, it is possible to define a separate pattern.

For very special versions like special Google libs, e.g., v1-rev12-1.21.0, it is possible to use the next two attributes.

patternForNextVersion

String

''

This pattern helps to identify a special part of the version string for comparison, e.g., '^(v1-rev)(\\d+)(-1\\.21\\.0)$'

sortStringPos

int

0

This number specifies the selected group for comparison, e.g., 2.

Examples
  • Extended semantic versions: 1.0.0.0, 1.0.0, 1.0, 1

  • Extended semantic verisons with special extensions

Version Example Search Pattern Comment

'1.2.0.201112221803-r'

'\\.\\d+-r'

'.201112221803-r' will be ignored and only '1.2.0' is used for comparison.

'9.2.9.v20150224'

'\\.v\\d+'

'.v20150224' will be ignored and only '9.2.9' is used for comparison.

  • Special version strings

Version Example Pattern Pos Comment

'v1-rev12-1.21.0'

'^(v1-rev)(\\d+)(-1\\.21\\.0)$'

2

Only 12 is used for comparison and update.

'v1-rev12-1.21.0'

'^(v1-rev12)(-1\\.)(\\d+)(\\.0)$'

3

Only 21 is used for comparison and update.

Project Extension 'versionManagement'

This plugin adds an extension versionManagement to the root project. This extension contains methods that add functionality to the publication configuration.

Methods

Method Type Description

withSubProjects(configure)

List<Project> or Project

A list of sub projects or a single sub project, e.g., 'subprojects'

fromConfigurations(configure)

List<String> or String

A list or a single configuration of the project, e.g., 'compile'.

withDependencies(configure)

List<String> or String

A list or a single string with a dependency configuration, e.g., 'com.company:module:version'.

Usage

Ivy Publishing

build.gradle
plugins {
    id 'com.intershop.gradle.versionrecommender' version '2.3.0'
    id 'ivy-publish'
}

configurations { compile }

dependencies {
    compile 'commons-configuration:commons-configuration:1.6'
}

publishing {
    publications {
        ivyFilter(IvyPublication) {
            module 'ivy-filter'
            revision project.version

            // adds all sub projects
            versionManagement.withSubProjects { subprojects }

            // the transitive closure of this configuration will
            // be flattened and added to the dependency management section
            versionManagement.fromConfigurations { project.configurations.compile }

            // alternative syntax when you want to explicitly add a dependency with no transitives
            versionManagement.withDependencies { 'manual:dep:1' }

            // further customization of the POM is allowed if desired
            descriptor.withXml {
                asNode().info[0].appendNode('description',
                                            'A demonstration of IVY customization')
            }
        }
    }
    repositories {
        ivy {
            // change to point to your repo, e.g. http://my.org/repo
            url "$buildDir/repo"
            layout('pattern') {
                ivy '[organisation]/[module]/[revision]/[type]s/ivy-[revision].xml'
                artifact '[organisation]/[module]/[revision]/[ext]s/[artifact]-[type](-[classifier])-[revision].[ext]'
            }
        }
    }
}

repositories {
    jcenter()
}

Executing the Gradle publishing task will generate the following ivy.xml file.

ivy.xml
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
  <info organisation="com.intershop" module="ivy-filter" revision="1.0.0" status="integration" publication="20170222210207">
    <description>A demonstration of IVY customization</description>
  </info>
  <configurations/>
  <publications/>
  <dependencies defaultconfmapping="*-&gt;default">
    <!-- sub projects -->
    <dependency org="com.intershop" name="project1a" rev="1.0.0" conf="default"/>
    <dependency org="com.intershop" name="project2b" rev="1.0.0" conf="default"/>
    <!-- dependencies from configuration compile -->
    <dependency org="commons-digester" name="commons-digester" rev="1.8" conf="default"/>
    <dependency org="commons-logging" name="commons-logging" rev="1.1.1" conf="default"/>
    <dependency org="commons-lang" name="commons-lang" rev="2.4" conf="default"/>
    <dependency org="commons-configuration" name="commons-configuration" rev="1.6" conf="default"/>
    <dependency org="commons-beanutils" name="commons-beanutils" rev="1.7.0" conf="default"/>
    <dependency org="commons-collections" name="commons-collections" rev="3.2.1" conf="default"/>
    <dependency org="commons-beanutils" name="commons-beanutils-core" rev="1.8.0" conf="default"/>
    <!-- dependency -->
    <dependency org="manual" name="dep" rev="1" conf="default"/>
  </dependencies>
</ivy-module>

Maven Publishing

build.gradle
plugins {
    id 'com.intershop.gradle.versionrecommender' version '2.3.0'
    id 'maven-publish'
}

configurations { compile }

dependencies {
    compile 'commons-configuration:commons-configuration:1.6'
}

publishing {
    publications {
        mvnFilter(MavenPublication) {
            artifactId 'mvn-filter'
            version project.version

            // adds all sub projects
            versionManagement.withSubProjects { subprojects }

            // the transitive closure of this configuration will
            // be flattened and added to the dependency management section
            versionManagement.fromConfigurations { project.configurations.compile }

            // alternative syntax when you want to explicitly add a dependency with no transitives
            versionManagement.withDependencies { 'manual:dep:1' }

            // further customization of the POM is allowed if desired
            pom.withXml {
                asNode().appendNode('description',
                                    'A demonstration of maven customization')
            }
        }
    }
    repositories {
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url "$buildDir/repo"
        }
    }
}

repositories {
    jcenter()
}

Executing the Gradle publishing task will generate the following *.pom file.

mvn-filter.pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.intershop</groupId>
  <artifactId>mvn-filter</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <dependencyManagement>
    <dependencies>
      <!-- project dependencies -->
      <dependency>
        <groupId>com.intershop</groupId>
        <artifactId>project1a</artifactId>
        <version>1.0.0</version>
      </dependency>
      <dependency>
        <groupId>com.intershop</groupId>
        <artifactId>project2b</artifactId>
        <version>1.0.0</version>
      </dependency>
      <!-- dependencies from configuration compile -->
      <dependency>
        <groupId>commons-digester</groupId>
        <artifactId>commons-digester</artifactId>
        <version>1.8</version>
      </dependency>
      <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
      </dependency>
      <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
      </dependency>
      <dependency>
        <groupId>commons-configuration</groupId>
        <artifactId>commons-configuration</artifactId>
        <version>1.6</version>
      </dependency>
      <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.7.0</version>
      </dependency>
      <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.2.1</version>
      </dependency>
      <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils-core</artifactId>
        <version>1.8.0</version>
      </dependency>
      <!-- dependency -->
      <dependency>
        <groupId>manual</groupId>
        <artifactId>dep</artifactId>
        <version>1</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <description>A demonstration of maven customization</description>
</project>

Test

The integration tests using a test repositories. Therefore it is necessary to specify project properties for the test execution.

Table 1. Table Subversion test configuration
Test Property Description Value

svnurl

Root URL of the test project

Must be specified with environment variable SVNURL

svnuser

User name of Subversion test user

Must be specified with environment variable SVNUSER

svnpasswd

Password for Subversion test user

Must be specified with environment variable SVNPASSWD

Table 2. Table Git test configuration
Test Property Description Value

giturl

URL of the test project

Must be specified with environment variable GITURL

gituser

User name of Git test user

Must be specified with environment variable GITUSER

gitpasswd

Password for Git test user

Must be specified with environment variable GITPASSWD

Thanks

License

Copyright 2014-2016 Intershop Communications.

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

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.