From 8db617e56028514d5f8d97853baf548ec921a7ea Mon Sep 17 00:00:00 2001 From: Rey <89825425+kingg22@users.noreply.github.com> Date: Sat, 30 Aug 2025 12:45:14 -0500 Subject: [PATCH 1/2] [#2483] build: perf parse of versions local plugin With this change remove manual parser of libs.versions.toml file and use java Properties API. Additional retrieve data of the file with PropertiesSource of gradle to be ready with configuration cache. --- .../reactive/env/VersionPropertiesSource.java | 34 +++++ .../reactive/env/VersionsPlugin.java | 135 ++++++++++-------- .../reactive/env/VersionsTomlParser.java | 70 --------- 3 files changed, 110 insertions(+), 129 deletions(-) create mode 100644 local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsTomlParser.java diff --git a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java new file mode 100644 index 000000000..5e8906b58 --- /dev/null +++ b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java @@ -0,0 +1,34 @@ +package org.hibernate.reactive.env; + +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.ValueSource; +import org.gradle.api.provider.ValueSourceParameters; + +import java.io.FileInputStream; +import java.util.Properties; + +/** + * Reads gradle/version.properties and returns the "projectVersion" property. + * Compatible with Configuration Cache (Gradle declares the file as input). + */ +public abstract class VersionPropertiesSource implements ValueSource { + public interface Params extends ValueSourceParameters { + RegularFileProperty getFile(); + } + + @Override + public String obtain() { + final var file = getParameters().getFile().getAsFile().get(); + if ( !file.exists() ) { + throw new RuntimeException( "Version file " + file.getAbsolutePath() + " does not exists" ); + } + final var props = new Properties(); + try (final var in = new FileInputStream( file )) { + props.load( in ); + } + catch (Exception e) { + throw new RuntimeException( "Unable to load properties from file - " + file.getAbsolutePath(), e ); + } + return props.getProperty( "projectVersion" ); + } +} diff --git a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java index 883317d4a..f4552dc37 100644 --- a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java +++ b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java @@ -1,14 +1,15 @@ package org.hibernate.reactive.env; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import java.util.function.Consumer; +import java.util.Optional; import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.artifacts.VersionCatalog; +import org.gradle.api.artifacts.VersionCatalogsExtension; +import org.gradle.api.artifacts.VersionConstraint; +import org.gradle.api.logging.Logger; +import org.gradle.api.provider.Provider; /** * Build plugin which applies some DSL extensions to the Project. Currently, these @@ -28,47 +29,71 @@ public class VersionsPlugin implements Plugin { public static final String SKIP_ORM_VERSION_PARSING = "skipOrmVersionParsing"; public static final String RELATIVE_FILE = "gradle/version.properties"; - public static final String RELATIVE_CATALOG = "gradle/libs.versions.toml"; @Override public void apply(Project project) { + final Logger log = project.getLogger(); + + // Expose the version file as an extension final File versionFile = project.getRootProject().file( RELATIVE_FILE ); project.getExtensions().add( VERSION_FILE, versionFile ); + // 1) release/development via -P if they come final ProjectVersion releaseVersion = determineReleaseVersion( project ); final ProjectVersion developmentVersion = determineDevelopmentVersion( project ); - final ProjectVersion projectVersion = determineProjectVersion( project, releaseVersion, versionFile ); - project.getLogger().lifecycle( "Project version: {} ({})", projectVersion.getFullName(), projectVersion.getFamily() ); + // 2) read projectVersion from version.properties using ValueSource (cacheable) + final var projectVersionString = project.getProviders().of( + VersionPropertiesSource.class, spec -> { + final var rf = project.getLayout() + .getProjectDirectory() + .file( RELATIVE_FILE ); + spec.getParameters().getFile().set( rf ); + } + ); + + final ProjectVersion projectVersion = determineProjectVersion( + project, releaseVersion, projectVersionString + ); + + log.lifecycle( "Project version: {} ({})", projectVersion.getFullName(), projectVersion.getFamily() ); project.getExtensions().add( PROJECT_VERSION, projectVersion ); if ( releaseVersion != null ) { - project.getLogger().lifecycle( "Release version: {} ({})", releaseVersion.getFullName(), releaseVersion.getFamily() ); + log.lifecycle( "Release version: {} ({})", releaseVersion.getFullName(), releaseVersion.getFamily() ); project.getExtensions().add( RELEASE_VERSION, releaseVersion ); } else { - project.getLogger().lifecycle( "Release version: n/a" ); + log.lifecycle( "Release version: n/a" ); } if ( developmentVersion != null ) { - project.getLogger().lifecycle( "Development version: {} ({})", developmentVersion.getFullName(), developmentVersion.getFamily() ); + log.lifecycle( + "Development version: {} ({})", + developmentVersion.getFullName(), + developmentVersion.getFamily() + ); project.getExtensions().add( DEVELOPMENT_VERSION, developmentVersion ); } else { - project.getLogger().lifecycle( "Development version: n/a" ); + log.lifecycle( "Development version: n/a" ); } - final VersionsTomlParser tomlParser = new VersionsTomlParser( project.getRootProject().file( RELATIVE_CATALOG ) ); - final String ormVersionString = determineOrmVersion( project, tomlParser ); + // 3) Version Catalog ("libs") See local-build-plugins/settings.gradle + final VersionCatalogsExtension catalogs = project.getExtensions().getByType( VersionCatalogsExtension.class ); + final VersionCatalog libs = catalogs.named( "libs" ); + + final String ormVersionString = determineOrmVersion( project, libs ); final Object ormVersion = resolveOrmVersion( ormVersionString, project ); - project.getLogger().lifecycle( "ORM version: {}", ormVersion ); + log.lifecycle( "ORM version: {}", ormVersion ); project.getExtensions().add( ORM_VERSION, ormVersion ); - final Object ormPluginVersion = determineOrmPluginVersion( ormVersion, project, tomlParser ); - project.getLogger().lifecycle( "ORM Gradle plugin version: {}", ormPluginVersion ); + final Object ormPluginVersion = determineOrmPluginVersion( ormVersion, project, libs ); + log.lifecycle( "ORM Gradle plugin version: {}", ormPluginVersion ); project.getExtensions().add( ORM_PLUGIN_VERSION, ormPluginVersion ); } + // --- Release / Development (with -P) -------------------------------------- private ProjectVersion determineReleaseVersion(Project project) { if ( project.hasProperty( RELEASE_VERSION ) ) { final Object version = project.property( RELEASE_VERSION ); @@ -89,74 +114,66 @@ private ProjectVersion determineDevelopmentVersion(Project project) { return null; } - public static ProjectVersion determineProjectVersion(Project project, ProjectVersion releaseVersion, File versionFile) { + // --- Project version (ValueSource for configuration cache) --------------- + + public static ProjectVersion determineProjectVersion( + Project project, + ProjectVersion releaseVersion, + Provider projectVersionString + ) { if ( releaseVersion != null ) { return releaseVersion; } - - final String fullName = readVersionProperties( versionFile ); - return new ProjectVersion( fullName ); - } - - private static String readVersionProperties(File file) { - if ( !file.exists() ) { - throw new RuntimeException( "Version file " + file.getAbsolutePath() + " does not exists" ); + // if don't have an explicit release, use value of file (with ValueSource) + final String fullName = projectVersionString.get(); + if ( fullName.isEmpty() ) { + final var file = project.getRootProject().file( RELATIVE_FILE ); + throw new RuntimeException( "Property 'projectVersion' is missing in " + file.getAbsolutePath() ); } - - final Properties versionProperties = new Properties(); - withInputStream( file, (stream) -> { - try { - versionProperties.load( stream ); - } - catch (IOException e) { - throw new RuntimeException( "Unable to load properties from file - " + file.getAbsolutePath(), e ); - } - } ); - - return versionProperties.getProperty( "projectVersion" ); + return new ProjectVersion( fullName ); } - private static void withInputStream(File file, Consumer action) { - try ( final FileInputStream stream = new FileInputStream( file ) ) { - action.accept( stream ); - } - catch (IOException e) { - throw new RuntimeException( "Error reading file stream = " + file.getAbsolutePath(), e ); - } - } + // --- ORM version from -P or catalogs ------------------------------------ - private String determineOrmVersion(Project project, VersionsTomlParser parser) { + private String determineOrmVersion(Project project, VersionCatalog libs) { // Check if it has been set in the project + // -PhibernateOrmVersion have priority if ( project.hasProperty( ORM_VERSION ) ) { return (String) project.property( ORM_VERSION ); } - - // Check in the catalog - final String version = parser.read( ORM_VERSION ); - if ( version != null ) { - return version; + // Find in Version Catalog + final Optional vc = libs.findVersion( ORM_VERSION ); + if ( vc.isPresent() ) { + final String required = vc.get().getRequiredVersion(); + if ( !required.isEmpty() ) { + return required; + } } throw new IllegalStateException( "Hibernate ORM version not specified on project" ); } private Object resolveOrmVersion(String stringForm, Project project) { if ( project.hasProperty( SKIP_ORM_VERSION_PARSING ) - && Boolean.parseBoolean( (String) project.property( SKIP_ORM_VERSION_PARSING ) ) ) { + && Boolean.parseBoolean( (String) project.property( SKIP_ORM_VERSION_PARSING ) ) + ) { return stringForm; } return new ProjectVersion( stringForm ); } - private Object determineOrmPluginVersion(Object ormVersion, Project project, VersionsTomlParser parser) { + private Object determineOrmPluginVersion(Object ormVersion, Project project, VersionCatalog libs) { // Check if it has been set in the project + // -PhibernateOrmGradlePluginVersion have priority if ( project.hasProperty( ORM_PLUGIN_VERSION ) ) { return project.property( ORM_PLUGIN_VERSION ); } - - // Check in the catalog - final String version = parser.read( ORM_PLUGIN_VERSION ); - if ( version != null ) { - return version; + // Find in Version Catalog + final Optional vc = libs.findVersion( ORM_PLUGIN_VERSION ); + if ( vc.isPresent() ) { + final String required = vc.get().getRequiredVersion(); + if ( !required.isEmpty() ) { + return required; + } } throw new IllegalStateException( "Hibernate ORM Gradle plugin version not specified on project" ); diff --git a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsTomlParser.java b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsTomlParser.java deleted file mode 100644 index 8833de6a6..000000000 --- a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsTomlParser.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.hibernate.reactive.env; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * Read the versions section of the library catalog - */ -public class VersionsTomlParser { - - private final Map data = new HashMap<>(); - - public VersionsTomlParser(File filePath) { - parse( filePath ); - } - - private void parse(File filePath) { - - try ( BufferedReader reader = new BufferedReader( new FileReader( filePath ) ) ) { - String line; - String currentSection = null; - while ( ( line = reader.readLine() ) != null ) { - line = line.trim(); - - // Skip comments and blank lines - if ( line.isEmpty() || line.startsWith( "#" ) ) { - continue; - } - - // Handle [section] - if ( line.startsWith( "[" ) && line.endsWith( "]" ) ) { - currentSection = line.substring( 1, line.length() - 1 ).trim(); - continue; - } - - if ( "versions".equalsIgnoreCase( currentSection ) ) { - // Handle key = value - int equalsIndex = line.indexOf( '=' ); - if ( equalsIndex == -1 ) { - continue; - } - - String key = line.substring( 0, equalsIndex ).trim(); - String value = line.substring( equalsIndex + 1 ).trim(); - - // Remove optional quotes around string values - if ( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) { - value = value.substring( 1, value.length() - 1 ); - } - - data.put( key, value ); - } - } - } - catch (IOException e) { - throw new RuntimeException( e ); - } - } - - /** - * Read the value of the property in the versions section of a toml file - */ - public String read(String property) { - return data.get( property ); - } -} From 5414a2b3b1bccac95916cfa1771b2da05c3fc200 Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Tue, 2 Sep 2025 10:33:47 +0200 Subject: [PATCH 2/2] [#2483] Minor refactoring --- .../reactive/env/VersionPropertiesSource.java | 2 +- .../reactive/env/VersionsPlugin.java | 118 ++++++------------ 2 files changed, 37 insertions(+), 83 deletions(-) diff --git a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java index 5e8906b58..3f70a4858 100644 --- a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java +++ b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionPropertiesSource.java @@ -25,10 +25,10 @@ public String obtain() { final var props = new Properties(); try (final var in = new FileInputStream( file )) { props.load( in ); + return props.getProperty( "projectVersion" ); } catch (Exception e) { throw new RuntimeException( "Unable to load properties from file - " + file.getAbsolutePath(), e ); } - return props.getProperty( "projectVersion" ); } } diff --git a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java index f4552dc37..9399462a1 100644 --- a/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java +++ b/local-build-plugins/src/main/java/org/hibernate/reactive/env/VersionsPlugin.java @@ -34,31 +34,12 @@ public class VersionsPlugin implements Plugin { public void apply(Project project) { final Logger log = project.getLogger(); - // Expose the version file as an extension + // Expose the version file as an extension (used during releases) final File versionFile = project.getRootProject().file( RELATIVE_FILE ); project.getExtensions().add( VERSION_FILE, versionFile ); - // 1) release/development via -P if they come - final ProjectVersion releaseVersion = determineReleaseVersion( project ); - final ProjectVersion developmentVersion = determineDevelopmentVersion( project ); - - // 2) read projectVersion from version.properties using ValueSource (cacheable) - final var projectVersionString = project.getProviders().of( - VersionPropertiesSource.class, spec -> { - final var rf = project.getLayout() - .getProjectDirectory() - .file( RELATIVE_FILE ); - spec.getParameters().getFile().set( rf ); - } - ); - - final ProjectVersion projectVersion = determineProjectVersion( - project, releaseVersion, projectVersionString - ); - - log.lifecycle( "Project version: {} ({})", projectVersion.getFullName(), projectVersion.getFamily() ); - project.getExtensions().add( PROJECT_VERSION, projectVersion ); - + // 1) Read release/development via -P if they come + final ProjectVersion releaseVersion = findProjectVersion( RELEASE_VERSION, project ); if ( releaseVersion != null ) { log.lifecycle( "Release version: {} ({})", releaseVersion.getFullName(), releaseVersion.getFamily() ); project.getExtensions().add( RELEASE_VERSION, releaseVersion ); @@ -67,46 +48,44 @@ public void apply(Project project) { log.lifecycle( "Release version: n/a" ); } + final ProjectVersion developmentVersion = findProjectVersion( DEVELOPMENT_VERSION, project ); if ( developmentVersion != null ) { - log.lifecycle( - "Development version: {} ({})", - developmentVersion.getFullName(), - developmentVersion.getFamily() - ); + log.lifecycle( "Development version: {} ({})", developmentVersion.getFullName(), developmentVersion.getFamily() ); project.getExtensions().add( DEVELOPMENT_VERSION, developmentVersion ); } else { log.lifecycle( "Development version: n/a" ); } - // 3) Version Catalog ("libs") See local-build-plugins/settings.gradle + // 2) read projectVersion from version.properties using ValueSource (cacheable) + final var projectVersionString = project.getProviders() + .of( VersionPropertiesSource.class, spec -> { + final var rf = project.getLayout().getProjectDirectory().file( RELATIVE_FILE ); + spec.getParameters().getFile().set( rf ); + } + ); + + final ProjectVersion projectVersion = determineProjectVersion( project, releaseVersion, projectVersionString ); + log.lifecycle( "Project version: {} ({})", projectVersion.getFullName(), projectVersion.getFamily() ); + project.getExtensions().add( PROJECT_VERSION, projectVersion ); + + // 3) Version Catalog ("libs"): see gradle/libs.versions.toml final VersionCatalogsExtension catalogs = project.getExtensions().getByType( VersionCatalogsExtension.class ); final VersionCatalog libs = catalogs.named( "libs" ); - final String ormVersionString = determineOrmVersion( project, libs ); + final String ormVersionString = determineVersion( ORM_VERSION, project, libs ); final Object ormVersion = resolveOrmVersion( ormVersionString, project ); log.lifecycle( "ORM version: {}", ormVersion ); project.getExtensions().add( ORM_VERSION, ormVersion ); - final Object ormPluginVersion = determineOrmPluginVersion( ormVersion, project, libs ); + final String ormPluginVersion = determineVersion( ORM_PLUGIN_VERSION, project, libs ); log.lifecycle( "ORM Gradle plugin version: {}", ormPluginVersion ); project.getExtensions().add( ORM_PLUGIN_VERSION, ormPluginVersion ); } - // --- Release / Development (with -P) -------------------------------------- - private ProjectVersion determineReleaseVersion(Project project) { - if ( project.hasProperty( RELEASE_VERSION ) ) { - final Object version = project.property( RELEASE_VERSION ); - if ( version != null ) { - return new ProjectVersion( (String) version ); - } - } - return null; - } - - private ProjectVersion determineDevelopmentVersion(Project project) { - if ( project.hasProperty( DEVELOPMENT_VERSION ) ) { - final Object version = project.property( DEVELOPMENT_VERSION ); + private ProjectVersion findProjectVersion(String property, Project project) { + if ( project.hasProperty( property ) ) { + final Object version = project.property( property ); if ( version != null ) { return new ProjectVersion( (String) version ); } @@ -115,67 +94,42 @@ private ProjectVersion determineDevelopmentVersion(Project project) { } // --- Project version (ValueSource for configuration cache) --------------- - - public static ProjectVersion determineProjectVersion( - Project project, - ProjectVersion releaseVersion, - Provider projectVersionString - ) { + public static ProjectVersion determineProjectVersion(Project project, ProjectVersion releaseVersion, Provider projectVersionString) { if ( releaseVersion != null ) { return releaseVersion; } - // if don't have an explicit release, use value of file (with ValueSource) + // if we don't have an explicit release, use value from 'version/gradle.properties' (with ValueSource) final String fullName = projectVersionString.get(); if ( fullName.isEmpty() ) { final var file = project.getRootProject().file( RELATIVE_FILE ); - throw new RuntimeException( "Property 'projectVersion' is missing in " + file.getAbsolutePath() ); + throw new RuntimeException( "Property 'projectVersion' not found in " + file.getAbsolutePath() ); } return new ProjectVersion( fullName ); } - // --- ORM version from -P or catalogs ------------------------------------ - - private String determineOrmVersion(Project project, VersionCatalog libs) { - // Check if it has been set in the project - // -PhibernateOrmVersion have priority - if ( project.hasProperty( ORM_VERSION ) ) { - return (String) project.property( ORM_VERSION ); + private String determineVersion(String property, Project project, VersionCatalog libs) { + // Check if the property is defined in the project + if ( project.hasProperty( property ) ) { + return (String) project.property( property ); } - // Find in Version Catalog - final Optional vc = libs.findVersion( ORM_VERSION ); + + // Otherwise, look for it in the catalog + final Optional vc = libs.findVersion( property ); if ( vc.isPresent() ) { final String required = vc.get().getRequiredVersion(); if ( !required.isEmpty() ) { return required; } } - throw new IllegalStateException( "Hibernate ORM version not specified on project" ); + + throw new IllegalStateException( "Property '" + property + "' not found in version catalog" ); } private Object resolveOrmVersion(String stringForm, Project project) { if ( project.hasProperty( SKIP_ORM_VERSION_PARSING ) - && Boolean.parseBoolean( (String) project.property( SKIP_ORM_VERSION_PARSING ) ) - ) { + && Boolean.parseBoolean( (String) project.property( SKIP_ORM_VERSION_PARSING ) ) ) { return stringForm; } return new ProjectVersion( stringForm ); } - - private Object determineOrmPluginVersion(Object ormVersion, Project project, VersionCatalog libs) { - // Check if it has been set in the project - // -PhibernateOrmGradlePluginVersion have priority - if ( project.hasProperty( ORM_PLUGIN_VERSION ) ) { - return project.property( ORM_PLUGIN_VERSION ); - } - // Find in Version Catalog - final Optional vc = libs.findVersion( ORM_PLUGIN_VERSION ); - if ( vc.isPresent() ) { - final String required = vc.get().getRequiredVersion(); - if ( !required.isEmpty() ) { - return required; - } - } - - throw new IllegalStateException( "Hibernate ORM Gradle plugin version not specified on project" ); - } }