Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLR-17406: Introduce Version Catalogs #2706

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
a0435d7
Introduce project-wide versions catalog
malliaridis Sep 10, 2024
f3f9dc0
Remove unused scriptDepVErsions.gradle
malliaridis Jul 12, 2024
efdabc4
Remove versionsPropsAreSorted gradle task
malliaridis Jul 13, 2024
fedc606
Replace versions.props references
malliaridis Jul 13, 2024
961c2bd
Migrate remaining dependencies and sync versions with versions.props
malliaridis Jul 13, 2024
c6a6933
Remove versions.props
malliaridis Jul 13, 2024
2d44f04
Remove palantir consistent versions plugin
malliaridis Jul 13, 2024
5e05300
Fix palantir's errorprone hacks
malliaridis Jul 17, 2024
f50e2c7
Add carrotsearch-dependencychecks plugin
malliaridis Jul 19, 2024
c74bfec
Use plugins from version catalog at remaining gradle files
malliaridis Jul 19, 2024
867fb11
Move buildSrc into a composite included build
malliaridis Jul 19, 2024
cb54484
Add and run tidy in included projects
malliaridis Jul 29, 2024
0585bba
Align and lock dependency versions
malliaridis Aug 22, 2024
cdc843f
Replace hamcrest-core with hamcrest
malliaridis Aug 22, 2024
6abab94
Add grpc bom
malliaridis Sep 5, 2024
db283a5
Sync netty versions with BOM
malliaridis Sep 10, 2024
98ec23e
Update licenses / hashes
malliaridis Sep 10, 2024
078ebbd
Fix dependency downgrade mistake from rebase
malliaridis Sep 10, 2024
05d30f2
Write locks
malliaridis Sep 10, 2024
83819ef
Update documentation about dependencies
malliaridis Aug 18, 2024
5825de2
Format version catalog
malliaridis Sep 11, 2024
94d8ca6
Remove unnecessary method reference
malliaridis Sep 16, 2024
eef39b2
Remove unnecessary method reference in getPackageVersion
malliaridis Sep 25, 2024
48c21cc
Fix typo in undercouch-download plugin
malliaridis Sep 25, 2024
50a4a81
Resolve eclipse.gradle null error and re-apply
malliaridis Sep 25, 2024
b895992
Fix errorprone issues
malliaridis Sep 25, 2024
101a323
Merge branch 'main' into SOLR-17406/rebase-version-catalogs
malliaridis Sep 30, 2024
6f92804
Migrate new modules to version catalogs
malliaridis Sep 30, 2024
3212b5b
Update licenses and sync versions
malliaridis Sep 30, 2024
699480d
Update list of consolidated configurations
malliaridis Oct 1, 2024
a0f4d1e
Merge with origin/main
malliaridis Oct 12, 2024
017fe17
Merge remote-tracking branch 'apache/main' into SOLR-17406/rebase-ver…
malliaridis Nov 8, 2024
6caff99
Sync versions with current main
malliaridis Nov 8, 2024
5824fdd
Write locks
malliaridis Nov 8, 2024
a763a69
Merge remote-tracking branch 'apache/main' into SOLR-17406/rebase-ver…
malliaridis Nov 9, 2024
7215a4c
Move remaining version references
malliaridis Nov 9, 2024
b41e9e5
Update version notes in netty constraints
malliaridis Nov 9, 2024
2b7519f
Fix typo
malliaridis Nov 11, 2024
d876ea0
Merge remote-tracking branch 'apache/main' into SOLR-17406/rebase-ver…
malliaridis Nov 13, 2024
e55348a
Resolve pending merge changes
malliaridis Nov 13, 2024
4e269b8
Follow lower-case naming convention in version references
malliaridis Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions build-tools/build-infra/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

plugins {
id "java-gradle-plugin"
id 'com.diffplug.spotless' version '6.5.2' apply false
alias(libs.plugins.diffplug.spotless) apply false
}

