Skip to main content

2024-11-15

Quote

If you wish to buy osmanthus, bring wine along; the world’s greatest duel in the wilderness. — “Genshin Impact” · Yuyu


Gradle Version Catalog

This article explains how to define dependency versions in the Gradle Version Catalog, focusing on two main approaches: Plain Version Declarations and Rich Version Declarations.


1. Plain Version Declaration (Required Version)

  • Uses a simple string to declare the version—equivalent to “you must use exactly this version.”

  • Example:

    [versions]
    other-lib = "5.5.0"
  • Explanation:

    • The dependency other-lib is locked to version 5.5.0.
    • This method is straightforward but offers no flexibility.

2. Rich Version Declaration

  • Rich Version Declarations allow you to specify version requirements through multiple rules, offering greater flexibility.

  • Example:

    [versions]
    my-lib = { strictly = "[1.0, 2.0[", prefer = "1.2" }
  • Explanation:

    • strictly = "[1.0, 2.0[" enforces that the version must be within the range [1.0, 2.0[ (inclusive of 1.0, exclusive of 2.0).
    • prefer = "1.2" indicates that, if possible, version 1.2 should be chosen.
    • When both strictly and prefer apply, Gradle will pick 1.2 because it satisfies the range.

3. Supported Properties in Rich Versions

3.1 require: Mandatory Version

  • Equivalent to a plain version declaration.

  • If require is set, all other rules are ignored.

    [versions]
    lib = { require = "3.5.0" }

3.2 strictly: Strict Version Range

  • Constrains the version to a specific range; Gradle will fail if a version outside this range is resolved.

  • Common range syntax:

    • [1.0, 2.0] — closed interval (includes both 1.0 and 2.0).

    • [1.0, 2.0[ — half-open interval (includes 1.0, excludes 2.0).

    • (1.0, 2.0) — open interval (excludes both endpoints).

      [versions]
      lib = { strictly = "[1.0, 2.0]" }

3.3 prefer: Preferred Version

  • Specifies which version to choose when multiple candidates satisfy the constraints.

  • If strictly is not set, prefer alone will determine the version.

    [versions]
    lib = { prefer = "1.2.3" }

3.4 reject: Excluded Versions

  • Lists specific versions that must be excluded, even if they meet other constraints.

    [versions]
    lib = { reject = ["1.0", "1.1"] }
  • Explanation:

    • Versions 1.0 and 1.1 are explicitly forbidden.

3.5 rejectAll: Exclude All Versions

  • When rejectAll = true, no versions are allowed (useful to temporarily disable a dependency).

    [versions]
    lib = { rejectAll = true }

4. Use Cases and Rule Precedence

4.1 require

  • If require is present, Gradle ignores strictly, prefer, and other rules, enforcing the exact version.

4.2 strictly + prefer

  • strictly establishes the allowed range, and prefer selects your favorite version within that range.

    [versions]
    lib = { strictly = "[1.0, 2.0]", prefer = "1.5" }
  • If available versions are 1.2, 1.5, and 1.8, they all satisfy [1.0, 2.0], but Gradle will choose 1.5.

4.3 strictly + reject

  • Combine strictly and reject to both constrain the range and exclude certain versions.

    [versions]
    lib = { strictly = "[1.0, 2.0]", reject = ["1.3"] }
  • Given candidates 1.2, 1.3, and 1.5, version 1.3 is removed from consideration; Gradle picks 1.2 or 1.5.

4.4 rejectAll

  • When set to true, no version can be selected, causing dependency resolution to fail—useful for debugging or temporarily disabling a library.

5. Complete Example

[versions]
lib = { strictly = "[1.0, 2.0[", prefer = "1.5", reject = ["1.3", "1.4"] }
  • strictly: Range [1.0, 2.0[.
  • prefer: Preferred version 1.5.
  • reject: Forbids versions 1.3 and 1.4.

Summary

Gradle’s Rich Versions feature empowers you to finely control your dependency versions:

  • require to lock a version absolutely.
  • strictly to enforce a range.
  • prefer to steer resolution toward a favored release.
  • reject and rejectAll to explicitly exclude problematic or unwanted versions.

These mechanisms help ensure build stability and precise conflict management in complex projects.

Usage in build.gradle.kts:

dependencies {
implementation(libs.lib) {
version {
strictly("1.6")
}
}
}