Rules

Introduction

Rules are the means to configure how Deputy resolves version conflicts in the dependency graph that roots in the project currently being worked on. There is always one active default rule, which is either 'LATEST RELEASE', 'LATEST RELEASE (no scan)', 'PRESENT RELEASE' or 'SNAPSHOT'.
Additionally, the user can define zero, one or more exceptional rules, called...


The chapter on Dependency Recursion describes how the default rule and the exceptional rules are applied to become effective whereas this chapter tries to give a short characterisation of the types of rules available and the ideas behind them.

Default Rule 'LATEST RELEASE'

This is the default default rule. It is recommended that you use this as long as there is no good reason to use another one. If you want to change it, however, you can do so by using the popup menu on the rules node.

This rule effects that the latest available release of an artifact is chosen if it is not overruled by some other rule.

The latest release is defined to be the highest entry in the descendingly ordered list of all versions to consider excluding SNAPSHOT versions.

The ordered list of all versions to consider for this choice is produced in one of two possible ways for each artifact:

  • If the artifact resides in a repository which is configured to be 'scannable' the list of all versions to consider is generated from all the artifact's POMs in this repository. That way, latest release means: the latest that has been published in the repository.
  • Else, if the artifact resides in a repository which is configured NOT to be 'scannable' the list of all versions to consider is generated from all the artifact's versions that the recursion encounters on its way through the dependency graph. That way, latest release means: the latest that has been demanded by at least one of the dependees in the dependency graph.

The latter type of repository configuration is useful for repositories of third party artifacts which are not under full control of the software project that use them. Here, one usually doesn't want to fish the latest stuff only because it exists (put there by some foreigner) but only when at least one of one's own components' really states a need for it. The 'Scannable' property can be configured for each repository in the dialog 'Edit Repository Configs' (see Edit menu).

Taking the latest release will be overruled in any of the following cases:

  • if there is at least one dependee in the dependency graph that depends on more recent SNAPSHOT and this SNAPSHOT is neither deprecated nor overruled by an enforcement rule, the SNAPSHOT will be taken instead
  • if there is a rule deprecating the latest release
  • if there is a rule enforcing a different version

Default Rule 'LATEST RELEASE (no scan)'

This rule works exactly like the rule 'LATEST RELEASE' except that no repository is scanned for later releases even if the repository is configured to be scannable. Instead, latest releases are only searched for within the dependency graph being traversed. Using this rule will avoid that you get releases newer than absolutely necessary (with respect to what the POMs of the projects in your dependency graph require).

Default Rule 'PRESENT RELEASE'

This rule is particularly useful if you want to minimize the number of changes that occur when applying the rules. Whenever a default choice must be performed, it will be the version that existed in the POM just before applying the rules. If the artifact was not present in the POM so far or if it was a SNAPSHOT, the latest release will be chosen as default.

Default Rule 'SNAPSHOT'

This rule effects that the SNAPSHOT of an artifact is chosen if it is not overruled by some other rule.

Taking the SNAPSHOT will be overruled in any of the following cases:

  • if there is a rule deprecating the SNAPSHOT
  • if there is a rule enforcing a different version

Enforcement Rules

An enforcement rule breaks the default rule for an artifact and ensures that exactly the version specified by the enforcement will be chosen instead in all cases.

The most common use case for enforcement rules is to enforce the SNAPSHOT for the subset of dependencies that are currently under construction by a team of developers.

An enforcement rule has no effect if there is a retention rule for the same artifact.

Deprecation Rules

A deprecation rule may break the default rule for an artifact by excluding the deprecated version from the list of versions to choose from. It says: 'Deputy may choose any version but not the deprecated one'.

In case all elements in the ordered list of selectable versions are deprecated or to be rejected for some other reason the last one is chosen nevertheless because Deputy cannot choose none.

If there is - against good reason - both an enforcement and a deprecation rule for the same artifact and the same version, the enforcement rule is stronger. An enforcement rule is a hard rule whereas a deprecation is only a soft rule which may be disregarded under some special circumstances.

The most common use case for a deprecation rule is to exclude a version that is known to cause problems in the context of the dependee.

Replacement Rules

Replacement rules can help in two cases:

  • If a dependency has been refactored by changing groups and/or by a change of its artifact id, it may well be for a transitional period that not all dependees have already been adapted to this change in their POMs. So, in order to tell Deputy that two differently named dependencies, which it may encounter while recursing over the dependency graph, are actually the same, a replacement rule is the means to do so.
  • If you need to create a branch for a project on which to work in parallel to the main code line, you have to rename the artifact id in the branched project to avoid a name clash of SNAPSHOTS in the repository. Now, if you test the branched component in an assembly you must add a replacement rule reflecting the renaming because the dependency graph may contain nodes which literally still depend (and will keep on depending) on the main code line's artifact.

You can create two flavours of replacement rules:

  • replace a group/artifact/version with some other group/artifact/version
  • replace a group/artifact with some other group/artifact/version (Recommended!)

The second option is the recommended one for the suggested use cases because it works for all versions of the artifact to be replaced. You can create this variant by selecting the artifact node (which doesn't have a version in its name) of the project to be replaced in the repository tree. In the dialog that pops up then, however, you must always also specify the version for the replacement project in order to ensure that it exists. Right after the replacement, however, this version is subject to be overruled by some other version according to the rules as any other non-replaced version would be, too.

While it is quite common to need a few enforcement rules and maybe also a couple of deprecations, replacement rules should rarely by required by an assembler.

Removal Rules

A removal rule excludes a dependency (and all its descendant dependencies, if not reachable otherwise) from the dependency recursion. The dependency affected by a removal rule is effectively treated as non-existent.

Removal rules can be specified for an artifact id or for an artifact id and a specific version. If you only specify the artifact id, all possible versions of the artifact will be affected. Usually, you would only specify the artifact id. You can do so by selecting the artifact node of the dependency to remove in the repositories browser tree.

If there is - against good reason - both a removal rule and some other rule referring to the same dependency, the other rule will be ignored.

The most common use case for a removal rule is to exclude a dependency, and thereby the whole sub dependency graph beneath, because it is simply not needed in some assembly.

Retention Rules

A retention rule ensures that all versions of an artifact encountered during the recursive process of applying the rules are retained as is in the result. This may lead to a resulting project definition that contains multiple dependencies to the same artifact! In fact, this is what this rule is good for. Practically, a retention rule overrules the normal behaviour and goal of Deputy of resolving version conflicts by choosing exactly one common version for all dependees. A retention rule does not yield a single version choice but simply ensures that all versions encountered anywhere in the dependency graph remain in the final result.

The envisaged use case of a retention rule is a component which must exist in the form of several versions in the same assembly at the same time. Such a component would change package or class names in each new version so that keeping old versions of it would not interfere with the additional usage of newer versions but guarantee downwards compatibility in the assembly.