repositories {
Expand All @@ -34,12 +34,9 @@ apply from: file('../../gradle/validation/check-environment.gradle')
tasks.register("checkJdkInternalsExportedToGradle") {}
apply from: file('../../gradle/validation/spotless.gradle')

// Load common script dependencies.
apply from: file("../scriptDepVersions.gradle")

java {
sourceCompatibility = scriptDepVersions['min-java-version']
targetCompatibility = scriptDepVersions['min-java-version']
sourceCompatibility = JavaVersion.toVersion(libs.versions.java.min.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.java.min.get())
}

gradlePlugin {
Expand All @@ -57,5 +54,5 @@ dependencies {
implementation gradleApi()
implementation localGroovy()

implementation "commons-codec:commons-codec:${scriptDepVersions['commons-codec']}"
implementation libs.commonscodec.commonscodec
}
9 changes: 9 additions & 0 deletions build-tools/build-infra/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@
*/

rootProject.name = 'build-infra'

// Use project's version catalog for centralized dependency management
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../../gradle/libs.versions.toml"))
}
}
}
10 changes: 3 additions & 7 deletions build-tools/missing-doclet/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@

plugins {
id 'java-library'
id 'com.diffplug.spotless' version '6.5.2' apply false
alias(libs.plugins.diffplug.spotless) apply false
}

repositories {
mavenCentral()
}

version = "1.0.0-SNAPSHOT"
group = "org.apache.solr.tools"
description = 'Doclet-based javadoc validation'

Expand All @@ -36,12 +35,9 @@ apply from: file('../../gradle/validation/check-environment.gradle')
tasks.register("checkJdkInternalsExportedToGradle") {}
apply from: file('../../gradle/validation/spotless.gradle')

// Load common script dependencies.
apply from: file("../scriptDepVersions.gradle")

java {
sourceCompatibility = scriptDepVersions['min-java-version']
targetCompatibility = scriptDepVersions['min-java-version']
sourceCompatibility = JavaVersion.toVersion(libs.versions.java.min.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.java.min.get())
}

tasks.withType(JavaCompile).configureEach {
Expand Down
9 changes: 9 additions & 0 deletions build-tools/missing-doclet/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@
*/

rootProject.name = "missing-doclet"

// Use project's version catalog for centralized dependency management
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../../gradle/libs.versions.toml"))
}
}
}
33 changes: 0 additions & 33 deletions build-tools/scriptDepVersions.gradle

This file was deleted.

31 changes: 16 additions & 15 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,23 @@ import java.time.format.DateTimeFormatter
plugins {
id 'base'
id 'solr.build-infra'
id 'com.palantir.consistent-versions' version '2.16.0'
id 'org.owasp.dependencycheck' version '9.0.8'
id 'ca.cutterslade.analyze' version '1.10.0'
id 'de.thetaphi.forbiddenapis' version '3.7' apply false
id 'de.undercouch.download' version '5.5.0' apply false
id 'net.ltgt.errorprone' version '3.1.0' apply false
id 'com.diffplug.spotless' version '6.5.2' apply false
id 'com.github.node-gradle.node' version '7.0.1' apply false
}

apply from: file('build-tools/scriptDepVersions.gradle')
alias(libs.plugins.carrotsearch.dependencychecks)
alias(libs.plugins.owasp.dependencycheck)
alias(libs.plugins.cutterslade.analyze)
alias(libs.plugins.benmanes.versions)
alias(libs.plugins.littlerobots.versioncatalogupdate) apply false
alias(libs.plugins.thetaphi.forbiddenapis) apply false
alias(libs.plugins.undercouch.download) apply false
alias(libs.plugins.ltgt.errorprone) apply false
alias(libs.plugins.diffplug.spotless) apply false
alias(libs.plugins.nodegradle.node) apply false
alias(libs.plugins.openapi.generator) apply false
}

// Declare default Java versions for the entire project and for SolrJ separately
rootProject.ext.minJavaVersionDefault = JavaVersion.toVersion(scriptDepVersions['min-java-version'])
rootProject.ext.minJavaVersionSolrJ = JavaVersion.toVersion(scriptDepVersions['min-solrj-java-version'])
rootProject.ext.minJavaVersionDefault = JavaVersion.toVersion(libs.versions.java.min.get())
rootProject.ext.minJavaVersionSolrJ = JavaVersion.toVersion(libs.versions.java.solrj.get())

