From 4ae1f80bd45aa913974259c4eb4b96be3df50a6e Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Tue, 4 Feb 2025 10:15:29 +0100 Subject: [PATCH 1/6] prepare release v0.20.0 --- README.md | 6 ++++-- build.gradle | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 309222b..8f466b4 100644 --- a/README.md +++ b/README.md @@ -26,12 +26,12 @@ To add a dependency on hash4j using Maven, use the following: com.dynatrace.hash4j hash4j - 0.19.0 + 0.20.0 ``` To add a dependency using Gradle: ```gradle -implementation 'com.dynatrace.hash4j:hash4j:0.19.0' +implementation 'com.dynatrace.hash4j:hash4j:0.20.0' ``` ## Hash algorithms @@ -50,6 +50,8 @@ hash4j currently implements the following hash algorithms: * farmhashuo * [PolymurHash 2.0](https://github.com/orlp/polymur-hash) * [XXH3](https://github.com/Cyan4973/xxHash) + * 64-bit + * 128-bit All hash functions are thoroughly tested against the native reference implementations and also other libraries like [Guava Hashing](https://javadoc.io/doc/com.google.guava/guava/latest/com/google/common/hash/package-summary.html), [Zero-Allocation Hashing](https://github.com/OpenHFT/Zero-Allocation-Hashing), [Apache Commons Codec](https://commons.apache.org/proper/commons-codec/apidocs/index.html), or [crypto](https://github.com/appmattus/crypto) (see [CrossCheckTest.java](src/test/java/com/dynatrace/hash4j/hashing/CrossCheckTest.java)). diff --git a/build.gradle b/build.gradle index b734e92..068c5a1 100644 --- a/build.gradle +++ b/build.gradle @@ -128,7 +128,7 @@ tasks.withType(JavaCompile).configureEach { } group = 'com.dynatrace.hash4j' -version = '0.19.0' +version = '0.20.0' static def readJavaLicense(licenseName) { From 1bdeac06dbf87ee7e93e01b28951913dd4cfde74 Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Tue, 4 Feb 2025 10:20:34 +0100 Subject: [PATCH 2/6] fixed line endings --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitattributes b/.gitattributes index 6a95784..5d1fc82 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,7 @@ * text=auto *.java text eol=lf +*.hpp text eol=lf +*.cpp text eol=lf *.txt text eol=lf *.py text eol=lf *.md text eol=lf From 0bb9c6359a010170419ff4b0df46e0f9bba73245 Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Tue, 4 Feb 2025 10:45:35 +0100 Subject: [PATCH 3/6] bump gradle to 8.12.1 --- gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 3990 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c8..e18bc25 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From b3e6d5d15a908d0dbfb9e6bdf39d9fd93744eaac Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Tue, 4 Feb 2025 10:51:19 +0100 Subject: [PATCH 4/6] bump google java format to 1.25.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 068c5a1..ccbdf26 100644 --- a/build.gradle +++ b/build.gradle @@ -168,7 +168,7 @@ static def readPythonLicense(licenseName) { } spotless { - def googleJavaFormatVersion = '1.25.0' + def googleJavaFormatVersion = '1.25.2' def eclipseCdtVersion = '11.6' def blackVersion = '24.10.0' def greclipseVersion = '4.32' From a845dafbeffbe870e033d3433513e40c22acb453 Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Tue, 4 Feb 2025 12:25:35 +0100 Subject: [PATCH 5/6] formatted build.gradle --- build.gradle | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index ccbdf26..d02e377 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,18 @@ +/* + * Copyright 2025 Dynatrace LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import com.diffplug.gradle.spotless.JavaExtension plugins { @@ -118,7 +133,7 @@ tasks.check { tasks.withType(Test).configureEach { useJUnitPlatform() - maxHeapSize '8g' + maxHeapSize = '8g' } tasks.withType(JavaCompile).configureEach { @@ -167,6 +182,7 @@ static def readPythonLicense(licenseName) { return s } +apply plugin: 'groovy' spotless { def googleJavaFormatVersion = '1.25.2' def eclipseCdtVersion = '11.6' @@ -205,10 +221,12 @@ spotless { ] ratchetFrom 'origin/main' - apply plugin: 'groovy' - groovyGradle { - target '*.gradle' // default target of groovyGradle + groovy { + importOrder() + removeSemicolons() greclipse(greclipseVersion) + licenseHeader readJavaLicense('APACHE_2_0_DYNATRACE') + target("**/*.gradle") } python { target 'python/**/*.py' @@ -268,14 +286,14 @@ jmh { } task evaluateBenchmarks(type:Exec) { - group "evaluation" - workingDir '.' + group = "evaluation" + workingDir = '.' commandLine 'python', 'python/benchmark_evaluation.py' } task evaluateEstimationErrors(type:Exec) { - group "evaluation" - workingDir '.' + group = "evaluation" + workingDir = '.' commandLine 'python', 'python/estimation_error_evaluation.py' } @@ -304,7 +322,7 @@ for (sketch in sketches) { def outputFileName = "test-results/" + sketch.toLowerCase() + '-estimation-error-p' + String.format( "%02d", p ) + '.csv' task "${sketchTaskName}"(type: JavaExec) { outputs.files outputFileName - group "evaluation" + group = "evaluation" classpath = sourceSets.test.runtimeClasspath mainClass = 'com.dynatrace.hash4j.distinctcount.' + sketch + 'EstimationErrorSimulation' args = [p.toString(), outputFileName] @@ -314,13 +332,13 @@ for (sketch in sketches) { } def evaluationTaskName = "simulate" + sketch + "EstimationErrors" task "${evaluationTaskName}" { - group "evaluation" + group = "evaluation" dependsOn sketchTasks } evaluationTasks.add(evaluationTaskName) } task "simulateEstimationErrors" { - group "evaluation" + group = "evaluation" dependsOn evaluationTasks } @@ -358,8 +376,8 @@ tasks.simulateHyperLogLogEstimationErrors.finalizedBy evaluateEstimationErrors tasks.simulateUltraLogLogEstimationErrors.finalizedBy evaluateEstimationErrors javadoc { - failOnError true - title 'hash4j ' + project.version + ' API' + failOnError = true + title = 'hash4j ' + project.version + ' API' } jacoco { From 70a3c06e66d590e47c801892c8e1468f44f06284 Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Tue, 4 Feb 2025 13:02:08 +0100 Subject: [PATCH 6/6] improved formatting --- build.gradle | 244 ++++++++++++++++++++++++------------------------ settings.gradle | 2 +- 2 files changed, 123 insertions(+), 123 deletions(-) diff --git a/build.gradle b/build.gradle index d02e377..7f68007 100644 --- a/build.gradle +++ b/build.gradle @@ -16,15 +16,15 @@ import com.diffplug.gradle.spotless.JavaExtension plugins { - id 'java-library' - id 'jacoco' - id 'me.champeau.jmh' version '0.7.3' - id 'org.sonarqube' version '6.0.1.5171' - id 'com.diffplug.spotless' version '7.0.2' - id 'maven-publish' - id 'signing' - id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' - id 'net.ltgt.errorprone' version '4.1.0' + id "java-library" + id "jacoco" + id "me.champeau.jmh" version "0.7.3" + id "org.sonarqube" version "6.0.1.5171" + id "com.diffplug.spotless" version "7.0.2" + id "maven-publish" + id "signing" + id "io.github.gradle-nexus.publish-plugin" version "2.0.0" + id "net.ltgt.errorprone" version "4.1.0" id "org.revapi.revapi-gradle-plugin" version "1.8.0" } @@ -34,19 +34,19 @@ repositories { } dependencies { - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.11.4' - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.11.4' - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.11.4' - testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.27.3' - testImplementation group: 'org.hipparchus', name: 'hipparchus-stat', version: '3.1' - testImplementation group: 'org.hipparchus', name: 'hipparchus-optim', version: '3.1' - testImplementation group: 'com.google.guava', name: 'guava', version: '33.4.0-jre' - testImplementation group: 'commons-codec', name: 'commons-codec', version: '1.18.0' - testImplementation group: 'net.openhft', name: 'zero-allocation-hashing', version: '0.15' - testImplementation group: 'com.appmattus.crypto', name: 'cryptohash', version: '1.0.2' - testImplementation group: 'org.greenrobot', name: 'essentials', version: '3.1.0' - testImplementation group: 'com.sangupta', name: 'murmur', version: '1.0.0' - errorprone group:'com.google.errorprone',name:'error_prone_core', version: '2.36.0' + testImplementation group: "org.junit.jupiter", name: "junit-jupiter-api", version: "5.11.4" + testRuntimeOnly group: "org.junit.jupiter", name: "junit-jupiter-engine", version: "5.11.4" + testImplementation group: "org.junit.jupiter", name: "junit-jupiter-params", version: "5.11.4" + testImplementation group: "org.assertj", name: "assertj-core", version: "3.27.3" + testImplementation group: "org.hipparchus", name: "hipparchus-stat", version: "3.1" + testImplementation group: "org.hipparchus", name: "hipparchus-optim", version: "3.1" + testImplementation group: "com.google.guava", name: "guava", version: "33.4.0-jre" + testImplementation group: "commons-codec", name: "commons-codec", version: "1.18.0" + testImplementation group: "net.openhft", name: "zero-allocation-hashing", version: "0.15" + testImplementation group: "com.appmattus.crypto", name: "cryptohash", version: "1.0.2" + testImplementation group: "org.greenrobot", name: "essentials", version: "3.1.0" + testImplementation group: "com.sangupta", name: "murmur", version: "1.0.0" + errorprone group:"com.google.errorprone",name:"error_prone_core", version: "2.36.0" } java { @@ -64,7 +64,7 @@ sourceSets { test java21 { java { - srcDir 'src/main/java21' + srcDir "src/main/java21" } dependencies { // add Java 21 dependencies here to make them available for Java 21 code @@ -75,7 +75,7 @@ sourceSets { } java21Test { java { - srcDir 'src/test/java21' + srcDir "src/test/java21" } dependencies { // add Java 21 dependencies here to make them available for Java 21 code @@ -87,12 +87,12 @@ sourceSets { } jar { - dependsOn 'compileJava21Java' - into('META-INF/versions/21') { + dependsOn "compileJava21Java" + into("META-INF/versions/21") { from sourceSets.java21.output } manifest { - attributes 'Multi-Release': 'true' + attributes "Multi-Release": "true" } } @@ -133,7 +133,7 @@ tasks.check { tasks.withType(Test).configureEach { useJUnitPlatform() - maxHeapSize = '8g' + maxHeapSize = "8g" } tasks.withType(JavaCompile).configureEach { @@ -142,101 +142,101 @@ tasks.withType(JavaCompile).configureEach { // options.errorprone.enabled = false } -group = 'com.dynatrace.hash4j' -version = '0.20.0' +group = "com.dynatrace.hash4j" +version = "0.20.0" static def readJavaLicense(licenseName) { - File licenseFile = new File('licenses/' + licenseName + '.txt') + File licenseFile = new File("licenses/" + licenseName + ".txt") def line - def s = '/*\n' + def s = "/*\n" licenseFile.withReader { reader -> while ((line = reader.readLine()) != null) { - s += ' *' + s += " *" if(!line.isEmpty()) { - s += ' ' + s += " " s += line } - s += '\n' + s += "\n" } } - s += ' */' + s += " */" return s } static def readPythonLicense(licenseName) { - File licenseFile = new File('licenses/' + licenseName + '.txt') + File licenseFile = new File("licenses/" + licenseName + ".txt") def line - def s = '#\n' + def s = "#\n" licenseFile.withReader { reader -> while ((line = reader.readLine()) != null) { - s += '#' + s += "#" if(!line.isEmpty()) { - s += ' ' + s += " " s += line } - s += '\n' + s += "\n" } } - s += '#' + s += "#" return s } -apply plugin: 'groovy' +apply plugin: "groovy" spotless { - def googleJavaFormatVersion = '1.25.2' - def eclipseCdtVersion = '11.6' - def blackVersion = '24.10.0' - def greclipseVersion = '4.32' + def googleJavaFormatVersion = "1.25.2" + def eclipseCdtVersion = "11.6" + def blackVersion = "24.10.0" + def greclipseVersion = "4.32" def specialLicenseHeaders = [ - new Tuple3('javaImohash', 'MIT_IMOHASH', [ - 'src/main/java/com/dynatrace/hash4j/file/Imohash1_0_2.java' + new Tuple3("javaImohash", "MIT_IMOHASH", [ + "src/main/java/com/dynatrace/hash4j/file/Imohash1_0_2.java" ]), - new Tuple3('javaKomihash', 'MIT_KOMIHASH' , [ - 'src/main/java/com/dynatrace/hash4j/hashing/Komihash4_3.java', - 'src/main/java/com/dynatrace/hash4j/hashing/Komihash5_0.java', - 'src/main/java/com/dynatrace/hash4j/hashing/AbstractKomihash.java' + new Tuple3("javaKomihash", "MIT_KOMIHASH" , [ + "src/main/java/com/dynatrace/hash4j/hashing/Komihash4_3.java", + "src/main/java/com/dynatrace/hash4j/hashing/Komihash5_0.java", + "src/main/java/com/dynatrace/hash4j/hashing/AbstractKomihash.java" ]), - new Tuple3('javaFarmHash', 'MIT_APACHE_2_0_FARMHASH',[ - 'src/main/java/com/dynatrace/hash4j/hashing/FarmHashNa.java', - 'src/main/java/com/dynatrace/hash4j/hashing/FarmHashUo.java' + new Tuple3("javaFarmHash", "MIT_APACHE_2_0_FARMHASH",[ + "src/main/java/com/dynatrace/hash4j/hashing/FarmHashNa.java", + "src/main/java/com/dynatrace/hash4j/hashing/FarmHashUo.java" ]), - new Tuple3('javaPolymurHash', 'ZLIB_POLYMURHASH',[ - 'src/main/java/com/dynatrace/hash4j/hashing/PolymurHash2_0.java' + new Tuple3("javaPolymurHash", "ZLIB_POLYMURHASH",[ + "src/main/java/com/dynatrace/hash4j/hashing/PolymurHash2_0.java" ]), - new Tuple3('javaSplitMix64', 'CREATIVE_COMMONS_SPLITMIX64',[ - 'src/main/java/com/dynatrace/hash4j/random/SplitMix64V1.java' + new Tuple3("javaSplitMix64", "CREATIVE_COMMONS_SPLITMIX64",[ + "src/main/java/com/dynatrace/hash4j/random/SplitMix64V1.java" ]), - new Tuple3('javaExponential', 'BOOST_EXPONENTIAL_RANDOM_GENERATION',[ - 'src/main/java/com/dynatrace/hash4j/random/RandomExponentialUtil.java' + new Tuple3("javaExponential", "BOOST_EXPONENTIAL_RANDOM_GENERATION",[ + "src/main/java/com/dynatrace/hash4j/random/RandomExponentialUtil.java" ]), - new Tuple3('javaConsistentJumpHash', 'APACHE_2_0_GUAVA',[ - 'src/main/java/com/dynatrace/hash4j/consistent/ConsistentJumpBucketHasher.java' + new Tuple3("javaConsistentJumpHash", "APACHE_2_0_GUAVA",[ + "src/main/java/com/dynatrace/hash4j/consistent/ConsistentJumpBucketHasher.java" ]), - new Tuple3('javaXXH', 'APACHE_2_0_XXH',[ - 'src/main/java/com/dynatrace/hash4j/hashing/XXH3_64.java', - 'src/main/java/com/dynatrace/hash4j/hashing/XXH3_128.java', - 'src/main/java/com/dynatrace/hash4j/hashing/XXH3Base.java' + new Tuple3("javaXXH", "APACHE_2_0_XXH",[ + "src/main/java/com/dynatrace/hash4j/hashing/XXH3_64.java", + "src/main/java/com/dynatrace/hash4j/hashing/XXH3_128.java", + "src/main/java/com/dynatrace/hash4j/hashing/XXH3Base.java" ]) ] - ratchetFrom 'origin/main' + ratchetFrom "origin/main" groovy { importOrder() removeSemicolons() greclipse(greclipseVersion) - licenseHeader readJavaLicense('APACHE_2_0_DYNATRACE') - target("**/*.gradle") + licenseHeader readJavaLicense("APACHE_2_0_DYNATRACE") + target("**/build.gradle") } python { - target 'python/**/*.py' + target "python/**/*.py" black(blackVersion) - licenseHeader readPythonLicense('APACHE_2_0_DYNATRACE'), '(import|from)' + licenseHeader readPythonLicense("APACHE_2_0_DYNATRACE"), "(import|from)" } cpp { - target 'reference-implementations/*/*.cpp', 'reference-implementations/*/*.hpp', 'reference-implementations/*.cpp', 'reference-implementations/*.hpp' + target "reference-implementations/*/*.cpp", "reference-implementations/*/*.hpp", "reference-implementations/*.cpp", "reference-implementations/*.hpp" eclipseCdt(eclipseCdtVersion) - licenseHeader readJavaLicense('APACHE_2_0_DYNATRACE') + licenseHeader readJavaLicense("APACHE_2_0_DYNATRACE") } java { importOrder() @@ -244,7 +244,7 @@ spotless { cleanthat() googleJavaFormat(googleJavaFormatVersion) formatAnnotations() - licenseHeader readJavaLicense('APACHE_2_0_DYNATRACE') + licenseHeader readJavaLicense("APACHE_2_0_DYNATRACE") targetExclude specialLicenseHeaders.collect {it.get(2)}.flatten() } specialLicenseHeaders.forEach { @@ -257,7 +257,7 @@ spotless { cleanthat() googleJavaFormat(googleJavaFormatVersion) formatAnnotations() - licenseHeader readJavaLicense('APACHE_2_0_DYNATRACE') + '\n\n' + readJavaLicense(licenseName) + licenseHeader readJavaLicense("APACHE_2_0_DYNATRACE") + "\n\n" + readJavaLicense(licenseName) target files } } @@ -265,36 +265,36 @@ spotless { sonarqube { properties { - property 'sonar.projectKey', 'dynatrace-oss_hash4j' - property 'sonar.organization', 'dynatrace-oss' - property 'sonar.host.url', 'https://sonarcloud.io' + property "sonar.projectKey", "dynatrace-oss_hash4j" + property "sonar.organization", "dynatrace-oss" + property "sonar.host.url", "https://sonarcloud.io" } } jmh { fork = 1 - timeUnit = 'us' + timeUnit = "us" failOnError = false - timeOnIteration = '1s' + timeOnIteration = "1s" warmupForks = 0 warmupIterations = 5 warmupBatchSize = 1 - warmup = '1s' + warmup = "1s" iterations = 20 - resultFormat = 'JSON' + resultFormat = "JSON" } task evaluateBenchmarks(type:Exec) { group = "evaluation" - workingDir = '.' - commandLine 'python', 'python/benchmark_evaluation.py' + workingDir = "." + commandLine "python", "python/benchmark_evaluation.py" } task evaluateEstimationErrors(type:Exec) { group = "evaluation" - workingDir = '.' - commandLine 'python', 'python/estimation_error_evaluation.py' + workingDir = "." + commandLine "python", "python/estimation_error_evaluation.py" } def sketches = ["UltraLogLog", "HyperLogLog"] @@ -319,14 +319,14 @@ for (sketch in sketches) { def sketchTasks = [] for (p in pValues) { def sketchTaskName = "simulate" + sketch + "EstimationErrorsP" + String.format( "%02d", p ) - def outputFileName = "test-results/" + sketch.toLowerCase() + '-estimation-error-p' + String.format( "%02d", p ) + '.csv' + def outputFileName = "test-results/" + sketch.toLowerCase() + "-estimation-error-p" + String.format( "%02d", p ) + ".csv" task "${sketchTaskName}"(type: JavaExec) { outputs.files outputFileName group = "evaluation" classpath = sourceSets.test.runtimeClasspath - mainClass = 'com.dynatrace.hash4j.distinctcount.' + sketch + 'EstimationErrorSimulation' + mainClass = "com.dynatrace.hash4j.distinctcount." + sketch + "EstimationErrorSimulation" args = [p.toString(), outputFileName] - jvmArgs = ['-Xmx16g'] + jvmArgs = ["-Xmx16g"] } sketchTasks.add(sketchTaskName) } @@ -342,28 +342,28 @@ task "simulateEstimationErrors" { dependsOn evaluationTasks } -tasks.register('checkStatusForBenchmarks') { +tasks.register("checkStatusForBenchmarks") { outputs.upToDateWhen { false } doLast { def status_text = "git status --porcelain".execute().text if(status_text?.trim()) { - throw new GradleException('There are uncommitted changes:\n' + status_text) + throw new GradleException("There are uncommitted changes:\n" + status_text) } } } -tasks.register('copyBenchmarkReport', Copy) { +tasks.register("copyBenchmarkReport", Copy) { def proc = "git rev-parse HEAD".execute() def revision = proc.text.trim() - from('build/results/jmh/') { - include 'results.*' - rename 'results', new Date().format('yyyy-MM-dd-HH-mm-ss') + ' ' + revision + from("build/results/jmh/") { + include "results.*" + rename "results", new Date().format("yyyy-MM-dd-HH-mm-ss") + " " + revision } - into 'benchmark-results' + into "benchmark-results" } -tasks.register('deleteBenchmarkReport', Delete) { - delete 'build/results/jmh/results.json' +tasks.register("deleteBenchmarkReport", Delete) { + delete "build/results/jmh/results.json" } tasks.test.finalizedBy jacocoTestReport @@ -377,11 +377,11 @@ tasks.simulateUltraLogLogEstimationErrors.finalizedBy evaluateEstimationErrors javadoc { failOnError = true - title = 'hash4j ' + project.version + ' API' + title = "hash4j " + project.version + " API" } jacoco { - toolVersion = '0.8.11' + toolVersion = "0.8.11" } jacocoTestReport { @@ -396,11 +396,11 @@ jacocoTestCoverageVerification { rule { limit { minimum = 1.0 - counter = 'LINE' + counter = "LINE" } limit { minimum = 1.0 - counter = 'BRANCH' + counter = "BRANCH" } } } @@ -411,26 +411,26 @@ publishing { mavenJava(MavenPublication) { from components.java pom { - name = 'com.dynatrace.hash4j:hash4j' - description = 'hash4j: A Dynatrace hash library for Java' - url = 'https://github.com/dynatrace-oss/hash4j' + name = "com.dynatrace.hash4j:hash4j" + description = "hash4j: A Dynatrace hash library for Java" + url = "https://github.com/dynatrace-oss/hash4j" licenses { license { - name = 'The Apache License, Version 2.0' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + name = "The Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0.txt" } } developers { developer { - id = 'Dynatrace' - name = 'Dynatrace LLC' - email = 'opensource@dynatrace.com' + id = "Dynatrace" + name = "Dynatrace LLC" + email = "opensource@dynatrace.com" } } scm { - connection = 'scm:git:git://github.com/dynatrace-oss/hash4j.git' - developerConnection = 'scm:git:ssh://github.com/dynatrace-oss/hash4j.git' - url = 'https://github.com/dynatrace-oss/hash4j' + connection = "scm:git:git://github.com/dynatrace-oss/hash4j.git" + developerConnection = "scm:git:ssh://github.com/dynatrace-oss/hash4j.git" + url = "https://github.com/dynatrace-oss/hash4j" } } } @@ -438,23 +438,23 @@ publishing { } signing { - useInMemoryPgpKeys(System.getenv('GPG_PRIVATE_KEY'), System.getenv('GPG_PASSPHRASE')) + useInMemoryPgpKeys(System.getenv("GPG_PRIVATE_KEY"), System.getenv("GPG_PASSPHRASE")) sign publishing.publications.mavenJava } nexusPublishing { - packageGroup = 'com.dynatrace' + packageGroup = "com.dynatrace" useStaging = true repositories { sonatype { - nexusUrl = uri('https://oss.sonatype.org/service/local/') - snapshotRepositoryUrl = uri('https://oss.sonatype.org/content/repositories/snapshots/') - username = System.getenv('OSSRH_USERNAME') - password = System.getenv('OSSRH_PASSWORD') + nexusUrl = uri("https://oss.sonatype.org/service/local/") + snapshotRepositoryUrl = uri("https://oss.sonatype.org/content/repositories/snapshots/") + username = System.getenv("OSSRH_USERNAME") + password = System.getenv("OSSRH_PASSWORD") } } } if (file("extra-configuration.gradle").exists()) { - apply from: 'extra-configuration.gradle' + apply from: "extra-configuration.gradle" } diff --git a/settings.gradle b/settings.gradle index e7579b4..3f5cab7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -rootProject.name = 'hash4j' \ No newline at end of file +rootProject.name = "hash4j"