2020-01-27 11:29:59 -05:00
|
|
|
Dependencies
|
|
|
|
============
|
|
|
|
|
|
|
|
Each gradle project can have multiple (named) "configurations"
|
|
|
|
and each configuration can have dependencies attached to it.
|
|
|
|
|
|
|
|
There are some standard conventions so, for example, the Java plugin
|
|
|
|
adds standard configurations such as "api", "implementation",
|
|
|
|
"testImplementation" and others. These configurations can also inherit
|
2024-06-17 03:49:21 -04:00
|
|
|
from each other; more about this topic can be found here:
|
2020-01-27 11:29:59 -05:00
|
|
|
|
|
|
|
https://docs.gradle.org/current/userguide/dependency_management_for_java_projects.html#dependency_management_for_java_projects
|
|
|
|
https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation
|
|
|
|
https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_plugin_and_dependency_management
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
Lucene uses the following configurations and attach project dependencies
|
|
|
|
to them:
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
moduleApi - makes the dependency available to main classes, tests and any
|
2020-01-27 11:29:59 -05:00
|
|
|
other modules importing the project (exportable dependency),
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
moduleImplementation - makes the dependency available to main classes, tests
|
|
|
|
but will *not* export the dependency to other modules (so their
|
2020-01-27 11:29:59 -05:00
|
|
|
compilation classpath won't contain it).
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
moduleTestImplementation - makes the dependency available for test classes only.
|
|
|
|
|
|
|
|
The "module" prefix is used to distinguish configurations which apply
|
|
|
|
to modular builds, compared to the regular classpath-configurations defined
|
|
|
|
by gradle's java module. Some Lucene modules may define regular classpath
|
|
|
|
entries to bypass the limitations of the module system (or gradle's).
|
2020-01-27 11:29:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
Adding a library dependency
|
|
|
|
---------------------------
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
Lucene dependencies and their versions are managed globally using version
|
|
|
|
catalogs (in versions.toml) [https://docs.gradle.org/current/userguide/platforms.html].
|
|
|
|
|
2020-01-27 11:29:59 -05:00
|
|
|
Let's say we wish to add a dependency on library "foo.bar:baz" in
|
|
|
|
version 1.2 to :lucene:core. Let's assume this library is only
|
|
|
|
used internally by the project. The :lucene:core project is configured
|
2024-06-17 03:49:21 -04:00
|
|
|
by lucene/core/build.gradle, so we add (or modify) the dependency
|
2020-01-27 11:29:59 -05:00
|
|
|
block as follows:
|
|
|
|
|
|
|
|
dependencies {
|
2024-06-17 03:49:21 -04:00
|
|
|
moduleImplementation deps.baz
|
2020-01-27 11:29:59 -05:00
|
|
|
}
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
The "moduleImplementation" here is a named configuration explained in the
|
|
|
|
section above. The "deps.baz" refers to the version catalog named "deps",
|
|
|
|
in which the dependency "baz" should be declared. If this is the first
|
|
|
|
reference to this library, then we have to add it to "versions.toml" catalog:
|
|
|
|
the version goes under the "versions" and module coordinates
|
|
|
|
under the "libraries" section:
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
[versions]
|
|
|
|
baz = "1.2"
|
|
|
|
...
|
|
|
|
[libraries]
|
|
|
|
baz = { module = "foo.bar:baz", version.ref = "baz" }
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
The version defined in the "versions" section is the preferred version of the library
|
|
|
|
we wish to use. Finally, run tidy to sort all entries in versions.toml:
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
gradlew tidy
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
Gradle will try to consolidate different versions across different
|
|
|
|
configurations to make sure they're compatible and may complain if it encounters
|
|
|
|
conflicting versions in the dependency tree. We want all dependencies to be consistent,
|
|
|
|
so we use an additional build plugin to ensure no accidental version changes
|
|
|
|
occur. Whenever we add or remove dependencies, we have to follow-up with lock file
|
|
|
|
regeneration:
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
gradlew writeLocks
|
|
|
|
git diff versions.*
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
IMPORTANT: The versions.lock file will contain a list of actual library versions
|
|
|
|
and configurations they occurred in.
|
2020-01-27 11:29:59 -05:00
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
Once a new dependency is added it always makes sense to regenerate the lock file
|
|
|
|
and look at which dependencies have changed (and why).
|
2020-01-27 11:29:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
Inspecting current dependencies
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
The tree of dependencies of a project (in all configurations) can
|
|
|
|
be dumped by the following command (example):
|
|
|
|
|
|
|
|
gradlew -p lucene\analysis\icu dependencies
|
|
|
|
|
|
|
|
But this can be a bit overwhelming; we will most likely be interested
|
|
|
|
in just the "publicly visible" and "classpath-visible" configurations.
|
|
|
|
|
|
|
|
The publicly visible project dependencies (classes shared by other
|
|
|
|
modules importing our module) can be displayed with:
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
gradlew -p lucene\analysis\icu dependencies --configuration moduleApi
|
2020-01-27 11:29:59 -05:00
|
|
|
|
|
|
|
And the "private" set of dependencies (real classpath) can be dumped
|
|
|
|
with:
|
|
|
|
|
2024-06-17 03:49:21 -04:00
|
|
|
gradlew -p lucene\analysis\icu dependencies --configuration moduleRuntimePath
|
2020-01-27 11:29:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
Excluding a transitive dependency
|
|
|
|
---------------------------------
|
|
|
|
|
|
|
|
Let's say "foo.bar:baz" has a transitive dependency on project
|
|
|
|
"foo.bar:irrelevant" and we know the transitive dependency is not
|
|
|
|
crucial for the functioning of "foo.bar:baz". We can exclude it
|
|
|
|
by adding an exclusion block to the original declaration:
|
|
|
|
|
|
|
|
dependencies {
|
2024-06-17 03:49:21 -04:00
|
|
|
implementation(deps.baz, {
|
2020-01-27 11:29:59 -05:00
|
|
|
exclude group: "foo.bar", module: "irrelevant"
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
Note the brackets - they are important and prevent accidental
|
|
|
|
mistakes of applying the exclusion to the wrong scope.
|
|
|
|
|
|
|
|
|
|
|
|
Updating dependency checksum and licenses
|
|
|
|
-----------------------------------------
|
|
|
|
|
|
|
|
The last step is to make sure the licenses, notice files and checksums
|
|
|
|
are in place for any new dependencies. This command will print what's
|
|
|
|
missing and where:
|
|
|
|
|
|
|
|
gradlew licenses
|
|
|
|
|
|
|
|
To update JAR checksums for licenses use:
|
|
|
|
|
|
|
|
gradlew updateLicenses
|