apply from: file('gradle/globals.gradle')

Expand Down Expand Up @@ -100,7 +102,7 @@ ext {
}

luceneBaseVersionProvider = project.provider {
def luceneVersion = getVersion('org.apache.lucene:lucene-core')
def luceneVersion = libs.versions.apache.lucene.get()
def m = (luceneVersion =~ /^\d+\.\d+\.\d+\b/)
if (!m) {
throw GradleException("Can't strip base version from " + luceneVersion)
Expand Down Expand Up @@ -150,7 +152,6 @@ apply from: file('gradle/validation/precommit.gradle')
apply from: file('gradle/validation/forbidden-apis.gradle')
apply from: file('gradle/validation/jar-checks.gradle')
apply from: file('gradle/validation/git-status.gradle')
apply from: file('gradle/validation/versions-props-sorted.gradle')
apply from: file('gradle/validation/validate-source-patterns.gradle')
apply from: file('gradle/validation/rat-sources.gradle')
apply from: file('gradle/validation/owasp-dependency-check.gradle')
Expand All @@ -161,7 +162,7 @@ apply from: file('gradle/validation/validate-log-calls.gradle')
apply from: file('gradle/validation/check-broken-links.gradle')

apply from: file('gradle/validation/solr.config-file-sanity.gradle')

apply from: file('gradle/validation/dependencies.gradle')
apply from: file('gradle/validation/spotless.gradle')

// Wire up included builds to some validation tasks.
Expand Down
20 changes: 12 additions & 8 deletions dev-docs/dependency-upgrades.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,34 @@
// specific language governing permissions and limitations
// under the License.

Solr has lots of 3rd party dependencies, defined mainly in `versions.props`.
Solr has lots of 3rd party dependencies, defined in `gradle/libs.versions.toml`.
Keeping them up-to-date is crucial for a number of reasons:

* minimizing the risk of critical CVE vulnerabilities by staying on a recent and supported version
* avoiding "dependency hell", that can arise from falling too far behind

Read the https://github.com/apache/solr/blob/main/help/dependencies.txt[help/dependencies.txt] file for an in-depth explanation of how gradle is deployed in Solr, using
https://github.com/palantir/gradle-consistent-versions[Gradle consistent-versions] plugin.
Read the https://github.com/apache/solr/blob/main/help/dependencies.txt[help/dependencies.txt] file for an in-depth
explanation of how dependencies are managed.

== Manual dependency upgrades
In order to upgrade a dependency, you need to run through a number of steps:

1. Identify the available versions from e.g. https://search.maven.org[Maven Central]
2. Update the version in `versions.props` file
3. Run `./gradlew --write-locks` to re-generate `versions.lock`. Note that this may cause a cascading effect where
2. Update the version in `gradle/libs.versions.toml` file
3. Run `./gradlew writeLocks` to re-generate `versions.lock`. Note that this may cause a cascading effect where
the locked version of other dependencies also change.
4. Run `./gradlew updateLicenses` to re-generate SHA1 checksums of the new jar files.
5. Once in a while, a new version of a dependency will transitively bring in brand-new dependencies.
4. In case of a conflict, resolve the conflict according to `help/dependencies.txt`
5. Check if there are any constraints that are obsolete after the dependency update
Copy link
Contributor

Choose a reason for hiding this comment

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

Check where? How does one identify an obsolete constraint?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The constraints are defined in gradle/validation/dependencies.gradle. There, if the updated dependency is listed, the constraint can be reviewed, updated or removed.

The constraints fall into two "groups". The first group are dependency constraints from dependencies that our project directly includes and require version alignment to sync the versions across all transitive dependencies.
The second group are dependencies that are only present as transitive dependencies. There, I followed the convention to provide additional information with "which dependencies use what version", so that the next person reviewing the constraint does not have to look it up. However, this is quite time-consuming to analyze the dependencies and therefore subject to change.

Now, in order to review a constraint, you have to check if the updated dependency is mentioned in any of the constraints, either as a reason for another dependency constraint or as the constraint's dependency. Removing temporarily a constraint, the task writeLocks will fail if the constraint is required.

This process and the constraints of dependencies.gradle are not optimal, as it is quite time-consuming and not obvious by just looking at it. We just haven't found yet a more efficient way to maintain these constraints.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant to imply that the documentation should answer these questions for the folks attempting to follow it :)

6. Update the license and notice files of the changed dependencies if necessary. See `help/dependencies.txt` for
Copy link
Contributor

Choose a reason for hiding this comment

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

Define necessary...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generally said, any difference in the LICENSE or NOTICE file of the affected dependencies is a change we have to include.

Updating LICENSE and NOTICE files is also subject to change, see SOLR-15929.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is detail that should be provided in the doc so that there's no variation in what people think is "necessary", even if it's just a reference to the doc mentioned in that ticket.

details.
7. Run `./gradlew updateLicenses` to re-generate SHA1 checksums of the new jar files.
8. Once in a while, a new version of a dependency will transitively bring in brand-new dependencies.
You'll need to decide whether to keep or exclude them. See `help/dependencies.txt` for details.

== Renovate bot Pull Requests
A member of the Solr community operates a Github bot running https://github.com/renovatebot/renovate[Renovate], which
files Pull Requests to Solr with dependency upgrade proposals. The PRs are labeled `dependencies` and do include
changes resulting from `gradle --write-locks` and `updateLicenses`.
changes resulting from `./gradlew writeLocks` and `updateLicenses`.

Community members and committers can then review, and if manual changes are needed, help bring the PR to completion.
For many dependencies, a changelog is included in the PR text, which may help guide the upgrade decision.
Expand Down
8 changes: 4 additions & 4 deletions gradle/documentation/markdown.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ buildscript {
}

dependencies {
classpath "com.vladsch.flexmark:flexmark:${scriptDepVersions['flexmark']}"
classpath "com.vladsch.flexmark:flexmark-ext-abbreviation:${scriptDepVersions['flexmark']}"
classpath "com.vladsch.flexmark:flexmark-ext-attributes:${scriptDepVersions['flexmark']}"
classpath "com.vladsch.flexmark:flexmark-ext-autolink:${scriptDepVersions['flexmark']}"
classpath libs.flexmark.flexmark
classpath libs.flexmark.extensions.abbreviation
classpath libs.flexmark.extensions.attributes
classpath libs.flexmark.extensions.autolink
}
}

Expand Down
10 changes: 5 additions & 5 deletions gradle/documentation/pull-lucene-javadocs.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ configure(project(":solr:documentation")) {
// from all Solr javadocs?) then perhaps we can find a way to build this list programatically?
// - If these javadocs are (only every) consumed by the ref guide only, then these deps & associated tasks
// should just be moved to the ref-guide build.gradle
javadocs group: 'org.apache.lucene', name: 'lucene-core', classifier: 'javadoc'
javadocs group: 'org.apache.lucene', name: 'lucene-analysis-common', classifier: 'javadoc'
javadocs group: 'org.apache.lucene', name: 'lucene-analysis-stempel', classifier: 'javadoc'
javadocs group: 'org.apache.lucene', name: 'lucene-queryparser', classifier: 'javadoc'
javadocs group: 'org.apache.lucene', name: 'lucene-spatial-extras', classifier: 'javadoc'
javadocs variantOf(libs.apache.lucene.core) { classifier 'javadoc' }
javadocs variantOf(libs.apache.lucene.analysis.common) { classifier 'javadoc' }
javadocs variantOf(libs.apache.lucene.analysis.stempel) { classifier 'javadoc' }
javadocs variantOf(libs.apache.lucene.queryparser) { classifier 'javadoc' }
javadocs variantOf(libs.apache.lucene.spatialextras) { classifier 'javadoc' }
}


Expand Down
2 changes: 1 addition & 1 deletion gradle/generation/javacc.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ configure(rootProject) {
}

dependencies {
javacc "net.java.dev.javacc:javacc:${scriptDepVersions['javacc']}"
javacc libs.javacc.javacc
}

task javacc() {
Expand Down
89 changes: 46 additions & 43 deletions gradle/ide/eclipse.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,65 +21,68 @@ import org.gradle.plugins.ide.eclipse.model.ClasspathEntry
def resources = scriptResources(buildscript)

configure(rootProject) {
apply plugin: "eclipse"
plugins.withType(JavaPlugin) {
apply plugin: "eclipse"

def relativize = { other -> rootProject.rootDir.relativePath(other).toString() }
def eclipseJavaVersion = propertyOrDefault("eclipse.javaVersion", libs.versions.java.min.get())
def relativize = { other -> rootProject.rootDir.relativePath(other).toString() }

eclipse {
project {
name = "Apache Solr ${version}"
}
eclipse {
project {
name = "Apache Solr ${version}"
}

classpath {
downloadSources = true
downloadJavadoc = true
defaultOutputDir = file('build/eclipse')
classpath {
downloadSources = true
downloadJavadoc = true
defaultOutputDir = file('build/eclipse')

file {
beforeMerged { classpath -> classpath.entries.removeAll { it.kind == "src" } }
file {
beforeMerged { classpath -> classpath.entries.removeAll { it.kind == "src" } }

whenMerged { classpath ->
def projects = allprojects.findAll { prj ->
return prj.plugins.hasPlugin(JavaPlugin) &&
prj.path != ":solr:solr-ref-guide"
}

Set<String> sources = []
Set<File> jars = []
projects.each { prj ->
prj.sourceSets.each { sourceSet ->
sources += sourceSet.java.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
sources += sourceSet.resources.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
whenMerged { classpath ->
def projects = allprojects.findAll { prj ->
return prj.plugins.hasPlugin(JavaPlugin) &&
prj.path != ":solr:solr-ref-guide"
}

// This is hacky - we take the resolved compile classpath and just
// include JAR files from there. We should probably make it smarter
// by looking at real dependencies. But then: this Eclipse configuration
// doesn't really separate sources anyway so why bother.
jars += prj.configurations.compileClasspath.resolve()
jars += prj.configurations.testCompileClasspath.resolve()
}
Set<String> sources = []
Set<File> jars = []
projects.each { prj ->
prj.sourceSets.each { sourceSet ->
sources += sourceSet.java.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
sources += sourceSet.resources.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
}

// This is hacky - we take the resolved compile classpath and just
// include JAR files from there. We should probably make it smarter
// by looking at real dependencies. But then: this Eclipse configuration
// doesn't really separate sources anyway so why bother.
jars += prj.configurations.compileClasspath.resolve()
jars += prj.configurations.testCompileClasspath.resolve()
}

classpath.entries += sources.sort().collect {name -> new SourceFolder(name, "build/eclipse/" + name) }
classpath.entries += jars.unique().findAll { location -> location.isFile() }.collect { location ->
new LibEntry(location.toString())
classpath.entries += sources.sort().collect {name -> new SourceFolder(name, "build/eclipse/" + name) }
classpath.entries += jars.unique().findAll { location -> location.isFile() }.collect { location ->
new LibEntry(location.toString())
}
}
}
}
}

jdt {
sourceCompatibility = rootProject.minJavaVersionDefault
targetCompatibility = rootProject.minJavaVersionDefault
javaRuntimeName = "JavaSE-${rootProject.minJavaVersionDefault}"
sourceCompatibility = eclipseJavaVersion
targetCompatibility = eclipseJavaVersion
javaRuntimeName = "JavaSE-${eclipseJavaVersion}"
}
}

eclipseJdt {
doLast {
project.sync {
from rootProject.file("${resources}/dot.settings")
into rootProject.file(".settings")
eclipseJdt {
doLast {
project.sync {
from rootProject.file("${resources}/dot.settings")
into rootProject.file(".settings")
}
}
}
}
Expand Down
Loading
Loading